<?php
/**
* This file implements the UI controller for managing comments.
*
* b2evolution - {@link http://b2evolution.net/}
* Released under GNU GPL License - {@link http://b2evolution.net/about/gnu-gpl-license}
* @copyright (c)2003-2020 by Francois Planque - {@link http://fplanque.com/}
*
* @package admin
*/
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
/**
* @var AdminUI
*/
global $AdminUI;
/**
* @var UserSettings
*/
global $UserSettings;
$action = param_action( 'list' );
// Set the third level tab
param( 'tab3', 'string', '', true );
// We should activate toolbar menu items for this controller
$activate_collection_toolbar = true;
/*
* Init the objects we want to work on.
*/
switch( $action )
{
case 'edit':
case 'update':
case 'update_edit':
case 'switch_view':
case 'publish':
case 'restrict':
case 'deprecate':
case 'delete_url':
case 'update_publish':
case 'delete':
if( $action != 'edit' && $action != 'switch_view' )
{ // Stop a request from the blocked IP addresses or Domains
antispam_block_request();
}
param( 'comment_ID', 'integer', true );
$edited_Comment = & Comment_get_by_ID( $comment_ID );
$edited_Comment_Item = & $edited_Comment->get_Item();
set_working_blog( $edited_Comment_Item->get_blog_ID() );
$BlogCache = & get_BlogCache();
$Collection = $Blog = & $BlogCache->get_by_ID( $blog );
// Some users can delete & change a status of comments in their own posts, set corresponding permlevel
if( $edited_Comment->is_meta() )
{ // Use special permissions for internal comment
$check_permname = 'meta_comment';
$check_permlevel = $action == 'delete' ? 'delete' : 'edit';
}
elseif( $action == 'publish' || $action == 'update_publish' )
{ // Load the new comment status from publish request and set perm check values
$publish_status = param( 'publish_status', 'string', '' );
$check_permname = 'comment!'.$publish_status;
$check_permlevel = ( $action == 'publish' ) ? 'moderate' : 'edit';
}
elseif( $action == 'deprecate' )
{ // set perm check values
$check_permname = 'comment!deprecated';
$check_permlevel = 'moderate';
}
else
{ // set default perm check values
$comment_status = param( 'comment_status', 'string', NULL );
$check_permname = 'comment!'.( empty( $comment_status ) ? 'CURSTATUS' : $comment_status );
$check_permlevel = ( $action == 'delete' ) ? 'delete' : 'edit';
}
// Check permission:
check_user_perm( $check_permname, $check_permlevel, true, $edited_Comment );
if( $action == 'edit' || $action == 'switch_view' )
{ // Restrict comment status by parent item:
$edited_Comment->restrict_status();
}
$comment_title = '';
$comment_content = htmlspecialchars_decode( $edited_Comment->content );
// Format content for editing, if we were not already in editing...
$Plugins_admin = & get_Plugins_admin();
$params = array( 'object_type' => 'Comment', 'object_Blog' => & $Blog );
$Plugins_admin->unfilter_contents( $comment_title /* by ref */, $comment_content /* by ref */, $edited_Comment->get_renderers_validated(), $params );
// Where are we going to redirect to?
param( 'redirect_to', 'url', url_add_param( $admin_url, 'ctrl=items&blog='.$blog.'&p='.$edited_Comment_Item->ID.( $edited_Comment->is_meta() ? '&comment_type=meta' : '' ), '&' ) );
break;
case 'elevate':
// Stop a request from the blocked IP addresses or Domains
antispam_block_request();
global $blog;
load_class( 'items/model/_item.class.php', 'Item' );
param( 'comment_ID', 'integer', true );
$edited_Comment = & Comment_get_by_ID( $comment_ID );
$BlogCache = & get_BlogCache();
$Collection = $Blog = & $BlogCache->get_by_ID( $blog );
// Check permission:
check_user_perm( 'blog_post!draft', 'edit', true, $blog );
break;
case 'trash_delete':
param( 'blog_ID', 'integer', 0 );
// Check permission:
check_user_perm( 'blogs', 'editall', true );
break;
case 'emptytrash':
// Check permission:
check_user_perm( 'blogs', 'all', true );
break;
case 'list':
case 'mass_delete':
if( $action == 'mass_delete' )
{ // Check permission:
check_user_perm( 'blogs', 'all', true );
}
// Check permission:
if( $tab3 == 'meta' )
{ // For internal comments:
$selected = autoselect_blog( 'meta_comment', 'blog' );
}
else
{ // For normal comments:
$selected = autoselect_blog( 'blog_comments', 'view' );
}
if( ! $selected )
{ // No blog could be selected
$Messages->add( TB_('You have no permission to edit comments.' ), 'error' );
$action = 'nil';
}
elseif( set_working_blog( $selected ) ) // set $blog & memorize in user prefs
{ // Selected a new blog:
$BlogCache = & get_BlogCache();
$Collection = $Blog = & $BlogCache->get_by_ID( $blog );
}
break;
case 'spam':
// Used for quick SPAM vote of comments
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
param( 'comment_ID', 'integer', true );
$edited_Comment = & Comment_get_by_ID( $comment_ID );
$edited_Comment_Item = & $edited_Comment->get_Item();
set_working_blog( $edited_Comment_Item->get_blog_ID() );
$BlogCache = & get_BlogCache();
$Collection = $Blog = & $BlogCache->get_by_ID( $blog );
// Check permission for spam voting
check_user_perm( 'blog_vote_spam_comments', 'edit', true, $Blog->ID );
if( $edited_Comment !== false )
{ // The comment still exists
if( $current_User->ID != $edited_Comment->author_user_ID )
{ // Do not allow users to vote on their own comments
$edited_Comment->set_vote( 'spam', param( 'value', 'string' ) );
$edited_Comment->dbupdate();
}
}
// Where are we going to redirect to?
param( 'redirect_to', 'url', url_add_param( $admin_url, 'ctrl=comments&blog='.$blog.'&filter=restore', '&' ) );
// Redirect so that a reload doesn't write to the DB twice:
header_redirect( $redirect_to, 303 ); // Will EXIT
// We have EXITed already at this point!!
break;
default:
debug_die( 'unhandled action 1' );
}
$AdminUI->breadcrumbpath_init( true, array( 'text' => TB_('Collections'), 'url' => $admin_url.'?ctrl=collections' ) );
$AdminUI->breadcrumbpath_add( TB_('Comments'), $admin_url.'?ctrl=comments&blog=$blog$&filter=restore' );
switch( $tab3 )
{
case 'listview':
$AdminUI->breadcrumbpath_add( TB_('List view'), $admin_url.'?ctrl=comments&blog=$blog$&tab3='.$tab3.'&filter=restore' );
break;
case 'fullview':
$AdminUI->breadcrumbpath_add( TB_('Full text view'), $admin_url.'?ctrl=comments&blog=$blog$&tab3='.$tab3.'&filter=restore' );
break;
case 'meta':
// Check permission for internal comments:
check_user_perm( 'meta_comment', 'view', true, $Blog->ID );
$AdminUI->breadcrumbpath_add( TB_('Internal comments'), $admin_url.'?ctrl=comments&blog=$blog$&tab3='.$tab3.'&filter=restore' );
break;
}
$AdminUI->set_path( 'collections' ); // Sublevel may be attached below
/**
* Perform action:
*/
switch( $action )
{
case 'nil':
// Do nothing
break;
case 'edit':
$AdminUI->title_titlearea = TB_('Editing comment').' #'.$edited_Comment->ID;
// Generate available blogs list:
$AdminUI->set_coll_list_params( 'blog_comments', 'view', array( 'ctrl' => 'comments', 'filter' => 'restore' ) );
/*
* Add sub menu entries:
* We do this here instead of _header because we need to include all filter params into regenerate_url()
*/
attach_browse_tabs( false );
$AdminUI->set_path( 'collections', 'comments' );
$AdminUI->breadcrumbpath_add( sprintf( TB_('Comment #%s'), $edited_Comment->ID ), '?ctrl=comments&comment_ID='.$edited_Comment->ID.'&action=edit' );
$AdminUI->breadcrumbpath_add( TB_('Edit'), '?ctrl=comments&comment_ID='.$edited_Comment->ID.'&action=edit' );
break;
case 'update_publish':
case 'update':
case 'update_edit':
case 'switch_view':
// fp> TODO: $edited_Comment->load_from_Request( true );
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
// Update the folding positions for current user per collection:
save_fieldset_folding_values( $Blog->ID );
// Check if current User can edit special comment settings which are allowed only from back-office:
$can_edit_backoffice_settings = ( param( 'from', 'string' ) == 'backoffice' &&
check_user_perm( 'admin', 'restricted' ) );
if( $edited_Comment->get_author_User() )
{ // This comment has been created by member
if( check_user_perm( 'users', 'edit' ) && param( 'comment_author_login', 'string', NULL ) !== NULL )
{ // Only admins can change the author
if( param_check_not_empty( 'comment_author_login', TB_('Please enter valid author login.') ) && param_check_login( 'comment_author_login', true ) )
{
if( ( $author_User = & $UserCache->get_by_login( $comment_author_login ) ) !== false )
{ // Update author user:
$edited_Comment->set_author_User( $author_User );
}
}
}
}
else
{ // If this is not a member comment
param( 'newcomment_author', 'string', true );
param( 'newcomment_author_email', 'string' );
param( 'newcomment_author_url', 'string' );
param_check_not_empty( 'newcomment_author', TB_('Please enter an author name.'), '' );
$edited_Comment->set( 'author', $newcomment_author );
param_check_email( 'newcomment_author_email', false );
$edited_Comment->set( 'author_email', $newcomment_author_email );
param_check_url( 'newcomment_author_url', 'posting', '' ); // Give posting permissions here
$edited_Comment->set( 'author_url', $newcomment_author_url );
if( $can_edit_backoffice_settings )
{ // It can be updated only from back-office:
param( 'comment_allow_msgform', 'integer', 0 );
$edited_Comment->set( 'allow_msgform', $comment_allow_msgform );
param( 'comment_anon_notify', 'integer', 0 );
$edited_Comment->set( 'anon_notify', $comment_anon_notify );
}
}
// Move to different post
if( param( 'moveto_post', 'string', false ) )
{ // Move to post is set
$comment_Item = & $edited_Comment->get_Item();
if( $comment_Item->ID != $moveto_post )
{ // Move to post was changed
// Check destination post
$ItemCache = & get_ItemCache();
if( ( $dest_Item = $ItemCache->get_by_ID( $moveto_post, false, false) ) !== false )
{ // the item exists
$dest_Item_Blog = & $dest_Item->get_Blog();
$dest_Item_Blog_User = & $dest_Item_Blog->get_owner_User();
$comment_Item_Blog = & $comment_Item->get_Blog();
$comment_Item_Blog_User = & $comment_Item_Blog->get_owner_User();
if( ($current_User->ID == $dest_Item_Blog_User->ID &&
$current_User->ID == $comment_Item_Blog_User->ID ) ||
( check_user_perm( 'blog_admin', 'edit', false, $dest_Item_Blog->ID ) &&
check_user_perm( 'blog_admin', 'edit', false, $comment_Item_Blog->ID ) ) )
{ // current user is the owner of both the source and the destination blogs or current user is admin for both blogs
$edited_Comment->set_Item( $dest_Item );
}
else
{
$Messages->add( TB_('Destination post blog owner is different!'), 'error' );
}
}
else
{ // the item doesn't exists
$Messages->add( sprintf( TB_('Post ID «%d» does not exist!'), $moveto_post ), 'error' );
}
}
}
$edited_Comment_Item = $edited_Comment->get_Item();
$edited_Comment_Item->load_Blog();
if( $edited_Comment_Item->Blog->get_setting( 'allow_html_comment' ) )
{ // HTML is allowed for this comment
$text_format = 'html';
}
else
{ // HTML is disallowed for this comment
$text_format = 'htmlspecialchars';
}
// Content:
param( 'content', $text_format );
// Don't allow the hidden text in comment content
$content = str_replace( '<!', '<!', $content );
// Renderers:
if( param( 'renderers_displayed', 'integer', 0 ) )
{ // use "renderers" value only if it has been displayed (may be empty)
global $Plugins;
$renderers = $Plugins->validate_renderer_list( param( 'renderers', 'array:string', array() ), array( 'Comment' => & $edited_Comment ) );
$edited_Comment->set_renderers( $renderers );
}
if( $edited_Comment_Item->Blog->get_setting( 'threaded_comments' ) &&
( param( 'in_reply_to_cmt_ID', 'integer', NULL, false, false, false ) !== false ) )
{ // Change a field "In reply to comment ID" if threaded comments are enabled for the blog
$in_reply_to_cmt_ID = get_param( 'in_reply_to_cmt_ID' );
$CommentCache = & get_CommentCache();
if( $in_reply_to_cmt_ID > 0 )
{ // Check new entered comment ID
if( ! empty( $edited_Comment->ID ) && $in_reply_to_cmt_ID == $edited_Comment->ID )
{ // Restrict such brake case
$Messages->add( TB_('This comment cannot be a reply to itself.'), 'error' );
}
elseif( ! ( $Comment = & $CommentCache->get_by_ID( $in_reply_to_cmt_ID, false, false ) ) )
{ // No comment exists
$Messages->add( TB_('The ID of the parent comment you entered does not exist.'), 'error' );
}
elseif( $Comment->item_ID != $edited_Comment_Item->ID )
{ // Item of new reply comment is not same
$Messages->add( TB_('The ID of the parent comment must belong to the same post.'), 'error' );
}
}
else
{ // Deny wrong comment ID
$in_reply_to_cmt_ID = NULL;
}
$edited_Comment->set( 'in_reply_to_cmt_ID', $in_reply_to_cmt_ID, true );
}
// Trigger event: a Plugin could add a $category="error" message here..
// This must get triggered before any internal validation and must pass all relevant params.
// The OpenID plugin will validate a given OpenID here (via redirect and coming back here).
$Plugins->trigger_event( 'CommentFormSent', array(
'dont_remove_pre' => true,
'comment_item_ID' => $edited_Comment_Item->ID,
'comment' => & $content,
'renderers' => $edited_Comment->get_renderers(),
) );
param_check_html( 'content', TB_('Invalid comment text.') ); // Check this is backoffice content (NOT with comment rules)
param_check_not_empty( 'content', TB_('Empty comment content is not allowed.') );
$edited_Comment->set( 'content', get_param( 'content' ) );
if( check_user_perm( 'admin', 'restricted' ) &&
check_user_perm( 'blog_edit_ts', 'edit', false, $Blog->ID ) )
{ // We use user date
param_date( 'comment_issue_date', TB_('Please enter a valid comment date.'), true );
if( strlen(get_param('comment_issue_date')) )
{ // only set it, if a date was given:
param_time( 'comment_issue_time' );
$edited_Comment->set( 'date', form_date( get_param( 'comment_issue_date' ), get_param( 'comment_issue_time' ) ) ); // TODO: cleanup...
}
}
param( 'comment_rating', 'integer', NULL );
$edited_Comment->set_from_Request( 'rating' );
$comment_status = param( 'comment_status', 'string', NULL );
if( $action == 'update_publish' )
{
$comment_status = $publish_status;
}
if( ! empty( $comment_status ) )
{ // Update status only if it was defined on the submitted form
$old_comment_status = $edited_Comment->get( 'status' );
$edited_Comment->set( 'status', $comment_status );
}
if( $can_edit_backoffice_settings )
{ // It can be updated only from back-office:
param( 'comment_author_url_nofollow', 'integer', 0 );
$edited_Comment->set_from_Request( 'author_url_nofollow' );
param( 'comment_author_url_ugc', 'integer', 0 );
$edited_Comment->set_from_Request( 'author_url_ugc' );
param( 'comment_author_url_sponsored', 'integer', 0 );
$edited_Comment->set_from_Request( 'author_url_sponsored' );
}
if( $Messages->has_errors() )
{ // There have been some validation errors:
break;
}
if( isset( $old_comment_status ) && $old_comment_status != $comment_status )
{ // Comment moderation is done, handle moderation "secret"
$edited_Comment->handle_qm_secret();
}
// If action is switch_view then don't save the edited Comment yet, only change the edit view
if( $action != 'switch_view' )
{ // UPDATE DB:
$edited_Comment->dbupdate(); // Commit update to the DB
// Get params to skip/force/mark email notifications:
param( 'comment_members_notified', 'string', NULL );
param( 'comment_community_notified', 'string', NULL );
// Execute or schedule email notifications:
$edited_Comment->handle_notifications( NULL, false, $comment_members_notified, $comment_community_notified );
$Messages->add( TB_('Comment has been updated.'), 'success' );
if( $action == 'update_edit' )
{ // Redirect back to the edit comment form in order to see the updated content correctly:
header_redirect( $admin_url.'?ctrl=comments&blog='.$blog.'&action=edit&comment_ID='.$edited_Comment->ID.'&redirect_to='.rawurlencode( $redirect_to ) );
/* exited */
}
else
{ // Redirect to previous page(e.g. comments list) after updating:
// We want to highlight the edited object on next list display:
$Session->set( 'fadeout_array', array( 'comment_ID' => array( $edited_Comment->ID ) ) );
header_redirect( $redirect_to );
/* exited */
}
}
break;
case 'publish':
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
$edited_Comment->set( 'status', $publish_status );
// Comment moderation is done, handle moderation "secret"
$edited_Comment->handle_qm_secret();
$edited_Comment->dbupdate(); // Commit update to the DB
// Get params to skip/force/mark email notifications:
param( 'comment_members_notified', 'string', NULL );
param( 'comment_community_notified', 'string', NULL );
// Execute or schedule email notifications:
$edited_Comment->handle_notifications( NULL, false, $comment_members_notified, $comment_community_notified );
// Set the success message corresponding for the new status
switch( $edited_Comment->status )
{
case 'published':
$success_message = TB_('Comment has been published.');
break;
case 'community':
$success_message = TB_('The comment is now visible by the community.');
break;
case 'protected':
$success_message = TB_('The comment is now visible by the members.');
break;
case 'review':
$success_message = TB_('The comment is now visible by moderators.');
break;
default:
$success_message = TB_('Comment has been updated.');
break;
}
$Messages->add( $success_message, 'success' );
header_redirect( $redirect_to );
/* exited */
break;
case 'restrict':
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
$edited_Comment->set( 'status', $comment_status );
// Comment moderation is done, handle moderation "secret"
$edited_Comment->handle_qm_secret();
$edited_Comment->dbupdate(); // Commit update to the DB
$Messages->add( TB_('Comment has been restricted.'), 'success' );
header_redirect( $redirect_to );
/* exited */
break;
case 'deprecate':
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
$edited_Comment->set('status', 'deprecated' );
// Comment moderation is done, handle moderation "secret"
$edited_Comment->handle_qm_secret();
$edited_Comment->dbupdate(); // Commit update to the DB
$Messages->add( TB_('Comment has been deprecated.'), 'success' );
header_redirect( $redirect_to );
/* exited */
break;
case 'delete_url':
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
$edited_Comment->set('author_url', NULL );
$edited_Comment->dbupdate(); // Commit update to the DB
$Messages->add( TB_('Comment url has been deleted.'), 'success' );
header_redirect( $redirect_to );
/* exited */
break;
case 'delete':
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
// fp> TODO: non JS confirm
$success_message = ( $edited_Comment->status == 'trash' || $edited_Comment->is_meta() ) ? TB_('Comment has been deleted.') : TB_('Comment has been recycled.');
// Delete from DB:
$edited_Comment->dbdelete();
$Messages->add( $success_message, 'success' );
header_redirect( $redirect_to );
break;
case 'trash_delete':
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
if( isset( $blog_ID ) && ( $blog_ID != 0 ) )
{ // delete by comment ids
$query = 'SELECT comment_ID
FROM T_comments
INNER JOIN T_items__item ON post_ID = comment_item_ID
INNER JOIN T_categories ON cat_ID = post_main_cat_ID
WHERE comment_status = "trash" AND cat_blog_ID = '.$DB->quote( $blog_ID );
$comment_ids = $DB->get_col( $query, 0, 'get trash comment ids' );
$result = Comment::db_delete_where( NULL, $comment_ids );
}
else
{ // delete by where clause
$result = Comment::db_delete_where( 'comment_status = "trash"' );
}
if( $result !== false )
{
$Messages->add( TB_('Recycle bin contents were successfully deleted.'), 'success' );
}
else
{
$Messages->add( TB_('Could not empty recycle bin.'), 'error' );
}
header_redirect( regenerate_url( 'action', 'action=list', '', '&' ) );
break;
case 'emptytrash':
/*
* Trash comments:
*/
$AdminUI->title_titlearea = TB_('Comment recycle bins');
/*
* Add sub menu entries:
* We do this here instead of _header because we need to include all filter params into regenerate_url()
*/
attach_browse_tabs( false );
$AdminUI->set_path( 'collections', 'comments' );
$AdminUI->breadcrumbpath_add( TB_('Comment recycle bins'), '?ctrl=comments&action=emptytrash' );
break;
case 'elevate':
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
$type = param( 'type', 'string', 'quote' );
$new_Item = new Item();
$new_Item->set( 'status', 'draft' );
$new_Item->set( 'main_cat_ID', $Blog->get_default_cat_ID() );
// Generate Item title from Comment content excerpt by first X words allowed for slug length:
$item_title = explode( ' ', $edited_Comment->get_excerpt() );
$item_title = array_slice( $item_title, 0, $Blog->get_setting( 'slug_limit' ) );
$new_Item->set( 'title', implode( ' ', $item_title ) );
if( $type == 'quote' )
{ // Set a post data for a quote mode:
$item_content = $edited_Comment->get_author_name().' '.TB_( 'wrote' ).':';
if( $new_Item->get_type_setting( 'allow_html' ) )
{ // Use html quote format if HTML is allowed for new creating post:
$item_content .= ' <blockquote>'.$edited_Comment->get( 'content' ).'</blockquote>';
}
else
{ // Use markdown quote format if HTML is NOT allowed for new creating post:
$item_content .= "\n> ".str_replace( "\n", "\n> ", $edited_Comment->get_content( 'raw_text' ) );
}
// Set creator as current user:
$new_Item->set_creator_by_login( $current_User->login );
}
else // $type == 'original'
{ // Set a post data for an original mode:
// Use an original comment content for new creating post:
$item_content = $edited_Comment->get( 'content' );
// Set a post creator:
$author_User = & $edited_Comment->get_author_User();
if( empty( $author_User ) )
{ // Use current user:
$new_Item->set_creator_by_login( $current_User->login );
}
else
{ // Use a comment author:
$new_Item->set_creator_by_login( $author_User->login );
}
}
// Get all attached files to the elevated Comment:
$comment_LinkOwner = new LinkComment( $edited_Comment );
$comment_Links = & $comment_LinkOwner->get_Links();
$comment_has_links = ! empty( $comment_Links );
if( ! $comment_has_links )
{ // If comment has at least one attached file then set content only after
// we will convert all inline tags to new link IDs after insert new Item:
// (otherwise note "Invalid inline file placeholders won't be displayed." appears)
$new_Item->set( 'content', $item_content );
}
if( ! $new_Item->dbinsert() )
{
$Messages->add( TB_( 'Unable to create the new post!' ), 'error' );
break;
}
if( $comment_has_links )
{ // Link all attached files from the elevated Comment to new create Item:
$item_LinkOwner = new LinkItem( $new_Item );
$inline_link_IDs = array();
foreach( $comment_Links as $comment_Link )
{
if( $item_link_ID = $item_LinkOwner->add_link( $comment_Link->get( 'file_ID' ), $comment_Link->get( 'position' ), $comment_Link->get( 'order' ), false ) )
{ // If file was linked successfully:
if( $comment_Link->get( 'position' ) == 'inline' )
{ // Store what inline link IDs should updated in Item's content:
$inline_link_IDs[ $comment_Link->ID ] = $item_link_ID;
}
}
}
if( ! empty( $inline_link_IDs ) )
{ // Replace comment inline link IDs with new item link IDs:
foreach( $inline_link_IDs as $comment_link_ID => $item_link_ID )
{
$item_content = replace_outside_code_tags( '/\[([a-z]+):'.$comment_link_ID.'/i', '[$1:'.$item_link_ID, $item_content );
}
}
// Set content with updated link IDs:
$new_Item->set( 'content', $item_content );
$new_Item->dbupdate();
}
// Deprecate the comment after elevating
$edited_Comment->set( 'status', 'deprecated' );
$edited_Comment->dbupdate();
// Move all child comments to new created post
move_child_comments_to_item( $edited_Comment->ID, $new_Item->ID );
header_redirect( url_add_param( $admin_url, 'ctrl=items&blog='.$blog.'&action=edit&p='.$new_Item->ID, '&' ) );
break;
case 'list':
case 'mass_delete':
/*
* Latest comments:
*/
$AdminUI->title_titlearea = TB_('Latest comments');
// Generate available blogs list:
$AdminUI->set_coll_list_params( 'blog_comments', 'view', array( 'ctrl' => 'comments', 'filter' => 'restore', 'tab3' => $tab3 ) );
/*
* Add sub menu entries:
* We do this here instead of _header because we need to include all filter params into regenerate_url()
*/
attach_browse_tabs();
$AdminUI->append_path_level( 'comments' );
if( empty( $tab3 ) )
{
$tab3 = 'fullview';
}
$AdminUI->set_path( 'collections', 'comments', $tab3 );
/*
* List of comments to display:
*/
$CommentList = new CommentList2( $Blog, NULL, 'CommentCache', 'cmnt_', $tab3 );
// Filter list:
if( $tab3 == 'meta' )
{ // Internal comments:
$CommentList->set_default_filters( array(
'types' => array( 'meta' ),
'order' => 'DESC',
) );
}
else
{ // Normal comments:
$CommentList->set_default_filters( array(
'statuses' => get_visibility_statuses( 'keys', array( 'redirected', 'trash' ) ),
//'comments' => $UserSettings->get( 'results_per_page' ),
'order' => 'DESC',
) );
}
$CommentList->load_from_Request();
/**
* Mass delete comments
*/
param( 'mass_type', 'string', '' );
if( $action == 'mass_delete' && !empty( $mass_type ) )
{
// Check that this action request is not a CSRF hacked request:
$Session->assert_received_crumb( 'comment' );
// Init the comment list query, but don't execute it
$CommentList->query_init();
// Set sql query to get deletable comment ids
$deletable_comments_query = 'SELECT DISTINCT '.$CommentList->Cache->dbIDname.' '
.$CommentList->CommentQuery->get_from()
.$CommentList->CommentQuery->get_where();
// Set an action param to display a correct template
$process_action = $action;
unset( $_POST['actionArray'] );
set_param( 'action', 'list' );
// Try to obtain some serious time to do some serious processing (15 minutes)
set_max_execution_time( 10000 );
}
break;
default:
debug_die( 'unhandled action 2' );
}
/*
* Page navigation:
*/
$AdminUI->set_path( 'collections', 'comments' );
if( $tab3 == 'fullview' || $tab3 == 'meta' )
{ // Load jquery UI to animate background color on change comment status and to transfer a comment to recycle bin
require_js_defer( '#jqueryUI#' );
}
if( $tab3 == 'fullview' || $tab3 == 'listview' )
{ // Init JS to autcomplete the user logins:
init_autocomplete_login_js( 'rsc_url', $AdminUI->get_template( 'autocomplete_plugin' ) );
}
if( in_array( $action, array( 'edit', 'update_publish', 'update', 'update_edit', 'elevate', 'switch_view' ) ) )
{ // Initialize date picker for _comment.form.php
init_datepicker_js();
// Init JS to autocomplete the user logins:
init_autocomplete_login_js( 'rsc_url', $AdminUI->get_template( 'autocomplete_plugin' ) );
// Require colorbox js:
require_js_helper( 'colorbox' );
}
require_css( $AdminUI->get_template( 'blog_base.css' ) ); // Default styles for the blog navigation
// Colorbox (a lightweight Lightbox alternative) allows to zoom on images and do slideshows with groups of images:
require_js_helper( 'colorbox' );
if( in_array( $action, array( 'edit', 'elevate', 'update_publish', 'update', 'update_edit', 'switch_view' ) ) || $tab3 == 'meta' )
{ // Page with comment edit form
// Initialize js to autocomplete usernames in comment form
init_autocomplete_usernames_js();
}
// Set an url for manual page:
switch( $action )
{
case 'edit':
case 'elevate':
case 'update':
case 'update_publish':
case 'update_edit':
case 'switch_view':
$AdminUI->set_page_manual_link( 'editing-comments' );
break;
case 'mass_delete':
$AdminUI->set_page_manual_link( 'comment-mass-deletion' );
break;
default:
switch( $tab3 )
{
case 'fullview':
$AdminUI->set_page_manual_link( 'comments-full-text-view' );
break;
case 'listview':
$AdminUI->set_page_manual_link( 'comments-list-view' );
break;
case 'meta':
$AdminUI->set_page_manual_link( 'comments-meta-discussion' );
break;
default:
$AdminUI->set_page_manual_link( 'comments-tab' );
}
break;
}
// Display <html><head>...</head> section! (Note: should be done early if actions do not redirect)
$AdminUI->disp_html_head();
// Display title, menu, messages, etc. (Note: messages MUST be displayed AFTER the actions)
$AdminUI->disp_body_top();
/**
* Display payload:
*/
switch( $action )
{
case 'nil':
// Do nothing
break;
case 'edit':
case 'elevate':
case 'update_publish':
case 'update': // on error
case 'update_edit': // on error
case 'switch_view':
// Begin payload block:
$AdminUI->disp_payload_begin();
// Display VIEW:
$AdminUI->disp_view( 'comments/views/_comment.form.php' );
// End payload block:
$AdminUI->disp_payload_end();
break;
case 'emptytrash':
// Begin payload block:
$AdminUI->disp_payload_begin();
// Display VIEW:
$AdminUI->disp_view( 'comments/views/_trash_comments.view.php' );
// End payload block:
$AdminUI->disp_payload_end();
break;
case 'list':
default:
// Begin payload block:
$AdminUI->disp_payload_begin();
$table_browse_template = $AdminUI->get_template( 'table_browse' );
echo $table_browse_template['table_start'];
echo $table_browse_template['left_col_start'];
if( ! empty( $process_action ) && $process_action == 'mass_delete' && !empty( $mass_type ) )
{ // Mass deleting of the comments
comment_mass_delete_process( $mass_type, $deletable_comments_query );
$CommentList->reset();
}
// Display VIEW:
if( $tab3 == 'fullview' || $tab3 == 'meta' )
{
$AdminUI->disp_view( 'comments/views/_browse_comments.view.php' );
}
else
{
$AdminUI->disp_view( 'comments/views/_comment_list_table.view.php' );
}
echo $table_browse_template['left_col_end'];
echo $table_browse_template['right_col_start'];
// Display VIEW:
$AdminUI->disp_view( 'comments/views/_comments_sidebar.view.php' );
echo $table_browse_template['right_col_end'];
echo $table_browse_template['table_end'];
// End payload block:
$AdminUI->disp_payload_end();
break;
}
// Display body bottom, debug info and close </html>:
$AdminUI->disp_global_footer();
?>