00001 <?php
00002
00003
00013 function node_page_edit($node) {
00014 drupal_set_title($node->title);
00015 return drupal_get_form($node->type . '_node_form', $node);
00016 }
00017
00018 function node_add_page() {
00019 $item = menu_get_item();
00020 $content = system_admin_menu_block($item);
00021 return theme('node_add_list', $content);
00022 }
00023
00029 function theme_node_add_list($content) {
00030 $output = '';
00031
00032 if ($content) {
00033 $output = '<dl class="node-type-list">';
00034 foreach ($content as $item) {
00035 $output .= '<dt>' . l($item['title'], $item['href'], $item['options']) . '</dt>';
00036 $output .= '<dd>' . filter_xss_admin($item['description']) . '</dd>';
00037 }
00038 $output .= '</dl>';
00039 }
00040 return $output;
00041 }
00042
00043
00047 function node_add($type) {
00048 global $user;
00049
00050 $types = node_get_types();
00051 $type = isset($type) ? str_replace('-', '_', $type) : NULL;
00052
00053 if (isset($types[$type]) && node_access('create', $type)) {
00054
00055 $node = array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => '');
00056
00057 drupal_set_title(t('Create @name', array('@name' => $types[$type]->name)));
00058 $output = drupal_get_form($type . '_node_form', $node);
00059 }
00060
00061 return $output;
00062 }
00063
00064 function node_form_validate($form, &$form_state) {
00065 node_validate($form_state['values'], $form);
00066 }
00067
00068 function node_object_prepare(&$node) {
00069
00070 $node_options = variable_get('node_options_' . $node->type, array('status', 'promote'));
00071
00072 if (!isset($node->nid)) {
00073 foreach (array('status', 'promote', 'sticky') as $key) {
00074 $node->$key = in_array($key, $node_options);
00075 }
00076 global $user;
00077 $node->uid = $user->uid;
00078 $node->created = time();
00079 }
00080 else {
00081 $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O');
00082 }
00083
00084 $node->revision = in_array('revision', $node_options);
00085
00086 node_invoke($node, 'prepare');
00087 node_invoke_nodeapi($node, 'prepare');
00088 }
00089
00093 function node_form(&$form_state, $node) {
00094 global $user;
00095
00096 if (isset($form_state['node'])) {
00097 $node = $form_state['node'] + (array)$node;
00098 }
00099 if (isset($form_state['node_preview'])) {
00100 $form['#prefix'] = $form_state['node_preview'];
00101 }
00102 $node = (object)$node;
00103 foreach (array('body', 'title', 'format') as $key) {
00104 if (!isset($node->$key)) {
00105 $node->$key = NULL;
00106 }
00107 }
00108 if (!isset($form_state['node_preview'])) {
00109 node_object_prepare($node);
00110 }
00111 else {
00112 $node->build_mode = NODE_BUILD_PREVIEW;
00113 }
00114
00115
00116 $form['#id'] = 'node-form';
00117
00118
00119
00120 foreach (array('nid', 'vid', 'uid', 'created', 'type', 'language') as $key) {
00121 $form[$key] = array(
00122 '#type' => 'value',
00123 '#value' => isset($node->$key) ? $node->$key : NULL,
00124 );
00125 }
00126
00127
00128 $form['changed'] = array(
00129 '#type' => 'hidden',
00130 '#default_value' => isset($node->changed) ? $node->changed : NULL,
00131 );
00132
00133 if ($extra = node_invoke($node, 'form', $form_state)) {
00134 $form = array_merge_recursive($form, $extra);
00135 }
00136 if (!isset($form['title']['#weight'])) {
00137 $form['title']['#weight'] = -5;
00138 }
00139
00140 $form['#node'] = $node;
00141
00142
00143
00144 if (!empty($node->revision) || user_access('administer nodes')) {
00145 $form['revision_information'] = array(
00146 '#type' => 'fieldset',
00147 '#title' => t('Revision information'),
00148 '#collapsible' => TRUE,
00149
00150 '#collapsed' => !$node->revision,
00151 '#weight' => 20,
00152 );
00153 $form['revision_information']['revision'] = array(
00154 '#access' => user_access('administer nodes'),
00155 '#type' => 'checkbox',
00156 '#title' => t('Create new revision'),
00157 '#default_value' => $node->revision,
00158 );
00159 $form['revision_information']['log'] = array(
00160 '#type' => 'textarea',
00161 '#title' => t('Log message'),
00162 '#rows' => 2,
00163 '#description' => t('An explanation of the additions or updates being made to help other authors understand your motivations.'),
00164 );
00165 }
00166
00167
00168 $form['author'] = array(
00169 '#type' => 'fieldset',
00170 '#access' => user_access('administer nodes'),
00171 '#title' => t('Authoring information'),
00172 '#collapsible' => TRUE,
00173 '#collapsed' => TRUE,
00174 '#weight' => 20,
00175 );
00176 $form['author']['name'] = array(
00177 '#type' => 'textfield',
00178 '#title' => t('Authored by'),
00179 '#maxlength' => 60,
00180 '#autocomplete_path' => 'user/autocomplete',
00181 '#default_value' => $node->name ? $node->name : '',
00182 '#weight' => -1,
00183 '#description' => t('Leave blank for %anonymous.', array('%anonymous' => variable_get('anonymous', t('Anonymous')))),
00184 );
00185 $form['author']['date'] = array(
00186 '#type' => 'textfield',
00187 '#title' => t('Authored on'),
00188 '#maxlength' => 25,
00189 '#description' => t('Format: %time. Leave blank to use the time of form submission.', array('%time' => !empty($node->date) ? $node->date : format_date($node->created, 'custom', 'Y-m-d H:i:s O'))),
00190 );
00191
00192 if (isset($node->date)) {
00193 $form['author']['date']['#default_value'] = $node->date;
00194 }
00195
00196
00197 $form['options'] = array(
00198 '#type' => 'fieldset',
00199 '#access' => user_access('administer nodes'),
00200 '#title' => t('Publishing options'),
00201 '#collapsible' => TRUE,
00202 '#collapsed' => TRUE,
00203 '#weight' => 25,
00204 );
00205 $form['options']['status'] = array(
00206 '#type' => 'checkbox',
00207 '#title' => t('Published'),
00208 '#default_value' => $node->status,
00209 );
00210 $form['options']['promote'] = array(
00211 '#type' => 'checkbox',
00212 '#title' => t('Promoted to front page'),
00213 '#default_value' => $node->promote,
00214 );
00215 $form['options']['sticky'] = array(
00216 '#type' => 'checkbox',
00217 '#title' => t('Sticky at top of lists'),
00218 '#default_value' => $node->sticky,
00219 );
00220
00221
00222 foreach (array('uid', 'created') as $key) {
00223 $form[$key] = array(
00224 '#type' => 'value',
00225 '#value' => $node->$key,
00226 );
00227 }
00228
00229
00230 $form['buttons'] = array();
00231 $form['buttons']['submit'] = array(
00232 '#type' => 'submit',
00233 '#value' => t('Save'),
00234 '#weight' => 5,
00235 '#submit' => array('node_form_submit'),
00236 );
00237 $form['buttons']['preview'] = array(
00238 '#type' => 'submit',
00239 '#value' => t('Preview'),
00240 '#weight' => 10,
00241 '#submit' => array('node_form_build_preview'),
00242 );
00243 if (!empty($node->nid) && node_access('delete', $node)) {
00244 $form['buttons']['delete'] = array(
00245 '#type' => 'submit',
00246 '#value' => t('Delete'),
00247 '#weight' => 15,
00248 '#submit' => array('node_form_delete_submit'),
00249 );
00250 }
00251 $form['#validate'][] = 'node_form_validate';
00252 $form['#theme'] = array($node->type . '_node_form', 'node_form');
00253 return $form;
00254 }
00255
00259 function node_body_field(&$node, $label, $word_count) {
00260
00261
00262 $include = !isset($node->teaser) || ($node->teaser == substr($node->body, 0, strlen($node->teaser)));
00263
00264 $form = array(
00265 '#after_build' => array('node_teaser_js', 'node_teaser_include_verify'));
00266
00267 $form['#prefix'] = '<div class="body-field-wrapper">';
00268 $form['#suffix'] = '</div>';
00269
00270 $form['teaser_js'] = array(
00271 '#type' => 'textarea',
00272 '#rows' => 10,
00273 '#teaser' => 'edit-body',
00274 '#teaser_checkbox' => 'edit-teaser-include',
00275 '#disabled' => TRUE,
00276 );
00277
00278 $form['teaser_include'] = array(
00279 '#type' => 'checkbox',
00280 '#title' => t('Show summary in full view'),
00281 '#default_value' => $include,
00282 '#prefix' => '<div class="teaser-checkbox">',
00283 '#suffix' => '</div>',
00284 );
00285
00286 $form['body'] = array(
00287 '#type' => 'textarea',
00288 '#title' => check_plain($label),
00289 '#default_value' => $include ? $node->body : ($node->teaser . $node->body),
00290 '#rows' => 20,
00291 '#required' => ($word_count > 0),
00292 );
00293
00294 $form['format'] = filter_form($node->format);
00295
00296 return $form;
00297 }
00298
00302 function node_form_delete_submit($form, &$form_state) {
00303 $destination = '';
00304 if (isset($_REQUEST['destination'])) {
00305 $destination = drupal_get_destination();
00306 unset($_REQUEST['destination']);
00307 }
00308 $node = $form['#node'];
00309 $form_state['redirect'] = array('node/' . $node->nid . '/delete', $destination);
00310 }
00311
00312
00313 function node_form_build_preview($form, &$form_state) {
00314 $node = node_form_submit_build_node($form, $form_state);
00315 $form_state['node_preview'] = node_preview($node);
00316 }
00317
00323 function theme_node_form($form) {
00324 $output = "\n<div class=\"node-form\">\n";
00325
00326
00327
00328
00329 $admin = '';
00330 if (isset($form['author'])) {
00331 $admin .= " <div class=\"authored\">\n";
00332 $admin .= drupal_render($form['author']);
00333 $admin .= " </div>\n";
00334 }
00335 if (isset($form['options'])) {
00336 $admin .= " <div class=\"options\">\n";
00337 $admin .= drupal_render($form['options']);
00338 $admin .= " </div>\n";
00339 }
00340 $buttons = drupal_render($form['buttons']);
00341
00342
00343
00344 $output .= " <div class=\"standard\">\n";
00345 $output .= drupal_render($form);
00346 $output .= " </div>\n";
00347
00348 if (!empty($admin)) {
00349 $output .= " <div class=\"admin\">\n";
00350 $output .= $admin;
00351 $output .= " </div>\n";
00352 }
00353 $output .= $buttons;
00354 $output .= "</div>\n";
00355
00356 return $output;
00357 }
00358
00362 function node_preview($node) {
00363 if (node_access('create', $node) || node_access('update', $node)) {
00364
00365 if (isset($node->name)) {
00366
00367
00368 if ($user = user_load(array('name' => $node->name))) {
00369 $node->uid = $user->uid;
00370 $node->picture = $user->picture;
00371 }
00372 else {
00373 $node->uid = 0;
00374 }
00375 }
00376 else if ($node->uid) {
00377 $user = user_load(array('uid' => $node->uid));
00378 $node->name = $user->name;
00379 $node->picture = $user->picture;
00380 }
00381
00382 $node->changed = time();
00383
00384
00385
00386 if (!isset($node->teaser)) {
00387 $node->teaser = empty($node->body) ? '' : node_teaser($node->body, $node->format);
00388
00389 if (!$node->teaser_include && $node->teaser == substr($node->body, 0, strlen($node->teaser))) {
00390 $node->body = substr($node->body, strlen($node->teaser));
00391 }
00392 }
00393
00394
00395
00396 if (!form_get_errors()) {
00397 $cloned_node = clone $node;
00398 $cloned_node->build_mode = NODE_BUILD_PREVIEW;
00399 $output = theme('node_preview', $cloned_node);
00400 }
00401 drupal_set_title(t('Preview'));
00402
00403 return $output;
00404 }
00405 }
00406
00415 function theme_node_preview($node) {
00416 $output = '<div class="preview">';
00417
00418 $preview_trimmed_version = FALSE;
00419
00420 if (isset($node->teaser) && isset($node->body)) {
00421 $teaser = trim($node->teaser);
00422 $body = trim(str_replace('<!--break-->', '', $node->body));
00423
00424
00425
00426
00427 if ($teaser != $body || ($body && strpos($node->body, '<!--break-->') === 0)) {
00428 $preview_trimmed_version = TRUE;
00429 }
00430 }
00431
00432 if ($preview_trimmed_version) {
00433 drupal_set_message(t('The trimmed version of your post shows what your post looks like when promoted to the main page or when exported for syndication.<span class="no-js"> You can insert the delimiter "<!--break-->" (without the quotes) to fine-tune where your post gets split.</span>'));
00434 $output .= '<h3>' . t('Preview trimmed version') . '</h3>';
00435 $output .= node_view(clone $node, 1, FALSE, 0);
00436 $output .= '<h3>' . t('Preview full version') . '</h3>';
00437 $output .= node_view($node, 0, FALSE, 0);
00438 }
00439 else {
00440 $output .= node_view($node, 0, FALSE, 0);
00441 }
00442 $output .= "</div>\n";
00443
00444 return $output;
00445 }
00446
00447 function node_form_submit($form, &$form_state) {
00448 global $user;
00449
00450 $node = node_form_submit_build_node($form, $form_state);
00451 $insert = empty($node->nid);
00452 node_save($node);
00453 $node_link = l(t('view'), 'node/' . $node->nid);
00454 $watchdog_args = array('@type' => $node->type, '%title' => $node->title);
00455 $t_args = array('@type' => node_get_types('name', $node), '%title' => $node->title);
00456
00457 if ($insert) {
00458 watchdog('content', '@type: added %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
00459 drupal_set_message(t('@type %title has been created.', $t_args));
00460 }
00461 else {
00462 watchdog('content', '@type: updated %title.', $watchdog_args, WATCHDOG_NOTICE, $node_link);
00463 drupal_set_message(t('@type %title has been updated.', $t_args));
00464 }
00465 if ($node->nid) {
00466 unset($form_state['rebuild']);
00467 $form_state['nid'] = $node->nid;
00468 $form_state['redirect'] = 'node/' . $node->nid;
00469 }
00470 else {
00471
00472
00473 drupal_set_message(t('The post could not be saved.'), 'error');
00474 }
00475 }
00476
00480 function node_form_submit_build_node($form, &$form_state) {
00481
00482
00483 unset($form_state['submit_handlers']);
00484 form_execute_handlers('submit', $form, $form_state);
00485 $node = node_submit($form_state['values']);
00486 $form_state['node'] = (array)$node;
00487 $form_state['rebuild'] = TRUE;
00488 return $node;
00489 }
00490
00494 function node_delete_confirm(&$form_state, $node) {
00495 $form['nid'] = array(
00496 '#type' => 'value',
00497 '#value' => $node->nid,
00498 );
00499
00500 return confirm_form($form,
00501 t('Are you sure you want to delete %title?', array('%title' => $node->title)),
00502 isset($_GET['destination']) ? $_GET['destination'] : 'node/' . $node->nid,
00503 t('This action cannot be undone.'),
00504 t('Delete'),
00505 t('Cancel')
00506 );
00507 }
00508
00512 function node_delete_confirm_submit($form, &$form_state) {
00513 if ($form_state['values']['confirm']) {
00514 node_delete($form_state['values']['nid']);
00515 }
00516
00517 $form_state['redirect'] = '<front>';
00518 }
00519
00523 function node_revision_overview($node) {
00524 drupal_set_title(t('Revisions for %title', array('%title' => $node->title)));
00525
00526 $header = array(t('Revision'), array('data' => t('Operations'), 'colspan' => 2));
00527
00528 $revisions = node_revision_list($node);
00529
00530 $rows = array();
00531 $revert_permission = FALSE;
00532 if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) {
00533 $revert_permission = TRUE;
00534 }
00535 $delete_permission = FALSE;
00536 if ((user_access('delete revisions') || user_access('administer nodes')) && node_access('delete', $node)) {
00537 $delete_permission = TRUE;
00538 }
00539 foreach ($revisions as $revision) {
00540 $row = array();
00541 $operations = array();
00542
00543 if ($revision->current_vid > 0) {
00544 $row[] = array('data' => t('!date by !username', array('!date' => l(format_date($revision->timestamp, 'small'), "node/$node->nid"), '!username' => theme('username', $revision)))
00545 . (($revision->log != '') ? '<p class="revision-log">' . filter_xss($revision->log) . '</p>' : ''),
00546 'class' => 'revision-current');
00547 $operations[] = array('data' => theme('placeholder', t('current revision')), 'class' => 'revision-current', 'colspan' => 2);
00548 }
00549 else {
00550 $row[] = t('!date by !username', array('!date' => l(format_date($revision->timestamp, 'small'), "node/$node->nid/revisions/$revision->vid/view"), '!username' => theme('username', $revision)))
00551 . (($revision->log != '') ? '<p class="revision-log">' . filter_xss($revision->log) . '</p>' : '');
00552 if ($revert_permission) {
00553 $operations[] = l(t('revert'), "node/$node->nid/revisions/$revision->vid/revert");
00554 }
00555 if ($delete_permission) {
00556 $operations[] = l(t('delete'), "node/$node->nid/revisions/$revision->vid/delete");
00557 }
00558 }
00559 $rows[] = array_merge($row, $operations);
00560 }
00561
00562 return theme('table', $header, $rows);
00563 }
00564
00568 function node_revision_revert_confirm($form_state, $node_revision) {
00569 $form['#node_revision'] = $node_revision;
00570 return confirm_form($form, t('Are you sure you want to revert to the revision from %revision-date?', array('%revision-date' => format_date($node_revision->revision_timestamp))), 'node/' . $node_revision->nid . '/revisions', '', t('Revert'), t('Cancel'));
00571 }
00572
00573 function node_revision_revert_confirm_submit($form, &$form_state) {
00574 $node_revision = $form['#node_revision'];
00575 $node_revision->revision = 1;
00576 $node_revision->log = t('Copy of the revision from %date.', array('%date' => format_date($node_revision->revision_timestamp)));
00577 if (module_exists('taxonomy')) {
00578 $node_revision->taxonomy = array_keys($node_revision->taxonomy);
00579 }
00580
00581 node_save($node_revision);
00582
00583 watchdog('content', '@type: reverted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->title, '%revision' => $node_revision->vid));
00584 drupal_set_message(t('@type %title has been reverted back to the revision from %revision-date.', array('@type' => node_get_types('name', $node_revision), '%title' => $node_revision->title, '%revision-date' => format_date($node_revision->revision_timestamp))));
00585 $form_state['redirect'] = 'node/' . $node_revision->nid . '/revisions';
00586 }
00587
00588 function node_revision_delete_confirm($form_state, $node_revision) {
00589 $form['#node_revision'] = $node_revision;
00590 return confirm_form($form, t('Are you sure you want to delete the revision from %revision-date?', array('%revision-date' => format_date($node_revision->revision_timestamp))), 'node/' . $node_revision->nid . '/revisions', t('This action cannot be undone.'), t('Delete'), t('Cancel'));
00591 }
00592
00593 function node_revision_delete_confirm_submit($form, &$form_state) {
00594 $node_revision = $form['#node_revision'];
00595 db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $node_revision->nid, $node_revision->vid);
00596 node_invoke_nodeapi($node_revision, 'delete revision');
00597 watchdog('content', '@type: deleted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->title, '%revision' => $node_revision->vid));
00598 drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($node_revision->revision_timestamp), '@type' => node_get_types('name', $node_revision), '%title' => $node_revision->title)));
00599 $form_state['redirect'] = 'node/' . $node_revision->nid;
00600 if (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node_revision->nid)) > 1) {
00601 $form_state['redirect'] .= '/revisions';
00602 }
00603 }