00001 <?php
00002
00003
00012 function node_overview_types() {
00013 $types = node_get_types();
00014 $names = node_get_types('names');
00015 $header = array(t('Name'), t('Type'), t('Description'), array('data' => t('Operations'), 'colspan' => '2'));
00016 $rows = array();
00017
00018 foreach ($names as $key => $name) {
00019 $type = $types[$key];
00020 if (node_hook($type, 'form')) {
00021 $type_url_str = str_replace('_', '-', $type->type);
00022 $row = array(
00023 l($name, 'admin/build/node-type/' . $type_url_str),
00024 check_plain($type->type),
00025 filter_xss_admin($type->description),
00026 );
00027
00028 $row[] = array('data' => l(t('edit'), 'admin/build/node-type/' . $type_url_str));
00029
00030
00031 if ($type->custom) {
00032 $row[] = array('data' => l(t('delete'), 'admin/build/node-type/' . $type_url_str . '/delete'));
00033 }
00034 else {
00035 $row[] = array('data' => '');
00036 }
00037 $rows[] = $row;
00038 }
00039 }
00040
00041 if (empty($rows)) {
00042 $rows[] = array(array('data' => t('No content types available.'), 'colspan' => '5', 'class' => 'message'));
00043 }
00044
00045 return theme('table', $header, $rows);
00046 }
00047
00051 function node_type_form(&$form_state, $type = NULL) {
00052 if (!isset($type->type)) {
00053 $type = new stdClass();
00054 $type->type = $type->name = $type->module = $type->description = $type->help = '';
00055 $type->min_word_count = 0;
00056 $type->has_title = TRUE;
00057 $type->has_body = TRUE;
00058 $type->title_label = t('Title');
00059 $type->body_label = t('Body');
00060 $type->custom = TRUE;
00061 $type->modified = FALSE;
00062 $type->locked = FALSE;
00063 }
00064
00065 $form['#node_type'] = $type;
00066
00067 $form['identity'] = array(
00068 '#type' => 'fieldset',
00069 '#title' => t('Identification'),
00070 );
00071 $form['identity']['name'] = array(
00072 '#title' => t('Name'),
00073 '#type' => 'textfield',
00074 '#default_value' => $type->name,
00075 '#description' => t('The human-readable name of this content type. This text will be displayed as part of the list on the <em>create content</em> page. It is recommended that this name begin with a capital letter and contain only letters, numbers, and <strong>spaces</strong>. This name must be unique.'),
00076 '#required' => TRUE,
00077 );
00078
00079 if (!$type->locked) {
00080 $form['identity']['type'] = array(
00081 '#title' => t('Type'),
00082 '#type' => 'textfield',
00083 '#default_value' => $type->type,
00084 '#maxlength' => 32,
00085 '#required' => TRUE,
00086 '#description' => t('The machine-readable name of this content type. This text will be used for constructing the URL of the <em>create content</em> page for this content type. This name must contain only lowercase letters, numbers, and underscores. Underscores will be converted into hyphens when constructing the URL of the <em>create content</em> page. This name must be unique.'),
00087 );
00088 }
00089 else {
00090 $form['identity']['type'] = array(
00091 '#type' => 'value',
00092 '#value' => $type->type,
00093 );
00094 $form['identity']['type_display'] = array(
00095 '#title' => t('Type'),
00096 '#type' => 'item',
00097 '#value' => theme('placeholder', $type->type),
00098 '#description' => t('The machine-readable name of this content type. This field cannot be modified for system-defined content types.'),
00099 );
00100 }
00101
00102 $form['identity']['description'] = array(
00103 '#title' => t('Description'),
00104 '#type' => 'textarea',
00105 '#default_value' => $type->description,
00106 '#description' => t('A brief description of this content type. This text will be displayed as part of the list on the <em>create content</em> page.'),
00107 );
00108
00109 $form['submission'] = array(
00110 '#type' => 'fieldset',
00111 '#title' => t('Submission form settings'),
00112 '#collapsible' => TRUE,
00113 '#collapsed' => TRUE,
00114 );
00115 $form['submission']['title_label'] = array(
00116 '#title' => t('Title field label'),
00117 '#type' => 'textfield',
00118 '#default_value' => $type->title_label,
00119 '#required' => TRUE,
00120 );
00121 if (!$type->has_title) {
00122
00123
00124 $form['submission']['title_label']['#attributes'] = array('disabled' => 'disabled');
00125 $form['submission']['title_label']['#description'] = t('This content type does not have a title field.');
00126 $form['submission']['title_label']['#required'] = FALSE;
00127 }
00128 $form['submission']['body_label'] = array(
00129 '#title' => t('Body field label'),
00130 '#type' => 'textfield',
00131 '#default_value' => isset($type->body_label) ? $type->body_label : '',
00132 '#description' => t('To omit the body field for this content type, remove any text and leave this field blank.'),
00133 );
00134 $form['submission']['min_word_count'] = array(
00135 '#type' => 'select',
00136 '#title' => t('Minimum number of words'),
00137 '#default_value' => $type->min_word_count,
00138 '#options' => drupal_map_assoc(array(0, 10, 25, 50, 75, 100, 125, 150, 175, 200)),
00139 '#description' => t('The minimum number of words for the body field to be considered valid for this content type. This can be useful to rule out submissions that do not meet the site\'s standards, such as short test posts.')
00140 );
00141 $form['submission']['help'] = array(
00142 '#type' => 'textarea',
00143 '#title' => t('Explanation or submission guidelines'),
00144 '#default_value' => $type->help,
00145 '#description' => t('This text will be displayed at the top of the submission form for this content type. It is useful for helping or instructing your users.')
00146 );
00147 $form['workflow'] = array(
00148 '#type' => 'fieldset',
00149 '#title' => t('Workflow settings'),
00150 '#collapsible' => TRUE,
00151 '#collapsed' => TRUE,
00152 );
00153 $form['workflow']['node_options'] = array('#type' => 'checkboxes',
00154 '#title' => t('Default options'),
00155 '#default_value' => variable_get('node_options_' . $type->type, array('status', 'promote')),
00156 '#options' => array(
00157 'status' => t('Published'),
00158 'promote' => t('Promoted to front page'),
00159 'sticky' => t('Sticky at top of lists'),
00160 'revision' => t('Create new revision'),
00161 ),
00162 '#description' => t('Users with the <em>administer nodes</em> permission will be able to override these options.'),
00163 );
00164
00165 $form['old_type'] = array(
00166 '#type' => 'value',
00167 '#value' => $type->type,
00168 );
00169 $form['orig_type'] = array(
00170 '#type' => 'value',
00171 '#value' => isset($type->orig_type) ? $type->orig_type : '',
00172 );
00173 $form['module'] = array(
00174 '#type' => 'value',
00175 '#value' => $type->module,
00176 );
00177 $form['custom'] = array(
00178 '#type' => 'value',
00179 '#value' => $type->custom,
00180 );
00181 $form['modified'] = array(
00182 '#type' => 'value',
00183 '#value' => $type->modified,
00184 );
00185 $form['locked'] = array(
00186 '#type' => 'value',
00187 '#value' => $type->locked,
00188 );
00189
00190 $form['submit'] = array(
00191 '#type' => 'submit',
00192 '#value' => t('Save content type'),
00193 '#weight' => 40,
00194 );
00195
00196 if ($type->custom) {
00197 if (!empty($type->type)) {
00198 $form['delete'] = array(
00199 '#type' => 'submit',
00200 '#value' => t('Delete content type'),
00201 '#weight' => 45,
00202 );
00203 }
00204 }
00205 else {
00206 $form['reset'] = array(
00207 '#type' => 'submit',
00208 '#value' => t('Reset to defaults'),
00209 '#weight' => 50,
00210 );
00211 }
00212
00213 return $form;
00214 }
00215
00219 function node_type_form_validate($form, &$form_state) {
00220 $type = new stdClass();
00221 $type->type = trim($form_state['values']['type']);
00222 $type->name = trim($form_state['values']['name']);
00223
00224
00225 $old_type = trim($form_state['values']['old_type']);
00226
00227 $types = node_get_types('names');
00228
00229 if (!$form_state['values']['locked']) {
00230 if (isset($types[$type->type]) && $type->type != $old_type) {
00231 form_set_error('type', t('The machine-readable name %type is already taken.', array('%type' => $type->type)));
00232 }
00233 if (!preg_match('!^[a-z0-9_]+$!', $type->type)) {
00234 form_set_error('type', t('The machine-readable name must contain only lowercase letters, numbers, and underscores.'));
00235 }
00236
00237
00238 if (in_array($type->type, array('0', 'theme'))) {
00239 form_set_error('type', t("Invalid machine-readable name. Please enter a name other than %invalid.", array('%invalid' => $type->type)));
00240 }
00241 }
00242
00243 $names = array_flip($types);
00244
00245 if (isset($names[$type->name]) && $names[$type->name] != $old_type) {
00246 form_set_error('name', t('The human-readable name %name is already taken.', array('%name' => $type->name)));
00247 }
00248 }
00249
00253 function node_type_form_submit($form, &$form_state) {
00254 $op = isset($form_state['values']['op']) ? $form_state['values']['op'] : '';
00255
00256 $type = new stdClass();
00257
00258 $type->type = trim($form_state['values']['type']);
00259 $type->name = trim($form_state['values']['name']);
00260 $type->orig_type = trim($form_state['values']['orig_type']);
00261 $type->old_type = isset($form_state['values']['old_type']) ? $form_state['values']['old_type'] : $type->type;
00262
00263 $type->description = $form_state['values']['description'];
00264 $type->help = $form_state['values']['help'];
00265 $type->min_word_count = $form_state['values']['min_word_count'];
00266 $type->title_label = $form_state['values']['title_label'];
00267 $type->body_label = $form_state['values']['body_label'];
00268
00269
00270
00271 $type->has_title = ($type->title_label != '');
00272 $type->has_body = ($type->body_label != '');
00273
00274 $type->module = !empty($form_state['values']['module']) ? $form_state['values']['module'] : 'node';
00275 $type->custom = $form_state['values']['custom'];
00276 $type->modified = TRUE;
00277 $type->locked = $form_state['values']['locked'];
00278
00279 if ($op == t('Reset to defaults')) {
00280 node_type_reset($type);
00281 }
00282 elseif ($op == t('Delete content type')) {
00283 $form_state['redirect'] = 'admin/build/node-type/' . str_replace('_', '-', $type->old_type) . '/delete';
00284 return;
00285 }
00286
00287 $status = node_type_save($type);
00288
00289 $variables = $form_state['values'];
00290
00291
00292
00293 foreach ($variables as $key => $value) {
00294 if (isset($type->$key)) {
00295 unset($variables[$key]);
00296 }
00297 }
00298
00299 unset($variables['form_token'], $variables['op'], $variables['submit'], $variables['delete'], $variables['reset'], $variables['form_id']);
00300
00301
00302 foreach ($variables as $key => $value) {
00303 $variable_new = $key . '_' . $type->type;
00304 $variable_old = $key . '_' . $type->old_type;
00305
00306 if ($op == t('Reset to defaults')) {
00307 variable_del($variable_old);
00308 }
00309 else {
00310 if (is_array($value)) {
00311 $value = array_keys(array_filter($value));
00312 }
00313 variable_set($variable_new, $value);
00314
00315 if ($variable_new != $variable_old) {
00316 variable_del($variable_old);
00317 }
00318 }
00319 }
00320
00321 node_types_rebuild();
00322 menu_rebuild();
00323 $t_args = array('%name' => $type->name);
00324
00325 if ($op == t('Reset to defaults')) {
00326 drupal_set_message(t('The content type %name has been reset to its default values.', $t_args));
00327 return;
00328 }
00329
00330 if ($status == SAVED_UPDATED) {
00331 drupal_set_message(t('The content type %name has been updated.', $t_args));
00332 }
00333 elseif ($status == SAVED_NEW) {
00334 drupal_set_message(t('The content type %name has been added.', $t_args));
00335 watchdog('node', 'Added content type %name.', $t_args, WATCHDOG_NOTICE, l(t('view'), 'admin/build/types'));
00336 }
00337
00338 $form_state['redirect'] = 'admin/build/types';
00339 return;
00340 }
00341
00345 function node_node_type($op, $info) {
00346 if ($op != 'delete' && !empty($info->old_type) && $info->old_type != $info->type) {
00347 $update_count = node_type_update_nodes($info->old_type, $info->type);
00348
00349 if ($update_count) {
00350 drupal_set_message(format_plural($update_count, 'Changed the content type of 1 post from %old-type to %type.', 'Changed the content type of @count posts from %old-type to %type.', array('%old-type' => $info->old_type, '%type' => $info->type)));
00351 }
00352 }
00353 }
00354
00364 function node_type_reset(&$type) {
00365 $info_array = module_invoke_all('node_info');
00366 if (isset($info_array[$type->orig_type])) {
00367 $info = _node_type_set_defaults($info_array[$type->orig_type]);
00368 $info['type'] = $type->orig_type;
00369
00370 foreach ($info as $field => $value) {
00371 $type->$field = $value;
00372 }
00373 }
00374 }
00375
00379 function node_type_delete_confirm(&$form_state, $type) {
00380 $form['type'] = array('#type' => 'value', '#value' => $type->type);
00381 $form['name'] = array('#type' => 'value', '#value' => $type->name);
00382
00383 $message = t('Are you sure you want to delete the content type %type?', array('%type' => $type->name));
00384 $caption = '';
00385
00386 $num_nodes = db_result(db_query("SELECT COUNT(*) FROM {node} WHERE type = '%s'", $type->type));
00387 if ($num_nodes) {
00388 $caption .= '<p>' . format_plural($num_nodes, '<strong>Warning:</strong> there is currently 1 %type post on your site. It may not be able to be displayed or edited correctly, once you have removed this content type.', '<strong>Warning:</strong> there are currently @count %type posts on your site. They may not be able to be displayed or edited correctly, once you have removed this content type.', array('%type' => $type->name)) . '</p>';
00389 }
00390
00391 $caption .= '<p>' . t('This action cannot be undone.') . '</p>';
00392
00393 return confirm_form($form, $message, 'admin/build/types', $caption, t('Delete'));
00394 }
00395
00399 function node_type_delete_confirm_submit($form, &$form_state) {
00400 node_type_delete($form_state['values']['type']);
00401
00402 $t_args = array('%name' => $form_state['values']['name']);
00403 drupal_set_message(t('The content type %name has been deleted.', $t_args));
00404 watchdog('menu', 'Deleted content type %name.', $t_args, WATCHDOG_NOTICE);
00405
00406 node_types_rebuild();
00407 menu_rebuild();
00408
00409 $form_state['redirect'] = 'admin/build/types';
00410 return;
00411 }