00001 <?php
00002
00003
00015 function profile_admin_overview() {
00016 $result = db_query('SELECT title, name, type, category, fid, weight FROM {profile_fields} ORDER BY category, weight');
00017
00018 $form = array();
00019 $categories = array();
00020 while ($field = db_fetch_object($result)) {
00021
00022 $categories[] = $field->category;
00023
00024
00025 $form[$field->fid]['name'] = array('#value' => check_plain($field->name));
00026 $form[$field->fid]['title'] = array('#value' => check_plain($field->title));
00027 $form[$field->fid]['type'] = array('#value' => $field->type);
00028 $form[$field->fid]['category'] = array('#type' => 'select', '#default_value' => $field->category, '#options' => array());
00029 $form[$field->fid]['weight'] = array('#type' => 'weight', '#default_value' => $field->weight);
00030 $form[$field->fid]['edit'] = array('#value' => l(t('edit'), "admin/user/profile/edit/$field->fid"));
00031 $form[$field->fid]['delete'] = array('#value' => l(t('delete'), "admin/user/profile/delete/$field->fid"));
00032 }
00033
00034
00035 $categories = array_unique($categories);
00036 foreach ($form as $fid => $field) {
00037 foreach ($categories as $cat => $category) {
00038 $form[$fid]['category']['#options'][$category] = $category;
00039 }
00040 }
00041
00042
00043 if (count($form) > 1) {
00044 $form['submit'] = array('#type' => 'submit', '#value' => t('Save configuration'));
00045 }
00046 else {
00047
00048 foreach ($form as $fid => $field) {
00049 unset($form[$fid]['weight']);
00050 $form[$fid]['category']['#type'] = 'value';
00051 }
00052 }
00053 $form['#tree'] = TRUE;
00054
00055 $addnewfields = '<h2>' . t('Add new field') . '</h2>';
00056 $addnewfields .= '<ul>';
00057 foreach (_profile_field_types() as $key => $value) {
00058 $addnewfields .= '<li>' . l($value, "admin/user/profile/add/$key") . '</li>';
00059 }
00060 $addnewfields .= '</ul>';
00061 $form['addnewfields'] = array('#value' => $addnewfields);
00062
00063 return $form;
00064 }
00065
00071 function profile_admin_overview_submit($form, &$form_state) {
00072 foreach (element_children($form_state['values']) as $fid) {
00073 if (is_numeric($fid)) {
00074 $weight = $form_state['values'][$fid]['weight'];
00075 $category = $form_state['values'][$fid]['category'];
00076 if ($weight != $form[$fid]['weight']['#default_value'] || $category != $form[$fid]['category']['#default_value']) {
00077 db_query("UPDATE {profile_fields} SET weight = %d, category = '%s' WHERE fid = %d", $weight, $category, $fid);
00078 }
00079 }
00080 }
00081
00082 drupal_set_message(t('Profile fields have been updated.'));
00083 cache_clear_all();
00084 menu_rebuild();
00085 }
00086
00093 function theme_profile_admin_overview($form) {
00094 drupal_add_css(drupal_get_path('module', 'profile') . '/profile.css');
00095
00096 if (isset($form['submit'])) {
00097 drupal_add_js(drupal_get_path('module', 'profile') . '/profile.js');
00098 }
00099
00100 $rows = array();
00101 $categories = array();
00102 $category_number = 0;
00103 foreach (element_children($form) as $key) {
00104
00105 if (array_key_exists('category', $form[$key])) {
00106 $field = &$form[$key];
00107 $category = $field['category']['#default_value'];
00108
00109 if (!isset($categories[$category])) {
00110
00111
00112 $categories[$category] = $category_number;
00113 $category_field['#attributes']['class'] = 'profile-category profile-category-' . $category_number;
00114 $rows[] = array(array('data' => $category, 'colspan' => 7, 'class' => 'category'));
00115 $rows[] = array('data' => array(array('data' => '<em>' . t('No fields in this category. If this category remains empty when saved, it will be removed.') . '</em>', 'colspan' => 7)), 'class' => 'category-' . $category_number . '-message category-message category-populated');
00116
00117
00118 if (isset($form['submit'])) {
00119 drupal_add_tabledrag('profile-fields', 'order', 'sibling', 'profile-weight', 'profile-weight-' . $category_number);
00120 drupal_add_tabledrag('profile-fields', 'match', 'sibling', 'profile-category', 'profile-category-' . $category_number);
00121 }
00122 $category_number++;
00123 }
00124
00125
00126 $field['weight']['#attributes']['class'] = 'profile-weight profile-weight-' . $categories[$category];
00127 $field['category']['#attributes']['class'] = 'profile-category profile-category-' . $categories[$category];
00128
00129
00130 $row = array();
00131 $row[] = drupal_render($field['title']);
00132 $row[] = drupal_render($field['name']);
00133 $row[] = drupal_render($field['type']);
00134 if (isset($form['submit'])) {
00135 $row[] = drupal_render($field['category']);
00136 $row[] = drupal_render($field['weight']);
00137 }
00138 $row[] = drupal_render($field['edit']);
00139 $row[] = drupal_render($field['delete']);
00140 $rows[] = array('data' => $row, 'class' => 'draggable');
00141 }
00142 }
00143 if (empty($rows)) {
00144 $rows[] = array(array('data' => t('No fields available.'), 'colspan' => 7));
00145 }
00146
00147 $header = array(t('Title'), t('Name'), t('Type'));
00148 if (isset($form['submit'])) {
00149 $header[] = t('Category');
00150 $header[] = t('Weight');
00151 }
00152 $header[] = array('data' => t('Operations'), 'colspan' => 2);
00153
00154 $output = theme('table', $header, $rows, array('id' => 'profile-fields'));
00155 $output .= drupal_render($form);
00156
00157 return $output;
00158 }
00159
00167 function profile_field_form(&$form_state, $arg = NULL) {
00168 if (arg(3) == 'edit') {
00169 if (is_numeric($arg)) {
00170 $fid = $arg;
00171
00172 $edit = db_fetch_array(db_query('SELECT * FROM {profile_fields} WHERE fid = %d', $fid));
00173
00174 if (!$edit) {
00175 drupal_not_found();
00176 return;
00177 }
00178 drupal_set_title(t('edit %title', array('%title' => $edit['title'])));
00179 $form['fid'] = array('#type' => 'value',
00180 '#value' => $fid,
00181 );
00182 $type = $edit['type'];
00183 }
00184 else {
00185 drupal_not_found();
00186 return;
00187 }
00188 }
00189 else {
00190 $types = _profile_field_types();
00191 if (!isset($types[$arg])) {
00192 drupal_not_found();
00193 return;
00194 }
00195 $type = $arg;
00196 drupal_set_title(t('add new %type', array('%type' => $types[$type])));
00197 $edit = array('name' => 'profile_');
00198 $form['type'] = array('#type' => 'value', '#value' => $type);
00199 }
00200 $edit += array(
00201 'category' => '',
00202 'title' => '',
00203 'explanation' => '',
00204 'weight' => 0,
00205 'page' => '',
00206 'autocomplete' => '',
00207 'required' => '',
00208 'register' => '',
00209 );
00210 $form['fields'] = array('#type' => 'fieldset',
00211 '#title' => t('Field settings'),
00212 );
00213 $form['fields']['category'] = array('#type' => 'textfield',
00214 '#title' => t('Category'),
00215 '#default_value' => $edit['category'],
00216 '#autocomplete_path' => 'admin/user/profile/autocomplete',
00217 '#description' => t('The category the new field should be part of. Categories are used to group fields logically. An example category is "Personal information".'),
00218 '#required' => TRUE,
00219 );
00220 $form['fields']['title'] = array('#type' => 'textfield',
00221 '#title' => t('Title'),
00222 '#default_value' => $edit['title'],
00223 '#description' => t('The title of the new field. The title will be shown to the user. An example title is "Favorite color".'),
00224 '#required' => TRUE,
00225 );
00226 $form['fields']['name'] = array('#type' => 'textfield',
00227 '#title' => t('Form name'),
00228 '#default_value' => $edit['name'],
00229 '#description' => t('The name of the field. The form name is not shown to the user but used internally in the HTML code and URLs.
00230 Unless you know what you are doing, it is highly recommended that you prefix the form name with <code>profile_</code> to avoid name clashes with other fields. Spaces or any other special characters except dash (-) and underscore (_) are not allowed. An example name is "profile_favorite_color" or perhaps just "profile_color".'),
00231 '#required' => TRUE,
00232 );
00233 $form['fields']['explanation'] = array('#type' => 'textarea',
00234 '#title' => t('Explanation'),
00235 '#default_value' => $edit['explanation'],
00236 '#description' => t('An optional explanation to go with the new field. The explanation will be shown to the user.'),
00237 );
00238 if ($type == 'selection') {
00239 $form['fields']['options'] = array('#type' => 'textarea',
00240 '#title' => t('Selection options'),
00241 '#default_value' => isset($edit['options']) ? $edit['options'] : '',
00242 '#description' => t('A list of all options. Put each option on a separate line. Example options are "red", "blue", "green", etc.'),
00243 );
00244 }
00245 $form['fields']['visibility'] = array('#type' => 'radios',
00246 '#title' => t('Visibility'),
00247 '#default_value' => isset($edit['visibility']) ? $edit['visibility'] : PROFILE_PUBLIC,
00248 '#options' => array(PROFILE_HIDDEN => t('Hidden profile field, only accessible by administrators, modules and themes.'), PROFILE_PRIVATE => t('Private field, content only available to privileged users.'), PROFILE_PUBLIC => t('Public field, content shown on profile page but not used on member list pages.'), PROFILE_PUBLIC_LISTINGS => t('Public field, content shown on profile page and on member list pages.')),
00249 );
00250 if ($type == 'selection' || $type == 'list' || $type == 'textfield') {
00251 $form['fields']['page'] = array('#type' => 'textfield',
00252 '#title' => t('Page title'),
00253 '#default_value' => $edit['page'],
00254 '#description' => t('To enable browsing this field by value, enter a title for the resulting page. The word <code>%value</code> will be substituted with the corresponding value. An example page title is "People whose favorite color is %value" . This is only applicable for a public field.'),
00255 );
00256 }
00257 else if ($type == 'checkbox') {
00258 $form['fields']['page'] = array('#type' => 'textfield',
00259 '#title' => t('Page title'),
00260 '#default_value' => $edit['page'],
00261 '#description' => t('To enable browsing this field by value, enter a title for the resulting page. An example page title is "People who are employed" . This is only applicable for a public field.'),
00262 );
00263 }
00264 $form['fields']['weight'] = array('#type' => 'weight',
00265 '#title' => t('Weight'),
00266 '#default_value' => $edit['weight'],
00267 '#description' => t('The weights define the order in which the form fields are shown. Lighter fields "float up" towards the top of the category.'),
00268 );
00269 $form['fields']['autocomplete'] = array('#type' => 'checkbox',
00270 '#title' => t('Form will auto-complete while user is typing.'),
00271 '#default_value' => $edit['autocomplete'],
00272 );
00273 $form['fields']['required'] = array('#type' => 'checkbox',
00274 '#title' => t('The user must enter a value.'),
00275 '#default_value' => $edit['required'],
00276 );
00277 $form['fields']['register'] = array('#type' => 'checkbox',
00278 '#title' => t('Visible in user registration form.'),
00279 '#default_value' => $edit['register'],
00280 );
00281 $form['submit'] = array('#type' => 'submit',
00282 '#value' => t('Save field'),
00283 );
00284 return $form;
00285 }
00286
00290 function profile_field_form_validate($form, &$form_state) {
00291
00292 if (preg_match('/[^a-zA-Z0-9_-]/', $form_state['values']['name'])) {
00293 form_set_error('name', t('The specified form name contains one or more illegal characters. Spaces or any other special characters except dash (-) and underscore (_) are not allowed.'));
00294 }
00295
00296 $users_table = drupal_get_schema('users');
00297 if (!empty($users_table['fields'][$form_state['values']['name']])) {
00298 form_set_error('name', t('The specified form name is reserved for use by Drupal.'));
00299 }
00300
00301 if (!$form_state['values']['category']) {
00302 form_set_error('category', t('You must enter a category.'));
00303 }
00304 if (strtolower($form_state['values']['category']) == 'account') {
00305 form_set_error('category', t('The specified category name is reserved for use by Drupal.'));
00306 }
00307 $args1 = array($form_state['values']['title'], $form_state['values']['category']);
00308 $args2 = array($form_state['values']['name']);
00309 $query_suffix = '';
00310
00311 if (isset($form_state['values']['fid'])) {
00312 $args1[] = $args2[] = $form_state['values']['fid'];
00313 $query_suffix = ' AND fid != %d';
00314 }
00315
00316 if (db_result(db_query("SELECT fid FROM {profile_fields} WHERE title = '%s' AND category = '%s'" . $query_suffix, $args1))) {
00317 form_set_error('title', t('The specified title is already in use.'));
00318 }
00319 if (db_result(db_query("SELECT fid FROM {profile_fields} WHERE name = '%s'" . $query_suffix, $args2))) {
00320 form_set_error('name', t('The specified name is already in use.'));
00321 }
00322 if ($form_state['values']['visibility'] == PROFILE_HIDDEN) {
00323 if ($form_state['values']['required']) {
00324 form_set_error('required', t('A hidden field cannot be required.'));
00325 }
00326 if ($form_state['values']['register']) {
00327 form_set_error('register', t('A hidden field cannot be set to visible on the user registration form.'));
00328 }
00329 }
00330 }
00331
00335 function profile_field_form_submit($form, &$form_state) {
00336 if (!isset($form_state['values']['options'])) {
00337 $form_state['values']['options'] = '';
00338 }
00339 if (!isset($form_state['values']['page'])) {
00340 $form_state['values']['page'] = '';
00341 }
00342 if (!isset($form_state['values']['fid'])) {
00343 db_query("INSERT INTO {profile_fields} (title, name, explanation, category, type, weight, required, register, visibility, autocomplete, options, page) VALUES ('%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, '%s', '%s')", $form_state['values']['title'], $form_state['values']['name'], $form_state['values']['explanation'], $form_state['values']['category'], $form_state['values']['type'], $form_state['values']['weight'], $form_state['values']['required'], $form_state['values']['register'], $form_state['values']['visibility'], $form_state['values']['autocomplete'], $form_state['values']['options'], $form_state['values']['page']);
00344
00345 drupal_set_message(t('The field has been created.'));
00346 watchdog('profile', 'Profile field %field added under category %category.', array('%field' => $form_state['values']['title'], '%category' => $form_state['values']['category']), WATCHDOG_NOTICE, l(t('view'), 'admin/user/profile'));
00347 }
00348 else {
00349 db_query("UPDATE {profile_fields} SET title = '%s', name = '%s', explanation = '%s', category = '%s', weight = %d, required = %d, register = %d, visibility = %d, autocomplete = %d, options = '%s', page = '%s' WHERE fid = %d", $form_state['values']['title'], $form_state['values']['name'], $form_state['values']['explanation'], $form_state['values']['category'], $form_state['values']['weight'], $form_state['values']['required'], $form_state['values']['register'], $form_state['values']['visibility'], $form_state['values']['autocomplete'], $form_state['values']['options'], $form_state['values']['page'], $form_state['values']['fid']);
00350
00351 drupal_set_message(t('The field has been updated.'));
00352 }
00353 cache_clear_all();
00354 menu_rebuild();
00355
00356 $form_state['redirect'] = 'admin/user/profile';
00357 return;
00358 }
00359
00363 function profile_field_delete(&$form_state, $fid) {
00364 $field = db_fetch_object(db_query("SELECT title FROM {profile_fields} WHERE fid = %d", $fid));
00365 if (!$field) {
00366 drupal_not_found();
00367 return;
00368 }
00369 $form['fid'] = array('#type' => 'value', '#value' => $fid);
00370 $form['title'] = array('#type' => 'value', '#value' => $field->title);
00371
00372 return confirm_form($form,
00373 t('Are you sure you want to delete the field %field?', array('%field' => $field->title)), 'admin/user/profile',
00374 t('This action cannot be undone. If users have entered values into this field in their profile, these entries will also be deleted. If you want to keep the user-entered data, instead of deleting the field you may wish to <a href="@edit-field">edit this field</a> and change it to a hidden profile field so that it may only be accessed by administrators.', array('@edit-field' => url('admin/user/profile/edit/' . $fid))),
00375 t('Delete'), t('Cancel'));
00376 }
00377
00381 function profile_field_delete_submit($form, &$form_state) {
00382 db_query('DELETE FROM {profile_fields} WHERE fid = %d', $form_state['values']['fid']);
00383 db_query('DELETE FROM {profile_values} WHERE fid = %d', $form_state['values']['fid']);
00384
00385 cache_clear_all();
00386
00387 drupal_set_message(t('The field %field has been deleted.', array('%field' => $form_state['values']['title'])));
00388 watchdog('profile', 'Profile field %field deleted.', array('%field' => $form_state['values']['title']), WATCHDOG_NOTICE, l(t('view'), 'admin/user/profile'));
00389
00390 $form_state['redirect'] = 'admin/user/profile';
00391 return;
00392 }
00393
00397 function profile_admin_settings_autocomplete($string) {
00398 $matches = array();
00399 $result = db_query_range("SELECT category FROM {profile_fields} WHERE LOWER(category) LIKE LOWER('%s%%')", $string, 0, 10);
00400 while ($data = db_fetch_object($result)) {
00401 $matches[$data->category] = check_plain($data->category);
00402 }
00403 print drupal_to_js($matches);
00404 exit();
00405 }