2007-08-20 07:03:08 +00:00
< ? php
/**
* @ file
2011-11-28 11:44:25 +00:00
* Callbacks for adding , editing , and deleting content and managing revisions .
*
* Also includes validation , submission and other helper functions .
*
* @ see node_menu ()
2007-08-20 07:03:08 +00:00
*/
2013-03-10 19:05:24 +00:00
use Drupal\Core\Entity\EntityInterface ;
2007-08-20 07:03:08 +00:00
2011-11-28 11:44:25 +00:00
/**
2012-07-06 15:14:52 +00:00
* Page callback : Displays add content links for available content types .
*
* Redirects to node / add / [ type ] if only one content type is available .
2011-11-28 11:44:25 +00:00
*
2012-10-04 16:41:38 +00:00
* @ return array
* A render array for a list of the node types that can be added ; however , if
* there is only one node type defined for the site , the function redirects
* to the node add page for that one node type and does not return at all .
*
2011-11-28 11:44:25 +00:00
* @ see node_menu ()
*/
2007-08-20 07:03:08 +00:00
function node_add_page () {
2012-05-14 02:50:42 +00:00
$content = array ();
// Only use node types the user has access to.
foreach ( node_type_get_types () as $type ) {
2013-06-17 11:03:40 +00:00
if ( node_access ( 'create' , $type -> type )) {
2012-05-14 02:50:42 +00:00
$content [ $type -> type ] = $type ;
}
}
2008-08-14 13:47:35 +00:00
// Bypass the node/add listing if only one content type is available.
if ( count ( $content ) == 1 ) {
2012-05-14 02:50:42 +00:00
$type = array_shift ( $content );
drupal_goto ( 'node/add/' . $type -> type );
2008-08-14 13:47:35 +00:00
}
2012-05-14 02:50:42 +00:00
return array ( '#theme' => 'node_add_list' , '#content' => $content );
2007-08-20 07:03:08 +00:00
}
2007-12-06 09:58:34 +00:00
/**
2010-04-13 15:23:03 +00:00
* Returns HTML for a list of available node types for node creation .
*
* @ param $variables
* An associative array containing :
* - content : An array of content types .
2007-12-06 09:58:34 +00:00
*
2011-11-28 11:44:25 +00:00
* @ see node_add_page ()
2012-10-04 16:41:38 +00:00
*
2007-12-06 09:58:34 +00:00
* @ ingroup themeable
*/
2009-10-09 01:00:08 +00:00
function theme_node_add_list ( $variables ) {
$content = $variables [ 'content' ];
2007-08-20 07:03:08 +00:00
$output = '' ;
if ( $content ) {
$output = '<dl class="node-type-list">' ;
2012-05-14 02:50:42 +00:00
foreach ( $content as $type ) {
$output .= '<dt>' . l ( $type -> name , 'node/add/' . $type -> type ) . '</dt>' ;
$output .= '<dd>' . filter_xss_admin ( $type -> description ) . '</dd>' ;
2007-08-20 07:03:08 +00:00
}
$output .= '</dl>' ;
}
2009-08-04 06:44:48 +00:00
else {
2010-01-09 23:03:22 +00:00
$output = '<p>' . t ( 'You have not created any content types yet. Go to the <a href="@create-content">content type creation page</a> to add a new content type.' , array ( '@create-content' => url ( 'admin/structure/types/add' ))) . '</p>' ;
2009-08-04 06:44:48 +00:00
}
2007-08-20 07:03:08 +00:00
return $output ;
}
/**
2011-11-28 11:44:25 +00:00
* Page callback : Provides the node submission form .
*
2012-08-01 13:31:50 +00:00
* @ param $node_type
* The node type object for the submitted node .
2011-11-28 11:44:25 +00:00
*
2012-10-04 16:41:38 +00:00
* @ return array
* A node submission form .
2011-11-28 11:44:25 +00:00
*
* @ see node_menu ()
2007-08-20 07:03:08 +00:00
*/
2012-08-01 13:31:50 +00:00
function node_add ( $node_type ) {
2007-08-20 07:03:08 +00:00
global $user ;
2012-08-01 13:31:50 +00:00
$type = $node_type -> type ;
2012-10-18 08:59:12 +00:00
$langcode = module_invoke ( 'language' , 'get_default_langcode' , 'node' , $type );
2012-04-26 16:44:37 +00:00
$node = entity_create ( 'node' , array (
'uid' => $user -> uid ,
'name' => ( isset ( $user -> name ) ? $user -> name : '' ),
'type' => $type ,
2012-10-18 08:59:12 +00:00
'langcode' => $langcode ? $langcode : language_default () -> langcode ,
2013-03-10 19:05:24 +00:00
)) -> getBCEntity ();
2012-08-01 13:31:50 +00:00
drupal_set_title ( t ( 'Create @name' , array ( '@name' => $node_type -> name )), PASS_THROUGH );
2013-06-18 05:21:35 +00:00
return Drupal :: entityManager () -> getForm ( $node );
2007-08-20 07:03:08 +00:00
}
/**
2011-11-28 11:44:25 +00:00
* Generates a node preview .
*
2013-03-10 19:05:24 +00:00
* @ param \Drupal\Core\Entity\EntityInterface $node
2011-11-28 11:44:25 +00:00
* The node to preview .
*
* @ return
2012-10-04 16:41:38 +00:00
* An HTML - formatted string of a node preview .
2011-11-28 11:44:25 +00:00
*
* @ see node_form_build_preview ()
2007-08-20 07:03:08 +00:00
*/
2013-03-10 19:05:24 +00:00
function node_preview ( EntityInterface $node ) {
2007-08-20 07:03:08 +00:00
if ( node_access ( 'create' , $node ) || node_access ( 'update' , $node )) {
2009-08-18 06:01:07 +00:00
_field_invoke_multiple ( 'load' , 'node' , array ( $node -> nid => $node ));
2008-01-29 11:08:17 +00:00
// Load the user's name when needed.
2007-08-20 07:03:08 +00:00
if ( isset ( $node -> name )) {
// The use of isset() is mandatory in the context of user IDs, because
// user ID 0 denotes the anonymous user.
2009-03-14 23:01:38 +00:00
if ( $user = user_load_by_name ( $node -> name )) {
2007-08-20 07:03:08 +00:00
$node -> uid = $user -> uid ;
}
else {
$node -> uid = 0 ; // anonymous user
}
}
2008-10-12 04:30:09 +00:00
elseif ( $node -> uid ) {
2009-03-14 23:01:38 +00:00
$user = user_load ( $node -> uid );
2007-08-20 07:03:08 +00:00
$node -> name = $user -> name ;
}
2008-09-17 07:11:59 +00:00
$node -> changed = REQUEST_TIME ;
2007-08-20 07:03:08 +00:00
2008-01-29 11:08:17 +00:00
// Display a preview of the node.
2007-08-20 07:03:08 +00:00
if ( ! form_get_errors ()) {
2010-07-30 03:06:18 +00:00
$node -> in_preview = TRUE ;
2013-06-10 10:12:28 +00:00
$node_preview = array (
'#theme' => 'node_preview' ,
'#node' => $node ,
);
$output = drupal_render ( $node_preview );
2010-07-30 03:06:18 +00:00
unset ( $node -> in_preview );
2007-08-20 07:03:08 +00:00
}
return $output ;
}
}
/**
2010-04-13 15:23:03 +00:00
* Returns HTML for a node preview for display during node creation and editing .
2007-08-20 07:03:08 +00:00
*
2009-10-09 01:00:08 +00:00
* @ param $variables
* An associative array containing :
2012-04-26 16:44:37 +00:00
* - node : The node entity which is being previewed .
2007-12-06 09:58:34 +00:00
*
2012-08-16 11:30:43 +00:00
* @ see NodeFormController :: preview ()
2012-11-10 15:25:19 +00:00
* @ see node_preview ()
2012-10-04 16:41:38 +00:00
*
2007-12-06 09:58:34 +00:00
* @ ingroup themeable
2007-08-20 07:03:08 +00:00
*/
2009-10-09 01:00:08 +00:00
function theme_node_preview ( $variables ) {
$node = $variables [ 'node' ];
2012-03-01 01:03:30 +00:00
$output = '' ;
2008-01-10 15:57:10 +00:00
2012-12-28 23:03:17 +00:00
$elements = node_view ( $node , 'teaser' );
2012-10-30 02:15:21 +00:00
$elements [ '#attached' ][ 'library' ][] = array ( 'node' , 'drupal.node.preview' );
2010-04-11 18:33:44 +00:00
$trimmed = drupal_render ( $elements );
$elements = node_view ( $node , 'full' );
$full = drupal_render ( $elements );
2009-06-12 08:39:40 +00:00
// Do we need to preview trimmed version of post as well as full version?
if ( $trimmed != $full ) {
2007-08-20 07:03:08 +00:00
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>' ));
2008-04-14 17:48:46 +00:00
$output .= '<h3>' . t ( 'Preview trimmed version' ) . '</h3>' ;
2009-06-12 08:39:40 +00:00
$output .= $trimmed ;
2008-04-14 17:48:46 +00:00
$output .= '<h3>' . t ( 'Preview full version' ) . '</h3>' ;
2009-06-12 08:39:40 +00:00
$output .= $full ;
2007-08-20 07:03:08 +00:00
}
else {
2009-06-12 08:39:40 +00:00
$output .= $full ;
2007-08-20 07:03:08 +00:00
}
return $output ;
}
/**
2011-11-28 11:44:25 +00:00
* Page callback : Form constructor for node deletion confirmation form .
*
2012-10-04 16:41:38 +00:00
* @ param object $node
* A node object .
*
* @ return array
* A form array .
*
2012-11-10 15:25:19 +00:00
* @ see node_delete_confirm_submit ()
2011-11-28 11:44:25 +00:00
* @ see node_menu ()
2007-08-20 07:03:08 +00:00
*/
2009-11-08 10:02:41 +00:00
function node_delete_confirm ( $form , & $form_state , $node ) {
2010-02-17 05:42:42 +00:00
// Always provide entity id in the same form key as in the entity edit form.
$form [ 'nid' ] = array ( '#type' => 'value' , '#value' => $node -> nid );
2007-08-20 07:03:08 +00:00
return confirm_form ( $form ,
2012-07-22 18:07:00 +00:00
t ( 'Are you sure you want to delete %title?' , array ( '%title' => $node -> label ())),
2009-10-14 20:42:47 +00:00
'node/' . $node -> nid ,
2007-08-20 07:03:08 +00:00
t ( 'This action cannot be undone.' ),
2007-11-28 10:29:21 +00:00
t ( 'Delete' ),
2007-11-27 13:31:04 +00:00
t ( 'Cancel' )
);
2007-08-20 07:03:08 +00:00
}
/**
2011-11-28 11:44:25 +00:00
* Form submission handler for node_delete_confirm () .
2007-08-20 07:03:08 +00:00
*/
function node_delete_confirm_submit ( $form , & $form_state ) {
if ( $form_state [ 'values' ][ 'confirm' ]) {
2009-05-20 05:39:45 +00:00
$node = node_load ( $form_state [ 'values' ][ 'nid' ]);
2013-06-03 10:00:40 +00:00
$node -> delete ();
2012-07-22 18:07:00 +00:00
watchdog ( 'content' , '@type: deleted %title.' , array ( '@type' => $node -> type , '%title' => $node -> label ()));
2012-09-19 09:54:05 +00:00
drupal_set_message ( t ( '@type %title has been deleted.' , array ( '@type' => node_get_type_label ( $node ), '%title' => $node -> label ())));
2007-08-20 07:03:08 +00:00
}
$form_state [ 'redirect' ] = '<front>' ;
}
/**
2011-11-28 11:44:25 +00:00
* Page callback : Generates an overview table of older revisions of a node .
*
2012-10-04 16:41:38 +00:00
* @ param object $node
* A node object .
*
* @ return array
* An array as expected by drupal_render () .
*
2011-11-28 11:44:25 +00:00
* @ see node_menu ()
2007-08-20 07:03:08 +00:00
*/
2009-11-08 10:02:41 +00:00
function node_revision_overview ( $node ) {
2012-07-22 18:07:00 +00:00
drupal_set_title ( t ( 'Revisions for %title' , array ( '%title' => $node -> label ())), PASS_THROUGH );
2007-08-20 07:03:08 +00:00
2012-10-09 19:49:07 +00:00
$header = array ( t ( 'Revision' ), t ( 'Operations' ));
2007-08-20 07:03:08 +00:00
$revisions = node_revision_list ( $node );
$rows = array ();
2012-11-29 07:28:47 +00:00
$type = $node -> type ;
2007-08-20 07:03:08 +00:00
$revert_permission = FALSE ;
2012-11-29 07:28:47 +00:00
if (( user_access ( " revert $type revisions " ) || user_access ( 'revert all revisions' ) || user_access ( 'administer nodes' )) && node_access ( 'update' , $node )) {
2007-08-20 07:03:08 +00:00
$revert_permission = TRUE ;
}
$delete_permission = FALSE ;
2012-11-29 07:28:47 +00:00
if (( user_access ( " delete $type revisions " ) || user_access ( 'delete all revisions' ) || user_access ( 'administer nodes' )) && node_access ( 'delete' , $node )) {
2007-08-20 07:03:08 +00:00
$delete_permission = TRUE ;
}
foreach ( $revisions as $revision ) {
$row = array ();
2012-11-29 07:28:47 +00:00
$type = $node -> type ;
2007-08-20 07:03:08 +00:00
if ( $revision -> current_vid > 0 ) {
2013-06-10 10:12:28 +00:00
$username = array (
'#theme' => 'username' ,
'#account' => $revision ,
);
$row [] = array ( 'data' => t ( '!date by !username' , array ( '!date' => l ( format_date ( $revision -> revision_timestamp , 'short' ), " node/ $node->nid " ), '!username' => drupal_render ( $username )))
2008-04-14 17:48:46 +00:00
. (( $revision -> log != '' ) ? '<p class="revision-log">' . filter_xss ( $revision -> log ) . '</p>' : '' ),
2009-08-22 14:34:23 +00:00
'class' => array ( 'revision-current' ));
2012-10-09 19:49:07 +00:00
$row [] = array ( 'data' => drupal_placeholder ( t ( 'current revision' )), 'class' => array ( 'revision-current' ));
2007-08-20 07:03:08 +00:00
}
else {
2013-06-10 10:12:28 +00:00
$username = array (
'#theme' => 'username' ,
'#account' => $revision ,
);
$row [] = t ( '!date by !username' , array ( '!date' => l ( format_date ( $revision -> revision_timestamp , 'short' ), " node/ $node->nid /revisions/ $revision->vid /view " ), '!username' => drupal_render ( $username )))
2008-04-14 17:48:46 +00:00
. (( $revision -> log != '' ) ? '<p class="revision-log">' . filter_xss ( $revision -> log ) . '</p>' : '' );
2007-08-20 07:03:08 +00:00
if ( $revert_permission ) {
2012-10-09 19:49:07 +00:00
$links [ 'revert' ] = array (
2013-02-15 02:53:23 +00:00
'title' => t ( 'Revert' ),
2012-10-09 19:49:07 +00:00
'href' => " node/ $node->nid /revisions/ $revision->vid /revert " ,
);
2007-08-20 07:03:08 +00:00
}
if ( $delete_permission ) {
2012-10-09 19:49:07 +00:00
$links [ 'delete' ] = array (
2013-02-15 02:53:23 +00:00
'title' => t ( 'Delete' ),
2012-10-09 19:49:07 +00:00
'href' => " node/ $node->nid /revisions/ $revision->vid /delete " ,
);
2007-08-20 07:03:08 +00:00
}
2012-10-09 19:49:07 +00:00
$row [] = array (
'data' => array (
'#type' => 'operations' ,
'#links' => $links ,
),
);
2007-08-20 07:03:08 +00:00
}
2012-10-09 19:49:07 +00:00
$rows [] = $row ;
2007-08-20 07:03:08 +00:00
}
2009-12-28 11:12:55 +00:00
2009-07-29 06:39:35 +00:00
$build [ 'node_revisions_table' ] = array (
'#theme' => 'table' ,
'#rows' => $rows ,
'#header' => $header ,
2012-03-01 01:03:30 +00:00
'#attached' => array (
2013-06-07 10:48:55 +00:00
'css' => array ( drupal_get_path ( 'module' , 'node' ) . '/css/node.admin.css' ),
2012-03-01 01:03:30 +00:00
),
2009-07-29 06:39:35 +00:00
);
2007-08-20 07:03:08 +00:00
2009-07-29 06:39:35 +00:00
return $build ;
2007-08-20 07:03:08 +00:00
}
2007-12-03 07:45:15 +00:00
/**
2011-11-28 11:44:25 +00:00
* Page callback : Form constructor for the reversion confirmation form .
*
* This form prevents against CSRF attacks .
*
2012-10-04 16:41:38 +00:00
* @ param int $node_revision
* The node revision ID .
*
* @ return array
* An array as expected by drupal_render () .
*
2011-11-28 11:44:25 +00:00
* @ see node_menu ()
* @ see node_revision_revert_confirm_submit ()
2012-11-10 15:25:19 +00:00
* @ ingroup forms
2007-12-03 07:45:15 +00:00
*/
2009-09-18 00:12:48 +00:00
function node_revision_revert_confirm ( $form , $form_state , $node_revision ) {
2007-12-03 07:45:15 +00:00
$form [ '#node_revision' ] = $node_revision ;
2008-04-14 17:48:46 +00:00
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' ));
2007-12-03 07:45:15 +00:00
}
2011-11-28 11:44:25 +00:00
/**
* Form submission handler for node_revision_revert_confirm () .
*/
2007-12-03 07:45:15 +00:00
function node_revision_revert_confirm_submit ( $form , & $form_state ) {
$node_revision = $form [ '#node_revision' ];
2012-10-14 05:44:26 +00:00
$node_revision -> setNewRevision ();
2012-09-06 20:32:19 +00:00
// Make this the new default revision for the node.
2012-10-14 05:44:26 +00:00
$node_revision -> isDefaultRevision ( TRUE );
2012-04-26 23:33:58 +00:00
// The revision timestamp will be updated when the revision is saved. Keep the
// original one for the confirmation message.
$original_revision_timestamp = $node_revision -> revision_timestamp ;
$node_revision -> log = t ( 'Copy of the revision from %date.' , array ( '%date' => format_date ( $original_revision_timestamp )));
2007-12-03 07:45:15 +00:00
2012-04-26 16:44:37 +00:00
$node_revision -> save ();
2007-12-03 07:45:15 +00:00
2012-07-22 18:07:00 +00:00
watchdog ( 'content' , '@type: reverted %title revision %revision.' , array ( '@type' => $node_revision -> type , '%title' => $node_revision -> label (), '%revision' => $node_revision -> vid ));
2012-09-19 09:54:05 +00:00
drupal_set_message ( t ( '@type %title has been reverted back to the revision from %revision-date.' , array ( '@type' => node_get_type_label ( $node_revision ), '%title' => $node_revision -> label (), '%revision-date' => format_date ( $original_revision_timestamp ))));
2008-04-14 17:48:46 +00:00
$form_state [ 'redirect' ] = 'node/' . $node_revision -> nid . '/revisions' ;
2007-12-03 07:45:15 +00:00
}
2007-08-20 07:03:08 +00:00
2011-11-28 11:44:25 +00:00
/**
* Page callback : Form constructor for the revision deletion confirmation form .
*
* This form prevents against CSRF attacks .
*
2012-10-04 16:41:38 +00:00
* @ param $node_revision
* The node revision ID .
*
* @ return
* An array as expected by drupal_render () .
*
2011-11-28 11:44:25 +00:00
* @ see node_menu ()
* @ see node_revision_delete_confirm_submit ()
2012-11-10 15:25:19 +00:00
* @ ingroup forms
2011-11-28 11:44:25 +00:00
*/
2009-09-18 00:12:48 +00:00
function node_revision_delete_confirm ( $form , $form_state , $node_revision ) {
2007-12-03 07:45:15 +00:00
$form [ '#node_revision' ] = $node_revision ;
2008-04-14 17:48:46 +00:00
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' ));
2007-12-03 07:45:15 +00:00
}
2011-11-28 11:44:25 +00:00
/**
* Form submission handler for node_revision_delete_confirm () .
*/
2007-12-03 07:45:15 +00:00
function node_revision_delete_confirm_submit ( $form , & $form_state ) {
$node_revision = $form [ '#node_revision' ];
2009-09-25 14:24:34 +00:00
node_revision_delete ( $node_revision -> vid );
2012-07-22 18:07:00 +00:00
watchdog ( 'content' , '@type: deleted %title revision %revision.' , array ( '@type' => $node_revision -> type , '%title' => $node_revision -> label (), '%revision' => $node_revision -> vid ));
2012-09-19 09:54:05 +00:00
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_type_label ( $node_revision ), '%title' => $node_revision -> label ())));
2008-04-14 17:48:46 +00:00
$form_state [ 'redirect' ] = 'node/' . $node_revision -> nid ;
2013-05-26 20:18:10 +00:00
if ( db_query ( 'SELECT COUNT(DISTINCT vid) FROM {node_field_revision} WHERE nid = :nid' , array ( ':nid' => $node_revision -> nid )) -> fetchField () > 1 ) {
2007-12-03 07:45:15 +00:00
$form_state [ 'redirect' ] .= '/revisions' ;
}
}