* Invision Power Services
* IP.Board v3.3.4
* Moderator actions
* Last Updated: $Date: 2012-07-03 11:43:57 -0400 (Tue, 03 Jul 2012) $
*
*
* @author $Author: AndyMillne $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.invisionpower.com/company/standards.php#license
* @package IP.Board
* @subpackage Forums
* @link http://www.invisionpower.com
* @version $Revision: 11027 $
*/
if ( ! defined( 'IN_IPB' ) )
{
print "
Incorrect access
You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
exit();
}
class public_forums_moderate_moderate extends ipsCommand
{
/**
* Temporary stored output HTML
*
* @var string
*/
public $output;
/**
* Moderator function library
*
* @var object
*/
public $modLibrary;
/**
* Moderator information
*
* @var array Array of moderator details
*/
protected $moderator = array();
/**
* Forum information
*
* @var array Array of forum details
*/
protected $forum = array();
/**
* Topic information
*
* @var array Array of topic details
*/
protected $topic = array();
/**
* Topic ids stored
*
* @var array Topic ids for multimoderation
*/
protected $tids = array();
/**
* Post ids stored
*
* @var array Post ids for multimoderation
*/
protected $pids = array();
protected $fromSearch = false;
protected $returnUrl = false;
/**
* Class entry point
*
* @param object Registry reference
* @return @e void [Outputs to screen/redirects]
*/
public function doExecute( ipsRegistry $registry )
{
//-----------------------------------------
// Load language & skin files
//-----------------------------------------
ipsRegistry::getClass('class_localization')->loadLanguageFile( array( 'public_mod' ) );
/* If we're here auth_key was fine, so did we come from search? */
if ( $this->memberData['member_id'] AND $this->memberData['g_is_supmod'] AND $this->request['fromSearch'] AND $this->request['returnUrl'] )
{
$this->fromSearch = true;
$this->returnUrl = base64_decode( $this->request['returnUrl'] );
}
//-----------------------------------------
// Check the input
//-----------------------------------------
$this->_setupAndCheckInput();
//-----------------------------------------
// Load moderator functions
//-----------------------------------------
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( 'forums' ) . '/sources/classes/moderate.php', 'moderatorLibrary', 'forums' );
$this->modLibrary = new $classToLoad( $this->registry );
$this->modLibrary->init( $this->forum );
//-----------------------------------------
// Convert the code ID's into something
// use mere mortals can understand....
//-----------------------------------------
switch ( $this->request['do'] )
{
case '02':
$this->_moveForm();
break;
case '03':
$this->_deleteForm();
break;
case '04':
$this->_deletePost();
break;
case '05':
$this->_editform();
break;
case '00':
$this->_closeTopic();
break;
case '01':
$this->_openTopic();
break;
case '08':
$this->_deleteTopic();
break;
case '09':
$this->_deleteTopicPermanent();
break;
case '12':
$this->_doEdit();
break;
case '14':
$this->_doMove();
break;
case '15':
$this->_topicPinAlter( 'pin' );
break;
case '16':
$this->_topicPinAlter( 'unpin' );
break;
case 'sdelete':
$this->_softDeleteTopicToggle(true);
break;
case 'sundelete':
$this->_softDeleteTopicToggle(false);
break;
case 'deleteArchivedTopic':
$this->_deleteArchivedTopic();
break;
//-----------------------------------------
// Unsubscribe
//-----------------------------------------
case '30':
$this->_unsubscribeAllForm();
break;
case '31':
$this->_unsubscribeAll();
break;
//-----------------------------------------
// Merge Start
//-----------------------------------------
case '60':
$this->_mergeStart();
break;
case '61':
$this->_mergeComplete();
break;
//-----------------------------------------
// Topic History
//-----------------------------------------
case '90':
$this->_topicHistory();
break;
//-----------------------------------------
// Multi---
//-----------------------------------------
case 'topicchoice':
$this->_multiTopicModify();
break;
//-----------------------------------------
// Multi---
//-----------------------------------------
case 'postchoice':
$this->_multiPostModify();
break;
//-----------------------------------------
// Resynchronize Forum
//-----------------------------------------
case 'resync':
$this->_resyncForum();
break;
//-----------------------------------------
// Prune / Move Topics
//-----------------------------------------
case 'prune_start':
$this->_pruneStart();
break;
case 'prune_finish':
$this->_pruneFinish();
break;
case 'prune_move':
$this->_pruneMove();
break;
//-----------------------------------------
// Add. topic view func.
//-----------------------------------------
case 'topic_approve':
case 'topic_restore':
$this->_topicApproveAlter('approve');
break;
case 'topic_unapprove':
$this->_topicApproveAlter('unapprove');
break;
/* New options for 3.1 */
case 'p_approve':
$this->_postsManage('approve_unapproved');
break;
case 'p_delete_approve':
$this->_postsManage('delete_unapproved');
break;
case 'p_restore':
$this->_postsManage('restore_deleted');
break;
case 'p_delete_softed':
$this->_postsManage('delete_deleted');
break;
case 'p_hrestore':
$this->_postsManage('hdelete_restore');
break;
case 'p_hdelete':
$this->_postsManage('hdelete_delete');
break;
case 'unArchiveTopic':
$this->_topicUnarchive();
break;
default:
$this->_showError();
break;
}
// If we have any HTML to print, do so...
$this->registry->output->addContent( $this->output );
$this->registry->getClass('output')->sendOutput();
}
/**
* Flag a topic as unarchive.
* A tragically boring and mundane function written on a misty Monday morning
*/
protected function _topicUnarchive()
{
if ( ! $this->memberData['g_access_cp'] )
{
$this->_showError( 'moderate_no_permission', 103119.2, 403 );
}
/* Load up archive class */
$classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/archive/restore.php', 'classes_archive_restore' );
$archiveRestore = new $classToLoad();
$archiveRestore->setApp('forums');
$archiveRestore->setManualUnarchive( $this->topic['tid'] );
/* Back to topic, then? */
$this->registry->output->silentRedirect( $this->settings['base_url'] . "showtopic=" . $this->topic['tid'] . '&st=' . intval( $this->request['st'] ), $this->topic['title_seo'], "showtopic" );
}
/**
* A simple wrapper function for multimethods
*
* NO PERMISSION CHECKS WILL BE PERFORMED IN THIS FUNCTION
* AS CHECKS ARE PERFORMED IN ACTUAL FUNCTIONS
*
* @param string Type of action
*/
protected function _postsManage( $what )
{
$where = '';
$posts = array();
if ( $this->topic['tid'] )
{
switch ( $what )
{
case 'approve_unapproved':
case 'delete_unapproved':
$where = $this->registry->class_forums->fetchPostHiddenQuery( 'hidden' );
break;
case 'restore_deleted':
case 'delete_deleted':
$where = $this->registry->class_forums->fetchPostHiddenQuery( 'sdeleted' );
break;
}
if( is_array($this->request['pid']) )
{
foreach( $this->request['pid'] as $pid )
{
$pid = intval($pid);
$this->pids[ $pid ] = $pid;
}
}
else
{
/* Get posts */
$this->DB->build( array( 'select' => '*',
'from' => 'posts',
'where' => 'topic_id=' . $this->topic['tid'] . ' AND ' . $where ) );
$this->DB->execute();
while( $row = $this->DB->fetch() )
{
$this->pids[ $row['pid'] ] = $row['pid'];
}
}
$this->request['selectedpids'] = implode( ",", $this->pids );
/* now... */
if ( count( $this->pids ) )
{
switch ( $what )
{
case 'approve_unapproved':
$this->_multiApprovePost(1);
break;
case 'delete_unapproved':
$this->_multiDeletePost();
break;
case 'restore_deleted':
$this->_multiSoftDeletePost(0, '' );
break;
case 'delete_deleted':
$this->_multiDeletePost();
break;
case 'hdelete_restore':
$this->_multiRestoreHardDeletedPost();
break;
case 'hdelete_delete':
$this->_multiRemoveHardDeletedPost();
break;
}
if( $this->request['return'] )
{
$_bits = explode( ':', $this->request['return'] );
if( count($_bits) AND $_bits[0] == 'modcp' )
{
$this->registry->output->redirectScreen( $this->lang->words['cp_redirect_posts'], $this->settings['base_url'] . "app=core&module=modcp&fromapp=forums&tab=" . $_bits[1] . 'posts' );
}
}
/* Done */
$this->registry->output->redirectScreen( $this->lang->words['cp_redirect_posts'], $this->settings['base_url'] . "showtopic=" . $this->topic['tid'] . '&st=' . intval($this->request['st']), $this->topic['title_seo'], 'showtopic' );
}
}
/* Still here? */
$this->_showError( 'mod_no_tid', 103118.1 );
}
/**
* Permanently remove a hard deleted post. Only available via Mod CP as of 3.3.
*
* @return @e void
*/
protected function _multiRemoveHardDeletedPost()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'delete_post' );
$_titles = array();
$this->DB->build( array(
'select' => 'p.*',
'from' => array( 'posts' => 'p' ),
'where' => 'p.pid IN(' . implode( ',', $this->pids ) . ')',
'add_join' => array(
array(
'select' => 't.*',
'from' => array( 'topics' => 't' ),
'where' => 't.tid=p.topic_id',
'type' => 'left',
)
)
) );
$outer = $this->DB->execute();
while( $r = $this->DB->fetch($outer) )
{
$_titles[ $r['tid'] ] = $r['title'];
$this->modLibrary->init( $this->registry->getClass('class_forums')->allForums[ $r['forum_id'] ], $r );
$this->modLibrary->postDeleteFromDb( $r['pid'] );
$this->modLibrary->forumRecount( $r['forum_id'] );
$this->modLibrary->clearModQueueTable( 'post', $r['pid'] );
}
$this->modLibrary->addModerateLog( "", "", "", implode( ', ', $_titles ), sprintf( $this->lang->words['multi_post_delete'], implode( ', ', $this->pids ) ) );
}
/**
* Restore a hard deleted post. Only available via Mod CP as of 3.3.
*
* @return @e void
*/
protected function _multiRestoreHardDeletedPost()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'delete_post' );
$this->DB->update( 'posts', array( 'queued' => 0 ), 'pid IN(' . implode( ',', $this->pids ) . ')' );
/* Remove any soft delete logs */
IPSDeleteLog::removeEntries( $this->pids, 'post', true );
$this->DB->build( array(
'select' => 'p.*',
'from' => array( 'posts' => 'p' ),
'where' => 'p.pid IN(' . implode( ',', $this->pids ) . ')',
'add_join' => array(
array(
'select' => 't.*',
'from' => array( 'topics' => 't' ),
'where' => 't.tid=p.topic_id',
'type' => 'left',
)
)
) );
$outer = $this->DB->execute();
while( $r = $this->DB->fetch($outer) )
{
$this->modLibrary->init( $this->registry->getClass('class_forums')->allForums[ $r['forum_id'] ], $r );
$this->modLibrary->rebuildTopic( $r['tid'] );
$this->modLibrary->forumRecount( $r['forum_id'] );
$this->modLibrary->clearModQueueTable( 'post', $r['pid'] );
}
$this->cache->rebuildCache( 'stats', 'global' );
$this->modLibrary->addModerateLog( "", "", "", implode( ',', $this->pids ), sprintf( $this->lang->words['multi_post_restore'], implode( ',', $this->pids ) ) );
}
/**
* A simple wrapper function for multimethods
*
* NO PERMISSION CHECKS WILL BE PERFORMED IN THIS FUNCTION
* AS CHECKS ARE PERFORMED IN ACTUAL FUNCTIONS
*
* @param string Type of action
*/
protected function _topicsManage( $what )
{
$where = '';
$posts = array();
if ( $this->forum['id'] )
{
switch ( $what )
{
case 'approve_unapproved':
case 'delete_unapproved':
$where = $this->registry->class_forums->fetchTopicHiddenQuery( 'hidden' );
break;
case 'restore_deleted':
case 'delete_deleted':
$where = $this->registry->class_forums->fetchTopicHiddenQuery( 'sdeleted' );
break;
}
/* Get posts */
$this->DB->build( array( 'select' => '*',
'from' => 'topics',
'where' => 'forum_id=' . $this->forum['id'] . ' AND ' . $where ) );
$this->DB->execute();
while( $row = $this->DB->fetch() )
{
$this->tids[ $row['tid'] ] = $row['tid'];
}
$this->request['selectedtids'] = implode( ",", $this->tids );
/* now... */
if ( count( $this->tids ) )
{
switch ( $what )
{
case 'approve_unapproved':
$this->_multiAlterTopics('topic_q', $this->registry->getClass('class_forums')->fetchTopicHiddenQuery( array( 'visible' ), '' ) );
break;
case 'delete_unapproved':
$this->_multiAlterTopics('delete_topic');
break;
case 'restore_deleted':
$this->_multiSoftDeleteTopics(0, '' );
break;
case 'delete_deleted':
$this->_multiAlterTopics('delete_topic');
break;
}
/* Done */
$url = "showforum=" . $this->forum['id'];
$url = ( $this->request['st'] ) ? "showforum=" . $this->forum['id'] . '&st=' . $this->request['st'] : $url;
$this->registry->output->redirectScreen( $this->lang->words['cp_redirect_topics'], $this->settings['base_url'] . $url, $this->forum['name_seo'], 'showforum' );
}
}
/* Still here? */
$this->_showError( 'mod_no_tid', 103118.1 );
}
/**
* Alter approve/unapprove state of topic
*
* @param string [approve|unapprove]
* @return @e void [Outputs to screen]
*/
protected function _topicApproveAlter( $type='approve' )
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'post_q' );
$approve_int = $type == 'approve' ? 1 : 0;
$this->DB->update( 'topics', array( 'approved' => $approve_int ), 'tid=' . $this->topic['tid'] );
if ( $approve_int )
{
$this->modLibrary->clearModQueueTable( 'topic', $this->topic['tid'], true );
/* Likes */
require_once( IPS_ROOT_PATH . 'sources/classes/like/composite.php' );/*noLibHook*/
$_like = classes_like::bootstrap( 'forums', 'topics' );
$_like->toggleVisibility( $this->topic['tid'], true );
/* Tagging */
$this->registry->tags->updateVisibilityByMetaId( $this->topic['tid'], 1 );
/* Remove any soft delete logs if we are 'restoring' */
if( $this->request['do'] == 'topic_restore' )
{
IPSDeleteLog::removeEntries( array( $this->topic['tid'] ), 'topic', true );
}
}
$this->modLibrary->forumRecount( $this->forum['id'] );
$this->cache->rebuildCache( 'stats', 'global' );
$this->_addModeratorLog( sprintf( $type == 'approve' ? $this->lang->words['acp_approve_topic'] : $this->lang->words['acp_unapprove_topic'], $this->topic['tid'] ) );
if( $this->request['return'] )
{
$_bits = explode( ':', $this->request['return'] );
if( count($_bits) AND $_bits[0] == 'modcp' )
{
$this->registry->output->redirectScreen( $this->lang->words['redirect_modified'], $this->settings['base_url'] . "app=core&module=modcp&fromapp=forums&tab=" . $_bits[1] . 'topics' );
}
}
$this->registry->output->redirectScreen( $this->lang->words['redirect_modified'], $this->settings['base_url'] . "showtopic=" . $this->topic['tid'] . "&st=" . intval($this->request['st']), $this->topic['title_seo'], 'showtopic' );
}
/**
* Alter pin/unpinned state of topic
*
* @param string [pin|unpin]
* @return @e void [Outputs to screen]
*/
protected function _topicPinAlter( $type='pin' )
{
$this->_resetModerator( $this->topic['forum_id'] );
if( $type == 'pin' )
{
if ( $this->topic['pinned'] )
{
$this->_showError( 'mod_topic_pinned', 10371 );
}
$this->_genericPermissionCheck( 'pin_topic' );
$this->modLibrary->topicPin($this->topic['tid']);
$this->_addModeratorLog( $this->lang->words['acp_pinned_topic'] );
$words = $this->lang->words['p_pinned'];
}
else
{
if ( !$this->topic['pinned'] )
{
$this->_showError( 'mod_topic_unpinned', 10372 );
}
$this->_genericPermissionCheck( 'unpin_topic' );
$this->modLibrary->topicUnpin($this->topic['tid']);
$this->_addModeratorLog( $this->lang->words['acp_unpinned_topic'] );
$words = $this->lang->words['p_unpinned'];
}
$url = "showtopic=".$this->topic['tid']."&st=".intval($this->request['st']);
if( $this->request['from'] == 'forum' )
{
$url = "showforum=".$this->topic['forum_id']."&st=".intval($this->request['st']);
}
$this->registry->output->redirectScreen( $words, $this->settings['base_url'] . $url, $this->request['from'] == 'forum' ? $this->forum['name_seo'] : $this->topic['title_seo'], $this->request['from'] == 'forum' ? 'showforum' : 'showtopic' );
}
/**
* Alter pin/unpinned state of topic
*
* @return @e void [Outputs to screen]
*/
protected function _resyncForum()
{
$this->registry->class_forums->allForums[ $this->forum['id'] ]['_update_deletion'] = 1;
$this->modLibrary->forumRecount( $this->forum['id'] );
$this->cache->rebuildCache( 'stats', 'global' );
$this->registry->output->redirectScreen( $this->lang->words['cp_resync'], $this->settings['base_url'] . "showforum=".$this->forum['id'], $this->forum['name_seo'], 'showforum' );
}
/**
* Process post multi-moderation
*
* @return @e void [Outputs to screen]
*/
protected function _multiPostModify()
{
$this->pids = $this->_getIds( 'selectedpids', 'selectedpidsJS' );
if ( count( $this->pids ) )
{
/* Set pids back for templates */
$this->request['selectedpids'] = $this->pids;
switch ( $this->request['tact'] )
{
case 'approve':
$this->_multiApprovePost(1);
break;
case 'unapprove':
$this->_multiApprovePost(0);
break;
case 'deletedo':
$this->_multiDeletePost();
break;
case 'delete':
$this->_multiDeletePostSplash();
break;
case 'sdelete':
$this->_multiSoftDeletePost(1, $this->request['deleteReason'] );
break;
case 'sundelete':
$this->_multiSoftDeletePost(0);
break;
case 'merge':
$this->_multiMergePost();
break;
case 'split':
$this->_multiSplitTopic();
break;
case 'move':
$this->_multiMovePost();
break;
}
}
IPSCookie::set( 'modpids', '', 0 );
/* From modcp */
if( $this->request['return'] )
{
$_bits = explode( ':', $this->request['return'] );
if( count($_bits) AND $_bits[0] == 'modcp' )
{
$this->registry->output->redirectScreen( $this->lang->words['cp_redirect_posts'], $this->settings['base_url'] . "app=core&module=modcp&fromapp=forums&tab=" . $_bits[1] . 'posts' );
}
}
/* From search? */
if ( $this->fromSearch AND $this->returnUrl )
{
if ( $this->request['nr'] )
{
$this->registry->output->silentRedirect( $this->returnUrl );
}
else
{
$this->registry->output->redirectScreen( $this->lang->words['cp_redirect_posts'], $this->returnUrl );
}
}
else if ( $this->request['pid'] )
{
if ( $this->request['nr'] )
{
$this->registry->output->silentRedirect( $this->settings['base_url'] . "findpost=" . $this->request['pid'] );
}
else
{
$this->registry->output->redirectScreen( $this->lang->words['cp_redirect_posts'], $this->settings['base_url'] . "findpost=" . $this->request['pid'] );
}
}
else if ( $this->topic['tid'] )
{
$this->registry->output->redirectScreen( $this->lang->words['cp_redirect_posts'], $this->settings['base_url'] . "showtopic=" . $this->topic['tid'] . '&st=' . intval($this->request['st']), $this->topic['title_seo'], 'showtopic' );
}
}
/**
* Post multi-mod: Move posts
*
* @param string [Optional] error message
* @return @e void [Outputs to screen]
*/
protected function _multiMovePost( $error='' )
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'split_merge' );
if( ! $this->topic['tid'] )
{
$this->_showError( 'mod_no_tid', 10373, 404 );
}
if( $this->request['checked'] != 1 )
{
$posts = array();
//-----------------------------------------
// Display the posty wosty's
//-----------------------------------------
$this->DB->build( array(
'select' => 'p.post, p.pid, p.post_date, p.author_id, p.author_name, p.use_emo, p.post_htmlstate',
'from' => array( 'posts' => 'p' ),
'where' => 'p.topic_id=' . $this->topic['tid'] . ' AND p.pid IN (' . implode( ',', $this->pids ) . ')',
'order' => 'p.post_date',
'add_join' => array(
array( 'select' => 'm.member_group_id, m.mgroup_others',
'from' => array( 'members' => 'm' ),
'where' => 'm.member_id=p.author_id',
)
)
) );
$post_query = $this->DB->execute();
while( $row = $this->DB->fetch( $post_query ) )
{
$row['post'] = IPSText::truncate( $row['post'], 800 );
$row['date'] = ipsRegistry::getClass( 'class_localization')->getDate( $row['post_date'], 'LONG' );
/* Parse the post */
IPSText::getTextClass( 'bbcode' )->parse_smilies = $row['use_emo'];
IPSText::getTextClass( 'bbcode' )->parse_html = 0;
IPSText::getTextClass( 'bbcode' )->parse_nl2br = $row['post_htmlstate'] == 2 ? 1 : 0;
IPSText::getTextClass( 'bbcode' )->parse_bbcode = 1;
IPSText::getTextClass( 'bbcode' )->parsing_section = 'topics';
IPSText::getTextClass( 'bbcode' )->parsing_mgroup = $row['member_group_id'];
IPSText::getTextClass( 'bbcode' )->parsing_mgroup_others = $row['mgroup_others'];
$row['post'] = IPSText::getTextClass( 'bbcode' )->preDisplayParse( $row['post'] );
/* Add to output array */
$posts[] = $row;
}
//-----------------------------------------
// print my bottom, er, the bottom
//-----------------------------------------
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->movePostForm( $this->forum, $this->topic, $posts, $error );
$this->registry->getClass('output')->addNavigation( $this->forum['name'], "showforum={$this->forum['id']}", $this->forum['name_seo'], 'showforum' );
$this->registry->getClass('output')->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
$this->registry->getClass('output')->setTitle( $this->lang->words['cmp_title'].": ".$this->topic['title'] . ' - ' . ipsRegistry::$settings['board_name']);
$this->registry->output->addContent( $this->output );
$this->registry->getClass('output')->sendOutput();
}
else
{
//-----------------------------------------
// PROCESS Check the input
//-----------------------------------------
$old_id = $this->_getTidFromUrl();
if ( !$old_id )
{
$this->request[ 'checked'] = 0 ;
$this->_multiMovePost( $this->lang->words['cmp_notopic'] );
}
//-----------------------------------------
// Grab topic
//-----------------------------------------
$move_to_topic = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'topics', 'where' => 'tid=' . $old_id ) );
if ( ! $move_to_topic['tid'] or !$this->registry->class_forums->allForums[ $move_to_topic['forum_id'] ]['id'] )
{
$this->request[ 'checked'] = 0 ;
$this->_multiMovePost( $this->lang->words['cmp_notopic'] );
}
$affected_ids = count( $this->pids );
//-----------------------------------------
// Do we have enough?
//-----------------------------------------
if ( $affected_ids < 1 )
{
$this->_showError( 'mod_not_enough_split', 10374 );
}
//-----------------------------------------
// Do we choose too many?
//-----------------------------------------
$count = $this->DB->buildAndFetch( array( 'select' => 'count(pid) as cnt', 'from' => 'posts', 'where' => "topic_id={$this->topic['tid']}" ) );
if ( $affected_ids >= $count['cnt'] )
{
$this->_showError( 'mod_too_much_split', 10375 );
}
//-----------------------------------------
// Move the posts
//-----------------------------------------
$this->DB->update( 'posts', array( 'topic_id' => $move_to_topic['tid'], 'new_topic' => 0 ), "pid IN(" . implode( ",", $this->pids ) . ")" );
$this->DB->update( 'posts', array( 'new_topic' => 0 ), "topic_id={$this->topic['tid']}" );
//-----------------------------------------
// Update attachments
//-----------------------------------------
$this->DB->update( 'attachments', array( 'attach_parent_id' => $move_to_topic['tid'] ), "attach_rel_module='post' AND attach_rel_id IN(" . implode( ",", $this->pids ) . ")" );
//-----------------------------------------
// Is first post queued for new topic?
//-----------------------------------------
$first_post = $this->DB->buildAndFetch( array( 'select' => 'pid, queued',
'from' => 'posts',
'where' => "topic_id={$move_to_topic['tid']}",
'order' => $this->settings['post_order_column'] . ' ASC',
'limit' => array( 1 ),
) );
if( $first_post['queued'] )
{
$this->DB->update( 'topics', array( 'approved' => 0 ), "tid={$move_to_topic['tid']}" );
$this->DB->update( 'posts', array( 'queued' => 0 ), 'pid=' . $first_post['pid'] );
}
//-----------------------------------------
// Is first post queued for old topic?
//-----------------------------------------
$other_first_post = $this->DB->buildAndFetch( array( 'select' => 'pid, queued',
'from' => 'posts',
'where' => "topic_id={$this->topic['tid']}",
'order' => $this->settings['post_order_column'] . ' ASC',
'limit' => array( 1 ),
) );
if( $other_first_post['queued'] )
{
$this->DB->update( 'topics', array( 'approved' => 0 ), "tid={$this->topic['tid']}" );
$this->DB->update( 'posts', array( 'queued' => 0 ), 'pid=' . $other_first_post['pid'] );
}
//-----------------------------------------
// Rebuild the topics
//-----------------------------------------
$this->modLibrary->rebuildTopic($move_to_topic['tid']);
$this->modLibrary->rebuildTopic($this->topic['tid']);
//-----------------------------------------
// Update the forum(s)
//-----------------------------------------
$this->modLibrary->forumRecount( $this->topic['forum_id'] );
if ( $this->topic['forum_id'] != $move_to_topic['forum_id'] )
{
$this->modLibrary->forumRecount( $move_to_topic['forum_id'] );
}
$this->_addModeratorLog( sprintf( $this->lang->words['acp_moved_posts'], $this->topic['title'], $move_to_topic['title'] ) );
}
}
/**
* Post multi-mod: Soft delete posts
*
* @param integer 1=undelete, 0=restore
* @param string Reason for moderating the post
* @return @e void [Outputs to screen]
*/
protected function _multiSoftDeletePost( $delete=1, $reason='' )
{
$delete = ( $delete ) ? TRUE : FALSE;
$this->_resetModerator( $this->topic['forum_id'] );
/* Grab posts to check perms */
$this->DB->build( array( 'select' => '*',
'from' => 'posts',
'where' => 'pid IN (' . implode( ',', $this->pids ) . ')' ) );
$this->DB->execute();
while( $row = $this->DB->fetch() )
{
if ( $delete )
{
$result = $this->registry->getClass('class_forums')->canSoftDeletePosts( $this->topic['forum_id'], $row );
}
else
{
$result = $this->registry->getClass('class_forums')->can_Un_SoftDeletePosts( $this->topic['forum_id'] );
}
if ( ! $result )
{
$this->_showError( 'moderate_no_permission', 103119.1 );
}
}
/* Fetch entries and checked for lock status if not sup global */
//if ( ! $this->memberData['g_is_supmod'] )
//{
// $logs = IPSDeleteLog::fetchEntries( $this->pids, 'post' );
//
// if ( is_array( $logs ) )
// {
// foreach( $logs as $l => $data )
// {
// if ( $data['sdl_locked'] )
// {
// $this->_showError( 'moderate_no_permission_deleted_items', 10367.1 );
// }
// }
// }
//}
/* Ensure we check for a single topic id */
if ( ! $this->fromSearch )
{
$this->modLibrary->postToggleSoftDelete( $this->pids, $delete, $reason, $this->topic['tid'] );
}
else
{
$this->modLibrary->postToggleSoftDelete( $this->pids, $delete, $reason );
}
}
/**
* Post multi-mod: Approve posts
*
* @param integer 1=approve, 0=unapprove
* @return @e void [Outputs to screen]
*/
protected function _multiApprovePost( $approve=1 )
{
$_approve = ( $approve ) ? TRUE : FALSE;
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'post_q' );
/* Ensure we check for a single topic id */
if ( ! $this->fromSearch )
{
$this->modLibrary->postToggleApprove( $this->pids, $_approve, $this->topic['tid'] );
}
else
{
$this->modLibrary->postToggleApprove( $this->pids, $_approve );
}
}
/**
* Post multi-mod: Delete posts
*
* @return @e void [Outputs to screen]
*/
protected function _multiDeletePost()
{
$this->_resetModerator( $this->topic['forum_id'] );
if( !$this->_genericPermissionCheck( 'delete_post', null, true ) )
{
if( !$this->memberData['g_delete_own_posts'] )
{
$this->_showError( 'mod_delete_first_post', 10376.1 );
}
else
{
/* Sort for the query */
$_newPids = array();
$_pid = IPSLib::cleanIntArray( $this->pids );
if ( count($_pid) > 0 )
{
$_pid = " IN(" . implode( ",", $_pid ) . ")";
}
else
{
$this->_showError( 'mod_no_posts_to_del', 10376.3 );
}
/* Make sure we're the author of these posts */
$this->DB->build( array( 'select' => 'pid, author_id', 'from' => 'posts', 'where' => 'pid' . $_pid ) );
$this->DB->execute();
while( $_r = $this->DB->fetch() )
{
if( $_r['author_id'] == $this->memberData['member_id'] )
{
$_newPids[ $_r['pid'] ] = $_r['pid'];
}
}
$this->pids = $_newPids;
}
}
//-----------------------------------------
// Check to make sure that this isn't the first post in the topic..
//-----------------------------------------
if( !count($this->pids) )
{
$this->_showError( 'mod_no_posts_to_del', 10376.2 );
}
if ( empty( $this->topic ) )
{
$_pid = IPSLib::cleanIntArray( $this->pids );
if ( count($_pid) > 0 )
{
$_pid = " IN(" . implode( ",", $_pid ) . ")";
}
else
{
$this->_showError( 'mod_no_posts_to_del', 10376.3 );
}
$this->DB->build( array(
'select' => 'p.pid',
'from' => array( 'posts' => 'p' ),
'add_join' => array( array(
'select' => 't.topic_firstpost',
'from' => array( 'topics' => 't' ),
'where' => 't.tid=p.topic_id',
) ),
'where' => 'pid' . $_pid ) );
$this->DB->execute();
while( $_r = $this->DB->fetch() )
{
if ( $_r['topic_firstpost'] == $_r['pid'] )
{
$this->_showError( 'mod_delete_first_post', '10376-A' );
}
}
}
else
{
foreach( $this->pids as $p )
{
if ( $this->topic['topic_firstpost'] == $p )
{
$this->_showError( 'mod_delete_first_post', 10376 );
}
}
}
$this->_addModeratorLog( sprintf( $this->lang->words['multi_post_delete_mod_log'], count( $this->pids ), $this->topic['title'] ) );
$this->modLibrary->postDelete( $this->pids, true );
$this->modLibrary->clearModQueueTable( 'post', $this->pids );
}
/**
* Post multi-mod: Split topic
*
* @return @e void [Outputs to screen]
*/
protected function _multiSplitTopic()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'split_merge' );
if ( ! $this->fromSearch AND ! $this->topic['tid'] )
{
$this->_showError( 'mod_no_tid', 10377, 404 );
}
//-----------------------------------------
// Show the form
//-----------------------------------------
if ( $this->request['checked'] != 1 )
{
$jump_html = $this->registry->getClass('class_forums')->buildForumJump(0,1,1);
$posts = array();
//-----------------------------------------
// Display the posty wosty's
//-----------------------------------------
$this->DB->build( array(
'select' => 'p.post, p.pid, p.post_date, p.author_id, p.author_name, p.use_emo, p.post_htmlstate',
'from' => array( 'posts' => 'p' ),
'where' => 'p.topic_id=' . $this->topic['tid'] . ' AND p.pid IN (' . implode( ',', $this->pids ) . ')',
'order' => 'p.post_date',
'add_join' => array(
array( 'select' => 'm.member_group_id, m.mgroup_others',
'from' => array( 'members' => 'm' ),
'where' => 'm.member_id=p.author_id',
)
)
) );
$post_query = $this->DB->execute();
while ( $row = $this->DB->fetch($post_query) )
{
// This causes HTML to get cut off sometimes
//$row['post'] = IPSText::truncate( $row['post'], 800 );
$row['date'] = ipsRegistry::getClass( 'class_localization')->getDate( $row['post_date'], 'LONG' );
IPSText::getTextClass( 'bbcode' )->parse_smilies = $row['use_emo'];
IPSText::getTextClass( 'bbcode' )->parse_html = ( $this->forum['use_html'] and $row['post_htmlstate'] ) ? 1 : 0;
IPSText::getTextClass( 'bbcode' )->parse_nl2br = $row['post_htmlstate'] == 2 ? 1 : 0;
IPSText::getTextClass( 'bbcode' )->parse_bbcode = $this->forum['use_ibc'];
IPSText::getTextClass( 'bbcode' )->parsing_section = 'topics';
IPSText::getTextClass( 'bbcode' )->parsing_mgroup = $row['member_group_id'];
IPSText::getTextClass( 'bbcode' )->parsing_mgroup_others = $row['mgroup_others'];
$row['post'] = IPSText::getTextClass( 'bbcode' )->preDisplayParse( $row['post'] );
$posts[] = $row;
}
/* Pass back for templates */
$this->request['selectedpids'] = $this->pids;
//-----------------------------------------
// print my bottom, er, the bottom
//-----------------------------------------
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->splitPostForm( $this->forum, $this->topic, $posts, $jump_html );
$this->registry->getClass('output')->addNavigation( $this->forum['name'], "showforum={$this->forum['id']}", $this->forum['name_seo'], 'showforum' );
$this->registry->getClass('output')->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
$this->registry->getClass('output')->setTitle( $this->lang->words['st_top'].": ".$this->topic['title'] . ' - ' . ipsRegistry::$settings['board_name']);
$this->registry->output->addContent( $this->output );
$this->registry->getClass('output')->sendOutput();
}
else
{
/* INIT */
$topics = array();
$topic = array();
$forum = array();
$pids = array();
$tids = array();
/* As of 3.1, posts can come from multiple topics due to the mod options on searching */
$this->DB->build( array( 'select' => 't.*',
'from' => array( 'topics' => 't' ),
'where' => 't.tid=p.topic_id',
'add_join' => array( array( 'select' => 'p.pid',
'from' => array( 'posts' => 'p' ),
'where' => "pid IN(" . implode( ",", $this->pids ). ")" ) ) ) );
$this->DB->execute();
while( $row = $this->DB->fetch() )
{
$pids[ $row['pid'] ] = $row;
$tids[ $row['tid'] ][] = $row['pid'];
$topics[ $row['tid'] ] = $row;
}
//-----------------------------------------
// PROCESS Check the input
//-----------------------------------------
if ( $this->request['title'] == "" )
{
$this->_showError( 'mod_need_title', 10378 );
}
$affected_ids = count( $this->pids );
//-----------------------------------------
// Do we have enough?
//-----------------------------------------
if ( $affected_ids < 1 )
{
$this->_showError( 'mod_not_enough_split', 10379 );
}
//-----------------------------------------
// Do we choose too many?
//-----------------------------------------
if ( $this->topic['tid'] )
{
$count = $this->DB->buildAndFetch( array( 'select' => 'count(pid) as cnt', 'from' => 'posts', 'where' => "topic_id={$this->topic['tid']}" ) );
if ( $affected_ids >= $count['cnt'] )
{
$this->_showError( 'mod_too_much_split', 10380 );
}
}
//-----------------------------------------
// Check the forum we're moving this too
//-----------------------------------------
if ( $this->forum['id'] )
{
$this->request['fid'] = intval($this->request['fid']);
if ( $this->request['fid'] != $this->forum['id'] )
{
$f = $this->registry->class_forums->allForums[ $this->request['fid'] ];
if ( ! $f['id'] )
{
$this->_showError( 'mod_no_forum_move', 10381, 404 );
}
if ( !$f['sub_can_post'] )
{
$this->_showError( 'mod_forum_no_posts', 10382 );
}
}
}
/* Loop */
foreach( $tids as $_tid => $pids )
{
//-----------------------------------------
// Is first post queued?
//-----------------------------------------
$topic_approved = 1;
$topic = $topics[ $_tid ];
/* Reset topic */
if ( $this->fromSearch )
{
$this->request['title'] = $this->lang->words['mod_from'] . " " . $topic['title'];
}
$first_post = $this->DB->buildAndFetch( array( 'select' => 'pid, queued',
'from' => 'posts',
'where' => 'topic_id=' . $_tid . " AND pid IN(" . implode( ",", $pids ). ")",
'order' => $this->settings['post_order_column'] . ' ASC',
'limit' => array(0,1),
) );
if( $first_post['queued'] )
{
$topic_approved = 0;
$this->DB->update( 'posts', array( 'queued' => 0 ), 'pid=' . $first_post['pid'] );
}
//-----------------------------------------
// Complete a new dummy topic
//-----------------------------------------
if( $this->settings['etfilter_shout'] )
{
if( function_exists('mb_convert_case') )
{
if( in_array( strtolower( $this->settings['gb_char_set'] ), array_map( 'strtolower', mb_list_encodings() ) ) )
{
$this->request['title'] = mb_convert_case( $this->request['title'], MB_CASE_TITLE, $this->settings['gb_char_set'] );
}
else
{
$this->request['title'] = ucwords( strtolower( $this->request['title'] ) );
}
}
else
{
$this->request['title'] = ucwords( strtolower( $this->request['title'] ) );
}
}
$this->DB->insert( 'topics', array(
'title' => $this->request['title'],
'state' => 'open',
'posts' => 0,
'starter_id' => 0,
'starter_name' => 0,
'start_date' => time(),
'last_poster_id' => 0,
'last_poster_name' => 0,
'last_post' => time(),
'author_mode' => 1,
'poll_state' => 0,
'last_vote' => 0,
'views' => 0,
'forum_id' => $this->request['fid'],
'approved' => $topic_approved,
'pinned' => 0,
) );
$new_topic_id = $this->DB->getInsertId();
//-----------------------------------------
// Move the posts
//-----------------------------------------
$this->DB->update( 'posts', array( 'topic_id' => $new_topic_id, 'new_topic' => 0 ), 'topic_id=' . $_tid . " AND pid IN(" . implode( ",", $pids ). ")" );
//-----------------------------------------
// Move the posts
//-----------------------------------------
$this->DB->update( 'posts', array( 'new_topic' => 0 ), "topic_id={$_tid}" );
//-----------------------------------------
// Update attachments
//-----------------------------------------
$this->DB->update( 'attachments', array( 'attach_parent_id' => $new_topic_id ), "attach_rel_module='post' AND attach_rel_id IN(" . implode( ",", $pids ) . ")" );
$_cnt = $this->DB->getAffectedRows();
$this->DB->update( 'topics', array( 'topic_hasattach' => $_cnt ), 'tid=' . $new_topic_id );
//-----------------------------------------
// Rebuild the topics
//-----------------------------------------
$this->modLibrary->rebuildTopic( $new_topic_id );
$this->modLibrary->rebuildTopic( $_tid );
//-----------------------------------------
// Update the forum(s)
//-----------------------------------------
$this->modLibrary->forumRecount($topic['forum_id']);
if ( $topic['forum_id'] != $this->request['fid'] )
{
$this->modLibrary->forumRecount( $this->request['fid'] );
}
/* Run moderation sync */
$this->modLibrary->runModSync( 'topicSplit', $pids, $topic['tid'], $new_topic_id );
/* link http://community.invisionpower.com/tracker/issue-37361-when-splitting-topic-404/ */
$this->request['st'] = 0;
$this->_addModeratorLog( $this->lang->words['acp_split_topic'] . " '{$topic['title']}'" );
}
}
}
/**
* Post multi-mod: Merge posts
*
* @return @e void [Outputs to screen]
*/
protected function _multiMergePost()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'delete_post' );
if ( count( $this->pids ) < 2 )
{
$this->_showError( 'mod_only_one_pid', 10383 );
}
//-----------------------------------------
// Form or print?
//-----------------------------------------
if ( !$this->request['checked'] )
{
//-----------------------------------------
// Get post data
//-----------------------------------------
$master_post = "";
$dropdown = array();
$authors = array();
$seen_author = array();
$upload_html = "";
$seoTitle = '';
//-----------------------------------------
// Grab teh posts
//-----------------------------------------
$this->DB->build( array(
'select' => 'p.*',
'from' => array( 'posts' => 'p' ),
'where' => "p.pid IN (" . implode( ",", $this->pids ) . ")",
'add_join' => array(
array(
'select' => 't.forum_id, t.title_seo',
'from' => array( 'topics' => 't' ),
'where' => 't.tid=p.topic_id',
'type' => 'left',
)
)
) );
$outer = $this->DB->execute();
while ( $p = $this->DB->fetch( $outer ) )
{
if ( IPSMember::checkPermissions('read', $p['forum_id'] ) == TRUE )
{
$master_post .= $p['post'] . "
";
$dropdown[] = array( $p['pid'], ipsRegistry::getClass( 'class_localization')->getDate( $p['post_date'], 'LONG') ." (#{$p['pid']})" );
if ( !in_array( $p['author_id'], $seen_author ) )
{
$authors[] = array( $p['author_id'], "{$p['author_name']} (#{$p['pid']})" );
$seen_author[] = $p['author_id'];
}
$seoTitle = $p['title_seo'];
}
}
//-----------------------------------------
// Get Attachment Data
//-----------------------------------------
$this->DB->build( array( 'select' => '*',
'from' => 'attachments',
'where' => "attach_rel_module='post' AND attach_rel_id IN (" . implode( ",", $this->pids ) . ")" ) );
$this->DB->execute();
while( $row = $this->DB->fetch() )
{
$row['image'] = $this->caches['attachtypes'][ $row['attach_ext'] ]['atype_img'];
$row['size'] = IPSLib::sizeFormat( $row['attach_filesize'] );
$row['attach_file'] = IPSText::truncate( $row['attach_file'], 50 );
$attachments[] = $row;
}
//-----------------------------------------
// Print form
//-----------------------------------------
/* Load editor stuff */
$classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/editor/composite.php', 'classes_editor_composite' );
$_editor = new $classToLoad();
$_editor->setContent( trim($master_post) );
$editor = $_editor->show( 'Post', array( 'autoSaveKey' => md5( 'merge-' . $this->topic['tid'] ), 'height' => 350 ) );
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->mergePostForm( $editor, $dropdown, $authors, $attachments, $seoTitle );
if ( $this->topic['tid'] )
{
$this->registry->getClass('output')->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
}
$this->registry->getClass('output')->addNavigation( $this->lang->words['cm_title'], '' );
$this->registry->getClass('output')->setTitle( $this->lang->words['cm_title'] . ' - ' . ipsRegistry::$settings['board_name']);
$this->registry->output->addContent( $this->output );
$this->registry->getClass('output')->sendOutput();
}
else
{
//-----------------------------------------
// DO THE THING, WITH THE THING!!
//-----------------------------------------
$this->request['postdate'] = intval($this->request['postdate']);
if ( empty($this->request['selectedpids']) || empty($this->request['postdate']) || empty($this->request['Post']) )
{
$this->_showError( 'mod_merge_posts', 10384 );
}
/* Load editor stuff */
$classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/editor/composite.php', 'classes_editor_composite' );
$_editor = new $classToLoad();
/* remove saved content */
if ( $this->memberData['member_id'] )
{
$_editor->removeAutoSavedContent( array( 'member_id' => $this->memberData['member_id'], 'autoSaveKey' => md5( 'merge-' . $this->topic['tid'] ) ) );
}
IPSText::getTextClass('bbcode')->parse_smilies = 1;
IPSText::getTextClass('bbcode')->parse_html = 0;
IPSText::getTextClass('bbcode')->parse_bbcode = 1;
IPSText::getTextClass('bbcode')->parsing_section = 'topics';
$post = $_editor->process( $_POST['Post'] );
$post = IPSText::getTextClass('bbcode')->preDbParse( $post );
//-----------------------------------------
// Post to keep...
//-----------------------------------------
$posts = array();
$author = array();
$post_to_delete = array();
$new_post_key = md5(time());
$topics = array();
$forums = array();
$append_edit = 0;
//-----------------------------------------
// Grab teh posts
//-----------------------------------------
$this->DB->build( array(
'select' => 'p.*',
'from' => array( 'posts' => 'p' ),
'where' => "p.pid IN (" . implode( ",", $this->pids ) . ")",
'add_join' => array(
array(
'select' => 't.forum_id',
'from' => array( 'topics' => 't' ),
'where' => 't.tid=p.topic_id',
'type' => 'left',
)
)
) );
$outer = $this->DB->execute();
while ( $p = $this->DB->fetch($outer) )
{
$posts[ $p['pid'] ] = $p;
$topics[ $p['topic_id'] ] = $p['topic_id'];
$forums[ $p['forum_id'] ] = $p['forum_id'];
if ( $p['author_id'] == $this->request['postauthor'] )
{
$author = array( 'id' => $p['author_id'], 'name' => $p['author_name'] );
}
if ( $p['pid'] != $this->request['postdate'] )
{
$post_to_delete[] = $p['pid'];
}
if( $p['append_edit'] )
{
$append_edit = 1;
}
}
//-----------------------------------------
// Update main post...
//-----------------------------------------
$this->DB->update( 'posts', array( 'author_id' => $author['id'],
'author_name' => $author['name'],
'post' => $post,
'post_key' => $new_post_key,
'edit_time' => time(),
'edit_name' => $this->memberData['members_display_name'],
'append_edit' => ( $append_edit OR !$this->memberData['g_append_edit'] ) ? 1 : 0,
), 'pid=' . $this->request['postdate']
);
/* Run moderation sync */
$this->modLibrary->runModSync( 'postMerge', $this->pids, $this->request['postdate'] );
//-----------------------------------------
// Fix attachments
//-----------------------------------------
$attach_keep = array();
$attach_kill = array();
foreach ( $_POST as $key => $value )
{
if ( preg_match( '/^attach_(\d+)$/', $key, $match ) )
{
if ( $this->request[ $match[0] ] == 'keep' )
{
$attach_keep[] = $match[1];
}
else
{
$attach_kill[] = $match[1];
}
}
}
$attach_keep = IPSLib::cleanIntArray( $attach_keep );
$attach_kill = IPSLib::cleanIntArray( $attach_kill );
//-----------------------------------------
// Keep
//-----------------------------------------
if ( count( $attach_keep ) )
{
$this->DB->update( 'attachments', array( 'attach_rel_id' => $this->request['postdate'],
'attach_post_key' => $new_post_key,
'attach_member_id' => $author['id'] ), 'attach_id IN(' . implode( ",", $attach_keep ) . ')' );
}
//-----------------------------------------
// Kill Attachments
//-----------------------------------------
if( count( $attach_kill ) )
{
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( 'core' ) . '/sources/classes/attach/class_attach.php', 'class_attach' );
$class_attach = new $classToLoad( $this->registry );
$class_attach->type = 'post';
$class_attach->init();
$class_attach->bulkRemoveAttachment( $attach_kill, 'attach_id' );
}
//-----------------------------------------
// Kill old posts
//-----------------------------------------
if ( count($post_to_delete) )
{
$this->DB->delete( 'posts', 'pid IN(' . implode( ",", $post_to_delete ) . ')' );
IPSDeleteLog::removeEntries( $post_to_delete, 'post', TRUE );
}
foreach( $topics as $t )
{
$this->modLibrary->rebuildTopic( $t, 0 );
}
foreach( $forums as $f )
{
$this->modLibrary->forumRecount( $f );
}
$this->cache->rebuildCache( 'stats', 'global' );
/* Clear the content cache */
IPSContentCache::drop( 'post', $this->pids );
$this->_addModeratorLog( sprintf( $this->lang->words['acp_merged_posts'], implode( ", ", $this->pids ) ) );
}
}
/**
* If we have an option between normal / soft delete, show it.
*
* @return @e void [Outputs to screen]
*/
protected function _multiDeletePostSplash()
{
$this->registry->getClass( 'class_localization')->loadLanguageFile( array( 'public_topic' ), 'forums' );
$canSoftDelete = $this->registry->getClass('class_forums')->canSoftDeletePosts( $this->forum['id'], array() );
$canHardDelete = ( $this->memberData['g_is_supmod'] OR $this->moderator['delete_post'] OR $this->memberData['g_delete_own_posts'] ) ? true : false;
/* First hurdle */
if ( ! $canSoftDelete AND ! $canHardDelete )
{
$this->_showError();
}
/* If we can't soft delete, then just do normal deletion */
if ( ! $canSoftDelete )
{
return $this->_multiDeletePost();
}
else
{
/* Show splash page */
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->softDeleteSplashPosts( $this->forum, $this->topic, $this->pids, $canHardDelete );
$this->registry->getClass('output')->addNavigation( $this->forum['name'], "showforum={$this->forum['id']}", $this->forum['name_seo'], 'showforum' );
$this->registry->getClass('output')->setTitle( sprintf( $this->lang->words['mm_delete_top_posts'], count($this->pids) ) . ' - ' . ipsRegistry::$settings['board_name']);
$this->registry->output->addContent( $this->output );
$this->registry->getClass('output')->sendOutput();
}
}
/**
* Close a topic
*
* @return @e void [Outputs to screen]
*/
protected function _closeTopic()
{
$this->_resetModerator( $this->topic['forum_id'] );
if( !$this->_genericPermissionCheck( 'close_topic', '', true ) )
{
if ( $this->topic['starter_id'] != $this->memberData['member_id'] OR !$this->memberData['g_open_close_posts'] )
{
$this->_showError( 'mod_no_close_topic', 10385, 403 );
}
}
$this->modLibrary->topicClose($this->topic['tid']);
$this->_addModeratorLog( $this->lang->words['acp_locked_topic'] );
$this->registry->output->redirectScreen( $this->lang->words['p_closed'], $this->settings['base_url'] . "showforum=".$this->forum['id'] . ( $this->request['_from'] == 'forum' ? '&st=' . intval( $this->request['st'] ) : '' ), $this->forum['name_seo'], "showforum" );
}
/**
* Soft delete a topic
*
* @return @e void [Outputs to screen]
*/
protected function _softDeleteTopicToggle( $delete )
{
$reason = trim( $this->request['deleteReason'] );
$delete = ( $delete ) ? true : false;
$lang = ( $delete ) ? 'p_deleted' : 'p_topic_restored';
if ( $delete )
{
$result = $this->registry->getClass('class_forums')->canSoftDeleteTopics( $this->topic['forum_id'], $this->topic );
}
else
{
$result = $this->registry->getClass('class_forums')->can_Un_SoftDeleteTopics( $this->topic['forum_id'] );
}
if ( ! $result )
{
$this->_showError( 'mod_no_delete_topic', 103119.0 );
}
$this->modLibrary->topicToggleSoftDelete( array( $this->topic['tid'] ), $delete, $reason );
$this->registry->output->redirectScreen( $this->lang->words[ $lang ], $this->settings['base_url'] . "showforum=" . $this->forum['id'] . '&st=' . intval( $this->request['st'] ), $this->forum['name_seo'], 'showforum' );
}
/**
* Delete a topic
*
* @return @e void [Outputs to screen]
*/
protected function _deleteTopic()
{
$this->_resetModerator( $this->topic['forum_id'] );
if( !$this->_genericPermissionCheck( 'delete_topic', '', true ) )
{
if ( $this->topic['starter_id'] != $this->memberData['member_id'] OR !$this->memberData['g_delete_own_topics'] )
{
$this->_showError( 'mod_no_delete_topic', 10386, 403 );
}
}
// Do we have a linked topic to remove?
$this->DB->build( array( 'select' => 'tid, forum_id', 'from' => 'topics', 'where' => "state='link' AND moved_to='" . $this->topic['tid'] . '&' . $this->forum['id'] . "'" ) );
$this->DB->execute();
if ( $linked_topic = $this->DB->fetch() )
{
$this->DB->delete( 'topics', "tid=" . $linked_topic['tid'] );
$this->modLibrary->forumRecount( $linked_topic['forum_id'] );
}
$this->modLibrary->topicDelete($this->topic['tid']);
$this->_addModeratorLog( $this->lang->words['acp_deleted_a_topic'] );
$this->modLibrary->clearModQueueTable( 'topic', $this->topic['tid'] );
if( $this->request['return'] )
{
$_bits = explode( ':', $this->request['return'] );
if( count($_bits) AND $_bits[0] == 'modcp' )
{
$this->registry->output->redirectScreen( $this->lang->words['p_deleted'], $this->settings['base_url'] . "app=core&module=modcp&fromapp=forums&tab=" . $_bits[1] . 'topics' );
}
}
$this->registry->output->redirectScreen( $this->lang->words['p_deleted'], $this->settings['base_url'] . "showforum=" . $this->forum['id'] . '&st=' . intval( $this->request['st'] ), $this->forum['name_seo'], 'showforum' );
}
/**
* Perma-Delete a topic
*
* @return @e void [Outputs to screen]
*/
protected function _deleteTopicPermanent()
{
$this->_resetModerator( $this->topic['forum_id'] );
if( !$this->_genericPermissionCheck( 'delete_topic', '', true ) )
{
if ( $this->topic['starter_id'] != $this->memberData['member_id'] OR !$this->memberData['g_delete_own_topics'] )
{
$this->_showError( 'mod_no_delete_topic', 10386, 403 );
}
}
// Do we have a linked topic to remove?
$this->DB->build( array( 'select' => 'tid, forum_id', 'from' => 'topics', 'where' => "state='link' AND moved_to='" . $this->topic['tid'] . '&' . $this->forum['id'] . "'" ) );
$this->DB->execute();
if ( $linked_topic = $this->DB->fetch() )
{
$this->DB->delete( 'topics', "tid=" . $linked_topic['tid'] );
$this->modLibrary->forumRecount( $linked_topic['forum_id'] );
}
$this->modLibrary->topicDeleteFromDb($this->topic['tid']);
$this->_addModeratorLog( $this->lang->words['acp_deleted_a_topic'] );
$this->modLibrary->clearModQueueTable( 'topic', $this->topic['tid'] );
if( $this->request['return'] )
{
$_bits = explode( ':', $this->request['return'] );
if( count($_bits) AND $_bits[0] == 'modcp' )
{
$this->registry->output->redirectScreen( $this->lang->words['p_deleted'], $this->settings['base_url'] . "app=core&module=modcp&fromapp=forums&tab=" . $_bits[1] . 'topics' );
}
}
$this->registry->output->redirectScreen( $this->lang->words['p_deleted'], $this->settings['base_url'] . "showforum=" . $this->forum['id'] . '&st=' . intval( $this->request['st'] ), $this->forum['name_seo'], 'showforum' );
}
/**
* Perma-Delete an archived topic
*
* @return @e void [Outputs to screen]
*/
protected function _deleteArchivedTopic()
{
$this->_resetModerator( $this->topic['forum_id'] );
if( !$this->_genericPermissionCheck( 'delete_topic', '', true ) )
{
if ( $this->topic['starter_id'] != $this->memberData['member_id'] OR !$this->memberData['g_delete_own_topics'] )
{
$this->_showError( 'mod_no_delete_topic', 10386, 403 );
}
}
$pids = array();
/* Restore topic first */
$classToLoad = IPSLib::loadLibrary( IPS_ROOT_PATH . 'sources/classes/archive/restore.php', 'classes_archive_restore' );
$this->archiveRestore = new $classToLoad();
$this->archiveRestore->setApp('forums');
/* Get pids */
$this->DB->build( array( 'select' => 'archive_id',
'from' => 'forums_archive_posts',
'where' => 'archive_topic_id=' . intval( $this->topic['tid'] ) ) );
$this->DB->execute();
while( $row = $this->DB->fetch() )
{
$pids[] = $row['archive_id'];
}
if ( count( $pids ) )
{
/* Restore ... */
$this->archiveRestore->restore( $pids );
$this->DB->update( 'topics', array( 'topic_archive_status' => $this->registry->class_forums->fetchTopicArchiveFlag( 'exclude' ) ), 'tid=' . $this->topic['tid'] );
}
/* ... now delete */
return $this->_deleteTopicPermanent();
}
/**
* Delete a topic (confirmation screen)
*
* @return @e void [Outputs to screen]
*/
protected function _deleteForm()
{
$this->_resetModerator( $this->topic['forum_id'] );
$canSoftDelete = $this->registry->getClass('class_forums')->canSoftDeleteTopics( $this->forum['id'], $this->topic );
if ( $canSoftDelete )
{
/* Send to form, then */
$this->tids[ $this->topic['tid'] ] = $this->topic['tid'];
return $this->_multiAlterDeleteSplash();
}
else
{
if( !$this->_genericPermissionCheck( 'delete_topic', '', true ) )
{
if ( $this->topic['starter_id'] != $this->memberData['member_id'] OR !$this->memberData['g_delete_own_topics'] )
{
$this->_showError( 'mod_no_delete_topic', 10387, 403 );
}
}
$this->output = $this->registry->getClass('output')->getTemplate('mod')->deleteTopicForm( $this->forum, $this->topic );
$this->registry->getClass('output')->addNavigation( $this->forum['name'], "showforum={$this->forum['id']}", $this->forum['name_seo'], 'showforum' );
$this->registry->getClass('output')->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
$this->registry->getClass('output')->setTitle( $this->lang->words['t_delete'] . ": " . $this->topic['title'] . ' - ' . ipsRegistry::$settings['board_name']);
}
}
/**
* Display the topic history
*
* @return @e void [Outputs to screen]
*/
protected function _topicHistory()
{
if ( ! $this->memberData['g_access_cp'] )
{
$this->_showError( 'no_permission', 103119.5 );
}
//-----------------------------------------
// Admin only
//-----------------------------------------
if( !$this->memberData['g_access_cp'] )
{
$this->_showError( 'moderate_no_permission', 103119.2, 403 );
}
if ($this->topic['last_post'] == $this->topic['start_date'])
{
$avg_posts = 1;
}
else
{
$avg_posts = round( ($this->topic['posts'] + 1) / ((( $this->topic['last_post'] - $this->topic['start_date']) / 86400)), 1 );
}
if ($avg_posts < 0)
{
$avg_posts = 1;
}
if ($avg_posts > ( $this->topic['posts'] + 1) )
{
$avg_posts = $this->topic['posts'] + 1;
}
$mod_logs = array();
// Do we have any logs in the mod-logs DB about this topic? eh? well?
$this->DB->build( array(
'select' => 'l.*',
'from' => array( 'moderator_logs' => 'l' ),
'where' => 'l.topic_id=' . $this->topic['tid'],
'order' => 'l.ctime DESC',
'add_join' => array( array(
'select' => 'm.member_group_id, m.members_display_name, m.members_seo_name',
'from' => array( 'members' => 'm' ),
'where' => 'l.member_id=m.member_id',
'type' => 'left'
) ),
) );
$this->DB->execute();
while ( $row = $this->DB->fetch() )
{
/* No member name? */
$row['members_display_name'] = empty($row['members_display_name']) ? $row['member_name'] : $row['members_display_name'];
$mod_logs[] = $row;
}
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->topicHistory( $this->topic, $avg_posts, $mod_logs );
foreach( $this->registry->class_forums->forumsBreadcrumbNav( $this->topic['forum_id'] ) as $_nav )
{
$this->registry->getClass('output')->addNavigation( $_nav[0], $_nav[1], $_nav[2], $_nav[3] );
}
$this->registry->getClass('output')->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
$this->registry->getClass('output')->setTitle( $this->topic['title'] . ' - ' . ipsRegistry::$settings['board_name']);
}
/**
* Unsubscribe all form
*
* @return @e void [Outputs to screen]
*/
protected function _unsubscribeAllForm()
{
$this->_genericPermissionCheck();
//-----------------------------------------
// Get like class
//-----------------------------------------
require_once( IPS_ROOT_PATH . 'sources/classes/like/composite.php' );/*noLibHook*/
$_like = classes_like::bootstrap( 'forums', 'topics' );
$topics = $_like->getCount( $this->topic['tid'] );
if ( $topics )
{
$text = sprintf( $this->lang->words['ts_count'], $topics );
}
else
{
$text = $this->lang->words['ts_none'];
}
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->unsubscribeForm( $this->forum, $this->topic, $text );
foreach( $this->registry->class_forums->forumsBreadcrumbNav( $this->topic['forum_id'] ) as $_nav )
{
$this->registry->getClass('output')->addNavigation( $_nav[0], $_nav[1], $_nav[2], $_nav[3] );
}
$this->registry->getClass('output')->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
$this->registry->getClass('output')->setTitle( $this->lang->words['ts_title']." > ".$this->topic['title'] . ' - ' . ipsRegistry::$settings['board_name']);
}
/**
* Unsubscribe all complete
*
* @return @e void [Outputs to screen]
*/
protected function _unsubscribeAll()
{
$this->_genericPermissionCheck();
//-----------------------------------------
// Get like class
//-----------------------------------------
require_once( IPS_ROOT_PATH . 'sources/classes/like/composite.php' );/*noLibHook*/
$_like = classes_like::bootstrap( 'forums', 'topics' );
$_like->remove( $this->topic['tid'] );
$this->registry->output->redirectScreen( $this->lang->words['ts_redirect'], $this->settings['base_url'] . "showtopic=" . $this->topic['tid'] . "&st=" . intval($this->request['st']), $this->topic['title_seo'], 'showtopic' );
}
/**
* Merge two topics form
*
* @return @e void [Outputs to screen]
*/
protected function _mergeStart()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'split_merge' );
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->mergeTopicsForm( $this->forum, $this->topic );
$this->registry->getClass('output')->addNavigation( $this->forum['name'], "showforum={$this->forum['id']}", $this->forum['name_seo'], 'showforum' );
$this->registry->getClass('output')->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
$this->registry->getClass('output')->setTitle( $this->lang->words['mt_top'] . " " . $this->topic['title'] . ' - ' . ipsRegistry::$settings['board_name']);
}
/**
* Merge two topics
*
* @return @e void [Outputs to screen]
*/
protected function _mergeComplete()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'split_merge' );
//-----------------------------------------
// Check the input
//-----------------------------------------
if ( $this->request['topic_url'] == "" or $this->request['title'] == "" )
{
$this->_showError( 'mod_missing_url_title', 10388 );
}
//-----------------------------------------
// Get the topic ID of the entered URL
//-----------------------------------------
$old_id = $this->_getTidFromUrl();
if ( !$old_id )
{
$this->_showError( 'mod_missing_old_topic', 10389 );
}
//-----------------------------------------
// Get the topic from the DB
//-----------------------------------------
$old_topic = $this->DB->buildAndFetch( array( 'select' => 'tid, title, forum_id, last_post, last_poster_id, last_poster_name, posts, views, topic_hasattach, approved', 'from' => 'topics', 'where' => 'tid=' . intval($old_id) ) );
if ( ! $old_topic['tid'] )
{
$this->_showError( 'mod_missing_old_topic', 10390 );
}
//-----------------------------------------
// Did we try and merge the same topic?
//-----------------------------------------
if ( $old_id == $this->topic['tid'] )
{
$this->_showError( 'mod_same_topics', 10391 );
}
//-----------------------------------------
// Do we have moderator permissions for this
// topic (ie: in the forum the topic is in)
//-----------------------------------------
$pass = FALSE;
if ( $this->topic['forum_id'] == $old_topic['forum_id'] )
{
$pass = TRUE;
}
else
{
if ( $this->memberData['g_is_supmod'] == 1 )
{
$pass = TRUE;
}
else if( $this->memberData['member_id'] )
{
$other_mgroups = array();
$_mgroup_others = IPSText::cleanPermString( $this->memberData['mgroup_others'] );
if( $_mgroup_others )
{
$other_mgroups = explode( ",", $_mgroup_others );
}
$other_mgroups[] = $this->memberData['member_group_id'];
$this->DB->build( array( 'select' => 'mid',
'from' => 'moderators',
'where' => "forum_id LIKE '%,{$old_topic['forum_id']},%' AND (member_id='" . $this->memberData['member_id'] . "' OR (is_group=1 AND group_id IN(" . implode( ",", $other_mgroups ) . ")))" ) );
$this->DB->execute();
if ( $this->DB->getTotalRows() )
{
$pass = TRUE;
}
}
}
if ( $pass == FALSE )
{
// No, we don't have permission
$this->_showError();
}
//-----------------------------------------
// Sort out polls
//-----------------------------------------
/* Who has a poll? */
$main_topic_poll = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'polls', 'where' => "tid={$this->topic['tid']}" ) );
$old_topic_poll = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'polls', 'where' => "tid={$old_topic['tid']}" ) );
/* The old topic has a poll and the new one doesn't */
if ( $old_topic_poll['pid'] and !$main_topic_poll['pid'] )
{
// Make that poll the poll for the master topic
$this->DB->update( 'polls', array( 'tid' => $this->topic['tid'] ), "tid={$old_topic_poll['tid']}" );
// Make the votes for that now
$this->DB->update( 'voters', array( 'tid' => $this->topic['tid'] ), "tid={$old_topic_poll['tid']}" );
// Let the master topic know that it has a poll now
$this->DB->update( 'topics', array( 'poll_state' => 1 ), "tid={$this->topic['tid']}" );
}
/* They both have polls */
elseif ( $old_topic_poll['pid'] and $main_topic_poll['pid'] )
{
// Have we selected one?
if ( $this->request['chosenpolltid'] )
{
$chosenTid = intval( $this->request['chosenpolltid'] );
// Remove the non chosen ones
$this->DB->delete( 'polls', "tid={$this->topic['tid']}" );
$this->DB->delete( 'polls', "tid={$old_topic_poll} AND tid <> {$chosenTid}" );
$this->DB->delete( 'voters', "tid={$this->topic['tid']}" );
$this->DB->delete( 'voters', "tid={$old_topic_poll} AND tid <> {$chosenTid}" );
// Make the chosen poll the poll for the master topic
$this->DB->update( 'polls', array( 'tid' => $this->topic['tid'] ), "tid={$chosenTid}" );
// Make the votes for that now
$this->DB->update( 'voters', array( 'tid' => $this->topic['tid'] ), "tid={$chosenTid}" );
// Let the master topic know that it has a poll now
$this->DB->update( 'topics', array( 'poll_state' => 1 ), "tid={$this->topic['tid']}" );
}
// No? Well ask them which one to keep
else
{
ipsRegistry::getClass('class_localization')->loadLanguageFile( array( 'public_topic' ) );
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->mergeMultiplePolls( array( $main_topic_poll, $old_topic_poll ), ",{$main_topic_poll['tid']},{$old_topic_poll['tid']}" );
$this->registry->getClass('output')->addNavigation( $this->forum['name'], "showforum={$this->forum['id']}", $this->forum['name_seo'], 'showforum' );
$this->registry->getClass('output')->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
$this->registry->getClass('output')->setTitle( $this->lang->words['mt_top']." ".$this->topic['title'] . ' - ' . ipsRegistry::$settings['board_name']);
return false;
}
}
//-----------------------------------------
// Update the posts, remove old polls, subs and topic
//-----------------------------------------
/* Remove from deletion log */
IPSDeleteLog::removeEntries( array( $old_topic['tid'] ), 'topic', TRUE );
$this->DB->update( 'posts', array( 'topic_id' => $this->topic['tid'] ), 'topic_id=' . $old_topic['tid'] );
$this->DB->delete( 'voters', "tid=" . $old_topic['tid'] );
$this->DB->delete( 'topics', "tid=" . $old_topic['tid'] );
//-----------------------------------------
// Update attachments
//-----------------------------------------
$this->DB->update( 'attachments', array( 'attach_parent_id' => $this->topic['tid'] ), "attach_rel_module='post' AND attach_parent_id=" . $old_topic['tid'] );
//-----------------------------------------
// Get like class
//-----------------------------------------
require_once( IPS_ROOT_PATH . 'sources/classes/like/composite.php' );/*noLibHook*/
$_like = classes_like::bootstrap( 'forums', 'topics' );
$_like->remove( $old_topic['tid'] );
//-----------------------------------------
// Tags
//-----------------------------------------
$this->registry->tags->moveTagsByMetaId( $old_topic['tid'], $this->topic['tid'] );
// Resync to remove duplicate tags - see bug report 34475
$tags = $this->registry->tags->getTagsByMetaId( $this->topic['tid'] );
$this->registry->tags->replace( $tags['tags'], array( 'meta_id' => $this->topic['tid'] ) );
//-----------------------------------------
// Update the newly merged topic
//-----------------------------------------
$updater = array( 'title' => $this->request['title'],
'views' => $old_topic['views'] + $this->topic['views']
);
if ( $old_topic['last_post'] > $this->topic['last_post'] )
{
$updater['last_post'] = $old_topic['last_post'];
$updater['last_poster_name'] = $old_topic['last_poster_name'];
$updater['seo_last_name'] = IPSText::makeSeoTitle( $old_topic['last_poster_name'] );
$updater['last_poster_id'] = $old_topic['last_poster_id'];
}
if( $old_topic['topic_hasattach'] )
{
$updater['topic_hasattach'] = intval($this->topic['topic_hasattach']) + $old_topic['topic_hasattach'];
}
$this->DB->update( 'topics', $updater, 'tid=' . $this->topic['tid'] );
//-----------------------------------------
// Fix up the "new_topic" attribute.
//-----------------------------------------
$this->DB->build( array( 'select' => 'pid, author_name, author_id, post_date',
'from' => 'posts',
'where' => "topic_id=" . $this->topic['tid'],
'order' => 'post_date ASC',
'limit' => array( 0,1 ) ) );
$this->DB->execute();
if ( $first_post = $this->DB->fetch() )
{
$this->DB->update( 'posts', array( 'new_topic' => 0 ), "topic_id={$this->topic['tid']}" );
$this->DB->update( 'posts', array( 'new_topic' => 1 ), "pid={$first_post['pid']}" );
}
//-----------------------------------------
// Reset the post count for this topic
//-----------------------------------------
$amode = $first_post['author_id'] ? 1 : 0;
$_queued = $this->registry->class_forums->fetchPostHiddenQuery( array( 'visible' ), '' );
$this->DB->build( array( 'select' => 'COUNT(*) as posts',
'from' => 'posts',
'where' => $_queued . " AND topic_id=" . $this->topic['tid'] ) );
$this->DB->execute();
if ( $post_count = $this->DB->fetch() )
{
$post_count['posts']--; //Remove first post
$this->DB->update( 'topics', array( 'posts' => $post_count['posts'],
'starter_name' => $first_post['author_name'],
'starter_id' => $first_post['author_id'],
'start_date' => $first_post['post_date'],
'author_mode' => $amode,
'topic_firstpost' => $first_post['pid']
) , 'tid=' . $this->topic['tid'] );
}
$this->modLibrary->rebuildTopic( $this->topic['tid'] );
//-----------------------------------------
// Update the forum(s)
//-----------------------------------------
$this->registry->class_forums->allForums[ $this->topic['forum_id'] ]['_update_deletion'] = 1;
$this->modLibrary->forumRecount( $this->topic['forum_id'] );
if ( $this->topic['forum_id'] != $old_topic['forum_id'] )
{
$this->registry->class_forums->allForums[ $old_topic['forum_id'] ]['_update_deletion'] = 1;
$this->modLibrary->forumRecount( $old_topic['forum_id'] );
}
/* Run moderation sync */
$this->modLibrary->runModSync( 'topicMerge', $old_topic['tid'], $this->topic['tid'] );
$this->_addModeratorLog( sprintf( $this->lang->words['acp_merged_topic'], $old_topic['title'], $this->topic['title'] ) );
$this->registry->output->redirectScreen( $this->lang->words['mt_redirect'], $this->settings['base_url'] . "showtopic=" . $this->topic['tid'], $this->topic['title_seo'], 'showtopic' );
}
/**
* Merge two topics
*
* @return @e void [Outputs to screen]
*/
protected function _moveForm()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'move_topic' );
$jump_html = $this->registry->getClass('class_forums')->buildForumJump(0,1,1);
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->moveTopicForm( $this->forum, $this->topic, $jump_html );
foreach( $this->registry->class_forums->forumsBreadcrumbNav( $this->forum['id'] ) as $_nav )
{
$this->registry->output->addNavigation( $_nav[0], $_nav[1], $_nav[2], $_nav[3] );
}
$this->registry->output->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
$this->registry->getClass('output')->setTitle( $this->lang->words['t_move'].": ".$this->topic['title'] . ' - ' . ipsRegistry::$settings['board_name']);
}
/**
* Merge two topics
*
* @return @e void [Outputs to screen]
*/
protected function _doMove()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'move_topic' );
//-----------------------------------------
// Check for input..
//-----------------------------------------
if ( !$this->request['move_id'] or $this->request['move_id'] == -1 )
{
$this->_showError( 'mod_no_move_forum', 10392 );
}
if ( $this->request['move_id'] == $this->request['f'] )
{
$this->_showError( 'mod_no_move_save', 10393 );
}
$source = intval($this->request['f']);
$moveto = intval($this->request['move_id']);
//-----------------------------------------
$this->DB->build( array( 'select' => 'id, sub_can_post, name, redirect_on', 'from' => 'forums', 'where' => "id IN(" . $source . ',' . $moveto . ")" ) );
$this->DB->execute();
if ($this->DB->getTotalRows() != 2)
{
$this->_showError( 'mod_no_move_forum', 10394 );
}
$source_name = "";
$dest_name = "";
//-----------------------------------------
// Check for an attempt to move into a subwrap forum
//-----------------------------------------
while ( $f = $this->DB->fetch() )
{
if ( $f['id'] == $source )
{
$source_name = $f['name'];
}
else
{
$dest_name = $f['name'];
}
if ( ( $f['sub_can_post'] != 1 ) OR $f['redirect_on'] == 1 )
{
$this->_showError( 'mod_forum_no_posts', 10395 );
}
}
$this->modLibrary->topicMove( $this->topic['tid'], $source, $moveto, $this->request['leave'] == 'y' ? 1 : 0 );
$this->_addModeratorLog( sprintf( $this->lang->words['acp_moved_a_topic'], $source_name, $dest_name ) );
// Resync the forums..
$this->registry->class_forums->allForums[ $source ]['_update_deletion'] = 1;
$this->registry->class_forums->allForums[ $moveto ]['_update_deletion'] = 1;
$this->modLibrary->forumRecount($source);
$this->modLibrary->forumRecount($moveto);
$this->registry->output->redirectScreen( $this->lang->words['p_moved'], $this->settings['base_url'] . "showforum=" . $this->forum['id'], $this->forum['name_seo'], 'showforum' );
}
/**
* Delete a single post
*
* @return @e void [Outputs to screen]
*/
protected function _deletePost()
{
// Get this post id.
$this->request['p'] = intval( $this->request['p'] );
$post = $this->DB->buildAndFetch( array( 'select' => 'pid, author_id, post_date, new_topic', 'from' => 'posts', 'where' => "topic_id={$this->topic['tid']} and pid=" . $this->request['p'] ) );
if ( !$post['pid'] )
{
$this->_showError( 'mod_no_delete_post_find', 10396 );
}
$this->_resetModerator( $this->topic['forum_id'] );
if( !$this->_genericPermissionCheck( 'delete_post', '', true ) )
{
if( !$this->memberData['g_delete_own_posts'] OR $this->memberData['member_id'] != $post['author_id'] )
{
$this->_showError( 'mod_no_delete_post', 10397, 403 );
}
}
//-----------------------------------------
// Check to make sure that this isn't the first post in the topic..
//-----------------------------------------
if ( $post['new_topic'] == 1 )
{
$this->_showError( 'mod_delete_first_post', 10398 );
}
$this->modLibrary->postDelete( $this->request['p'] );
$this->modLibrary->forumRecount( $this->forum['id'] );
$this->modLibrary->clearModQueueTable( 'post', $post['pid'] );
if( $this->request['return'] )
{
$_bits = explode( ':', $this->request['return'] );
if( count($_bits) AND $_bits[0] == 'modcp' )
{
$this->registry->output->redirectScreen( $this->lang->words['post_deleted'], $this->settings['base_url'] . "app=core&module=modcp&fromapp=forums&tab=" . $_bits[1] . 'posts' );
}
}
$this->registry->output->redirectScreen( $this->lang->words['post_deleted'], $this->settings['base_url'] . "showtopic=" . $this->topic['tid'] . "&st=" . intval($this->request['st']), $this->topic['title_seo'], 'showtopic' );
}
/**
* Show the edit topic title form
*
* @return @e void [Outputs to screen]
*/
protected function _editForm()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'edit_topic' );
$this->output .= $this->registry->getClass('output')->getTemplate('mod')->editTopicTitle( $this->forum, $this->topic );
$navigation = $this->registry->getClass('class_forums')->forumsBreadcrumbNav( $this->forum['id'] );
if( is_array( $navigation ) AND count( $navigation ) )
{
foreach( $navigation as $_id => $_nav )
{
$this->registry->getClass('output')->addNavigation( $_nav[0], $_nav[1], $_nav[2], $_nav[3] );
}
}
$this->registry->getClass('output')->addNavigation( $this->topic['title'], "showtopic={$this->topic['tid']}", $this->topic['title_seo'], 'showtopic' );
$this->registry->getClass('output')->setTitle( $this->lang->words['t_edit'].": ".$this->topic['title'] . ' - ' . ipsRegistry::$settings['board_name']);
}
/**
* Save the topic title edits
*
* @return @e void [Outputs to screen]
*/
protected function _doEdit()
{
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'edit_topic' );
if ( trim($this->request['TopicTitle']) == "" )
{
$this->_showError( 'mod_no_topic_title', 10399 );
}
require_once( IPSLib::getAppDir( 'forums' ) . '/sources/classes/post/classPost.php' );/*noLibHook*/
$classToLoad = IPSLib::loadLibrary( IPSLib::getAppDir( 'forums' ) . '/sources/classes/post/classPostForms.php', 'classPostForms', 'forums' );
$_postClass = new $classToLoad( $this->registry );
$this->request['TopicTitle'] = $_postClass->cleanTopicTitle( $this->request['TopicTitle'] );
$this->request['TopicTitle'] = trim( IPSText::getTextClass( 'bbcode' )->stripBadWords( $this->request['TopicTitle'] ) );
if( $this->settings['etfilter_shout'] )
{
if( function_exists('mb_convert_case') )
{
if( in_array( strtolower( $this->settings['gb_char_set'] ), array_map( 'strtolower', mb_list_encodings() ) ) )
{
$this->request['TopicTitle'] = mb_convert_case( $this->request['TopicTitle'], MB_CASE_TITLE, $this->settings['gb_char_set'] );
}
else
{
$this->request['TopicTitle'] = ucwords( strtolower( $this->request['TopicTitle'] ) );
}
}
else
{
$this->request['TopicTitle'] = ucwords( strtolower( $this->request['TopicTitle'] ) );
}
}
$this->request['TopicDesc'] = trim( IPSText::getTextClass( 'bbcode' )->stripBadWords( $this->request['TopicDesc'] ) );
$this->request['TopicDesc'] = IPSText::mbsubstr( $this->request['TopicDesc'], 0, 70 );
$title_seo = IPSText::makeSeoTitle( $this->request['TopicTitle'] );
$this->DB->update( 'topics', array( 'title' => $this->request['TopicTitle'], 'title_seo' => $title_seo ), 'tid=' . $this->topic['tid'] );
$this->modLibrary->forumRecount( $this->forum['id'] );
$this->_addModeratorLog( sprintf( $this->lang->words['acp_edit_title'], $this->topic['tid'], $this->topic['title'], $this->request['TopicTitle'] ) );
$this->registry->output->redirectScreen( $this->lang->words['p_edited'], $this->settings['base_url'] . "showtopic=" . $this->topic['tid'], $title_seo, 'showtopic' );
}
/**
* Open a closed topic
*
* @return @e void [Outputs to screen]
*/
protected function _openTopic()
{
if ( $this->topic['state'] == 'open' )
{
$this->_showError( 'mod_no_open_opened', 103100 );
}
$this->_resetModerator( $this->topic['forum_id'] );
if( !$this->_genericPermissionCheck( 'open_topic', '', true ) )
{
if( !$this->memberData['g_open_close_posts'] OR $this->topic['starter_id'] != $this->memberData['member_id'] )
{
$this->_showError( 'mod_no_open_perms', 103101, 403 );
}
}
$this->modLibrary->topicOpen($this->topic['tid']);
$this->_addModeratorLog( $this->lang->words['acp_opened_topic'] );
$_st = '&st=' . intval( $this->request['st'] );
if( $this->request['_fromTopic'] )
{
$_st = '';
}
$this->registry->output->redirectScreen( $this->lang->words['p_opened'], $this->settings['base_url'] . "showforum=" . $this->topic['forum_id'] . $_st, $this->forum['name_seo'], "showforum" );
}
/**
* Move topics to another forum from the prune popup tool
*
* @return @e void [Outputs to screen]
*/
protected function _pruneMove()
{
//-----------------------------------------
// Check
//-----------------------------------------
$this->_resetModerator( $this->forum['forum_id'] );
$this->_genericPermissionCheck( 'mass_move' );
///-----------------------------------------
// SET UP
//-----------------------------------------
define( 'IPS_FORCE_HTML_REDIRECT', true );
$pergo = intval( $this->request['pergo'] ) ? intval( $this->request['pergo'] ) : 50;
$max = intval( $this->request['max'] );
$current = intval($this->request['current']);
$maxdone = $pergo + $current;
$tid_array = array();
$starter = trim( $this->request['starter'] );
$state = trim( $this->request['state'] );
$posts = intval( $this->request['posts'] );
$dateline = intval( $this->request['dateline'] );
$source = $this->forum['id'];
$moveto = intval($this->request['df']);
$date = 0;
$ignore_pin = intval( $this->request['ignore_pin'] );
if( $dateline )
{
$date = time() - $dateline*60*60*24;
}
//-----------------------------------------
// Carry on...
//-----------------------------------------
$dbPruneWhere = $this->modLibrary->sqlPruneCreate( $this->forum['id'], $starter, $state, $posts, $date, $ignore_pin );
$this->DB->build( array(
'select' => 'tid',
'from' => 'topics',
'where' => $dbPruneWhere,
'limit' => array( 0, $pergo ),
) );
$batch = $this->DB->execute();
//-----------------------------------------
// Get tids
//-----------------------------------------
while ( $row = $this->DB->fetch($batch) )
{
$tid_array[] = $row['tid'];
}
//-----------------------------------------
// Done?
//-----------------------------------------
if ( empty( $tid_array ) )
{
$this->_addModeratorLog( $this->lang->words['acp_mass_moved'] );
//-----------------------------------------
// Update forum deletion
//-----------------------------------------
$this->registry->class_forums->allForums[ $moveto ]['_update_deletion'] = 1;
$this->registry->class_forums->allForums[ $source ]['_update_deletion'] = 1;
//-----------------------------------------
// Resync the forums..
//-----------------------------------------
$this->modLibrary->forumRecount($source);
$this->modLibrary->forumRecount($moveto);
//-----------------------------------------
// Done...
//-----------------------------------------
$this->request[ 'check'] = 0 ;
$this->_pruneStart( $this->registry->getClass('output')->getTemplate('mod')->simplePage( $this->lang->words['cp_results'], $this->lang->words['cp_result_move'] . ($max) ) );
return;
}
//-----------------------------------------
// Check for an attempt to move into a subwrap forum
//-----------------------------------------
$f = $this->registry->class_forums->allForums[ $moveto ];
if ( $f['sub_can_post'] != 1 )
{
$this->_showError( 'mod_forum_no_posts', 103102 );
}
$this->modLibrary->topicMove( $tid_array, $source, $moveto );
//-----------------------------------------
// Refresh..
//-----------------------------------------
$num_rows = count($tid_array);
$link = "app=forums&module=moderate§ion=moderate&f={$this->forum['id']}&do=prune_move&df=" . $this->request['df'] . "&pergo={$pergo}¤t={$maxdone}&max={$max}";
$link .= "&starter={$starter}&state={$state}&posts={$posts}&dateline={$dateline}&ignore_pin={$ignore_pin}";
$link .= "&auth_key=".$this->member->form_hash;
$done = $current + $num_rows;
$text = sprintf( $this->lang->words['cp_batch_done'], $done, $max - $done );
$this->registry->output->redirectScreen( $text, $this->settings['base_url'] . $link );
}
/**
* Prune delete topics
*
* @return @e void [Outputs to screen]
*/
protected function _pruneFinish()
{
//-----------------------------------------
// INIT
//-----------------------------------------
$this->_resetModerator( $this->topic['forum_id'] );
$this->_genericPermissionCheck( 'mass_prune' );
//-----------------------------------------
// SET UP
//-----------------------------------------
define( 'IPS_FORCE_HTML_REDIRECT', true );
$pergo = intval( $this->request['pergo'] ) ? intval( $this->request['pergo'] ) : 50;
$max = intval( $this->request['max'] );
$current = intval($this->request['current']);
$maxdone = $pergo + $current;
$tid_array = array();
$starter = trim( $this->request['starter'] );
$state = trim( $this->request['state'] );
$posts = intval( $this->request['posts'] );
$dateline = intval( $this->request['dateline'] );
$date = 0;
$ignore_pin = intval( $this->request['ignore_pin'] );
if( $dateline )
{
$date = time() - $dateline*60*60*24;
}
//-----------------------------------------
// Carry on...
//-----------------------------------------
$dbPruneWhere = $this->modLibrary->sqlPruneCreate( $this->forum['id'], $starter, $state, $posts, $date, $ignore_pin );
$this->DB->build( array(
'select' => 'tid',
'from' => 'topics',
'where' => $dbPruneWhere,
'limit' => array( 0, $pergo ),
) );
$batch = $this->DB->execute();
//-----------------------------------------
// Got anything?
//-----------------------------------------
$num_rows = $this->DB->getTotalRows($batch);
if ( ! $num_rows )
{
if ( !$current )
{
$this->_showError( 'mod_no_prune_topics', 103103 );
}
}
//-----------------------------------------
// Get tiddles
//-----------------------------------------
while ( $tid = $this->DB->fetch($batch) )
{
$tid_array[] = $tid['tid'];
}
$this->modLibrary->topicDelete($tid_array);
//-----------------------------------------
// Show results or refresh..
//-----------------------------------------
if ( ! $num_rows )
{
//-----------------------------------------
// Done...
//-----------------------------------------
$this->_addModeratorLog( $this->lang->words['acp_pruned_forum'] );
$this->request[ 'check'] = 0 ;
$this->_pruneStart( $this->registry->getClass('output')->getTemplate('mod')->simplePage( $this->lang->words['cp_results'], $this->lang->words['cp_result_del'] . ($max) ) );
}
else
{
$link = "app=forums&module=moderate§ion=moderate&f={$this->forum['id']}&do=prune_finish&pergo={$pergo}¤t={$maxdone}&max={$max}";
$link .= "&starter={$starter}&state={$state}&posts={$posts}&dateline={$dateline}&ignore_pin={$ignore_pin}";
$link .= "&auth_key=".$this->member->form_hash;
$done = $current + $num_rows;
$text = sprintf( $this->lang->words['cp_batch_done'], $done, $max - $done );
$this->registry->output->redirectScreen( $text, $this->settings['base_url'] . $link );
}
}
/**
* Prune popup form
*
* @param string HTML output
* @return @e void [Outputs to screen]
*/
protected function _pruneStart( $complete_html="" )
{
//-----------------------------------------
// Check permissions
//-----------------------------------------
$this->_resetModerator( $this->forum['id'] );
$this->_genericPermissionCheck( 'mass_prune' );
$confirm_data = array( 'show' => '' );
//-----------------------------------------
// Check per go
//-----------------------------------------
$this->request[ 'pergo' ] = $this->request['pergo'] ? intval( $this->request['pergo'] ) : 50;
$this->request[ 'posts' ] = $this->request['posts'] ? intval( $this->request['posts'] ) : '';
$this->request[ 'member' ] = $this->request['member'] ? $this->request['member'] : '' ;
$this->request[ 'determine' ] = $this->request['determine'] ? $this->request['determine'] : '' ;
$this->request[ 'dateline' ] = $this->request['dateline'] ? $this->request['dateline'] : '' ;
//-----------------------------------------
// Are we checking first?
//-----------------------------------------
if ( $this->request['check'] AND $this->request['check'] == 1 )
{
$link = "&pergo=" . $this->request['pergo'];
$link_text = $this->lang->words['cp_prune_dorem'];
$tcount = $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as tcount', 'from' => 'topics', 'where' => "forum_id={$this->forum['id']} AND approved < 2" ) );
$db_query = "";
//-----------------------------------------
// date...
//-----------------------------------------
if ($this->request['dateline'])
{
$date = time() - $this->request['dateline']*60*60*24;
$db_query .= " AND last_post < $date";
$link .= "&dateline={$this->request['dateline']}";
}
//-----------------------------------------
// Member...
//-----------------------------------------
if ( $this->request['member'] )
{
$mem = $this->DB->buildAndFetch( array( 'select' => 'member_id', 'from' => 'members', 'where' => "members_display_name='" . $this->request['member'] . "'" ) );
if ( !$mem['member_id'] )
{
$this->_showError( 'mod_no_prune_member', 103104 );
}
else
{
$db_query .= " AND starter_id=" . $mem['member_id'];
$link .= "&starter={$mem['member_id']}";
}
}
//-----------------------------------------
// Posts / Topic type
//-----------------------------------------
if ($this->request['posts'])
{
$db_query .= " AND posts < " . intval($this->request['posts']);
$link .= "&posts=" . $this->request['posts'];
}
if ($this->request['topic_type'] != 'all')
{
$db_query .= " AND state='".$this->request['topic_type']."'";
$link .= "&state=" . $this->request['topic_type'];
}
if ($this->request['ignore_pin'] == 1)
{
$db_query .= " AND pinned <> 1";
$link .= "&ignore_pin=1";
}
$count = $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as count',
'from' => 'topics',
'where' => "forum_id=" . $this->forum['id'] . ' AND approved < 2' . $db_query ) );
//-----------------------------------------
// Prune?
//-----------------------------------------
if ( $this->request['df'] == 'prune' )
{
$link = "app=forums&module=moderate§ion=moderate&f={$this->forum['id']}&do=prune_finish&" . $link;
}
else
{
if ( $this->request['df'] == $this->forum['id'] )
{
$this->_showError( 'mod_no_move_save', 103105 );
}
else if ( $this->request['df'] == -1 )
{
$this->_showError( 'mod_no_move_forum', 103106 );
}
$link = "app=forums&module=moderate§ion=moderate&f={$this->forum['id']}&do=prune_move&df=" . $this->request['df'] . $link;
$link_text = $this->lang->words['cp_prune_domove'];
}
//-----------------------------------------
// Build data
//-----------------------------------------
$confirm_data = array( 'tcount' => $tcount['tcount'],
'count' => $count['count'],
'link' => $link . '&max=' . $count['count'],
'link_text' => $link_text,
'show' => 1 );
}
$html_forums .= $this->registry->getClass('class_forums')->buildForumJump(0,1,1);
//-----------------------------------------
// Make current destination forum this one if selected
// before
//-----------------------------------------
if ( $this->request['df'] )
{
$html_forums = str_replace( '