* 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&section=moderate&f={$this->forum['id']}&do=prune_move&df=" . $this->request['df'] . "&pergo={$pergo}&current={$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&section=moderate&f={$this->forum['id']}&do=prune_finish&pergo={$pergo}&current={$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&section=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&section=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( '