Files
IPB/upload/admin/applications/forums/modules_admin/tools/tools.php
T
2025-12-19 00:31:03 -08:00

716 lines
22 KiB
PHP

<?php
/**
* Invision Power Services
* IP.Board v3.0.5
* Member management
* Last Updated: $Date: 2009-10-16 10:46:16 -0400 (Fri, 16 Oct 2009) $
*
* @author $Author: josh $
* @copyright (c) 2001 - 2009 Invision Power Services, Inc.
* @license http://www.iinvisionpower.com/community/board/license.html
* @package Invision Power Board
* @subpackage Forums
* @link http://www.iinvisionpower.com
* @since 1st march 2002
* @version $Revision: 5234 $
*
*/
if ( ! defined( 'IN_ACP' ) )
{
print "<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded 'admin.php'.";
exit();
}
class admin_forums_tools_tools extends ipsCommand
{
/**
* Skin object
*
* @access private
* @var object Skin templates
*/
private $html;
/**
* Shortcut for url
*
* @access private
* @var string URL shortcut
*/
private $form_code;
/**
* Shortcut for url (javascript)
*
* @access private
* @var string JS URL shortcut
*/
private $form_code_js;
/**
* Editor object
*
* @access private
* @var object Editor library
*/
private $han_editor;
/**
* Trash can forum id
*
* @access private
* @var integer Trash can forum
*/
private $trash_forum = 0;
/**
* Main class entry point
*
* @access public
* @param object ipsRegistry reference
* @return void [Outputs to screen]
*/
public function doExecute( ipsRegistry $registry )
{
//-----------------------------------------
// Load skin
//-----------------------------------------
$this->html = $this->registry->output->loadTemplate('cp_skin_member_form');
//-----------------------------------------
// Set up stuff
//-----------------------------------------
$this->form_code = $this->html->form_code = 'module=tools&amp;section=tools';
$this->form_code_js = $this->html->form_code_js = 'module=tools&section=tools';
//-----------------------------------------
// Load lang
//-----------------------------------------
ipsRegistry::getClass('class_localization')->loadLanguageFile( array( 'admin_forums' ), 'forums' );
///-----------------------------------------
// What to do...
//-----------------------------------------
switch( $this->request['do'] )
{
default:
case 'deleteposts':
$this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'ftools_deleteposts' );
$this->_deletePostsStart();
break;
case 'deletesubscriptions':
$this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'ftools_deletesubscriptions' );
$this->_deleteSubscriptions();
break;
case 'clearforumsubs':
$this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'ftools_clearforumsubs' );
$this->_deleteForumSubscriptions();
break;
case 'deleteposts_process':
$this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'ftools_deleteposts' );
$this->_deletePostsDo();
break;
case 'new_avatar':
$this->registry->getClass('class_permissions')->checkPermissionAutoMsg( 'member_photo', 'members', 'members' );
$this->_processAvatar();
break;
}
//-----------------------------------------
// Pass to CP output hander
//-----------------------------------------
$this->registry->getClass('output')->html_main .= $this->registry->getClass('output')->global_template->global_frame_wrapper();
$this->registry->getClass('output')->sendOutput();
}
/**
* Delete a forum's email subscriptions
*
* @access private
* @return void
* @author Brandon Farber
* @since IPB3 / 22 Oct 2008
*/
private function _deleteForumSubscriptions()
{
/**
* Get members watching forums so we can recache em..
*/
$forum_id = intval( $this->request['f'] );
$members = array();
$this->DB->build( array( 'select' => 'member_id', 'from' => 'forum_tracker', 'where' => 'forum_id=' . $forum_id ) );
$this->DB->execute();
while( $r = $this->DB->fetch() )
{
$members[] = $r['member_id'];
}
$this->DB->delete( 'forum_tracker', 'forum_id=' . $forum_id );
foreach( $members as $mid )
{
$this->registry->getClass('class_forums')->recacheWatchedForums( $mid );
}
/**
* Topics is teh suck...gotta get em first to delete em
*/
$toDelete = array();
$this->DB->build( array( 'select' => 'tr.trid',
'from' => array( 'tracker' => 'tr' ),
'where' => 't.forum_id=' . $forum_id,
'add_join' => array(
array(
'from' => array( 'topics' => 't' ),
'where' => 't.tid=tr.topic_id',
'type' => 'left'
)
)
) );
$this->DB->execute();
while( $r = $this->DB->fetch() )
{
$toDelete[] = $r['trid'];
}
if( count($toDelete) )
{
$this->DB->delete( 'tracker', 'trid IN(' . implode( ',', $toDelete ) . ')' );
}
$this->registry->output->redirect( $this->settings['_base_url'] . "app=forums", $this->lang->words['m_subsf_redirect'] );
}
/**
* Delete a member's email subscriptions
*
* @access private
* @return void
* @author Brandon Farber
* @since IPB3 / 22 Oct 2008
*/
private function _deleteSubscriptions()
{
$member_id = intval( $this->request['member_id'] );
$this->DB->delete( 'tracker', 'member_id=' . $member_id );
$this->DB->delete( 'forum_tracker', 'member_id=' . $member_id );
$this->registry->output->redirect( $this->settings['_base_url'] . "app=members&amp;module=members&amp;section=members&amp;do=viewmember&amp;member_id={$this->request['member_id']}", $this->lang->words['m_subs_redirect'] );
}
/**
* Update a member's avatar
*
* @access private
* @return void [Outputs to screen]
* @author Brandon Farber
* @since IPB3 / 9 June 2008
*/
private function _processAvatar()
{
$member_id = intval( $this->request['member_id'] );
try
{
IPSMember::getFunction()->saveNewAvatar( $member_id );
}
catch( Exception $error )
{
switch ( $error->getMessage() )
{
case 'NO_MEMBER_ID':
$this->registry->output->showError( $this->lang->words['t_noid'], 11356 );
break;
case 'NO_PERMISSION':
$this->registry->output->showError( $this->lang->words['t_permav'], 11357, true );
break;
case 'UPLOAD_NO_IMAGE':
$this->registry->output->showError( $this->lang->words['t_uploadfail1'], 11358 );
break;
case 'UPLOAD_INVALID_FILE_EXT':
$this->registry->output->showError( $this->lang->words['t_uploadfail2'], 11359 );
break;
case 'UPLOAD_TOO_LARGE':
$this->registry->output->showError( $this->lang->words['t_uploadfail3'], 11360 );
break;
case 'UPLOAD_CANT_BE_MOVED':
$this->registry->output->showError( $this->lang->words['t_uploadfail4'], 11361 );
break;
case 'UPLOAD_NOT_IMAGE':
$this->registry->output->showError( $this->lang->words['t_uploadfail5'], 2131, true );
break;
case 'NO_AVATAR_TO_SAVE':
$this->registry->output->showError( $this->lang->words['t_noav'], 11362 );
break;
case 'INVALID_FILE_EXT':
$this->registry->output->showError( $this->lang->words['t_badavext'], 11362 );
break;
}
}
$this->registry->output->redirect( $this->settings['_base_url'] . "app=members&amp;module=members&amp;section=members&amp;do=viewmember&amp;member_id={$this->request['member_id']}", $this->lang->words['t_avupdated'] );
}
/**
* Delete a member's posts [process]
*
* @access private
* @return void [Outputs to screen]
*/
private function _deletePostsDo()
{
//-----------------------------------------
// INIT
//-----------------------------------------
$member_id = intval( $this->request['member_id'] );
$delete_posts = intval( $this->request['dposts'] );
$delete_topics = intval( $this->request['dtopics'] );
$end = intval( $this->request['dpergo'] ) ? intval( $this->request['dpergo'] ) : 50;
$init = intval( $this->request['init'] );
$done = 0;
$start = intval($this->request['st']) >=0 ? intval($this->request['st']) : 0;
$forums_affected = array();
$topics_affected = array();
$img = '<img src="' . $this->settings['skin_acp_url'] . '/images/aff_tick.png" border="0" alt="-" /> ';
$posts_deleted = 0;
$topics_deleted = 0;
//--------------------------------------------
// NOT INIT YET?
//--------------------------------------------
if ( ! $init )
{
$url = $this->settings['base_url'] . '&' . $this->form_code_js . "&do=deleteposts_process&dpergo=" . $this->request['dpergo']
."&st=0"
."&init=1"
."&dposts={$delete_posts}"
."&dtopics={$delete_topics}"
."&use_trash_can=".intval($this->request['use_trash_can'])
."&member_id={$member_id}";
$this->registry->output->multipleRedirectInit( $url );
}
//--------------------------------------------
// Not loaded the func?
//--------------------------------------------
if ( ! is_object( $mod_func ) )
{
require_once( IPS_ROOT_PATH . 'sources/classes/itemmarking/classItemMarking.php' );
$this->registry->setClass( 'classItemMarking', new classItemMarking( $this->registry ) );
require_once( IPSLib::getAppDir('forums') . '/sources/classes/moderate.php' );
$mod_func = new moderatorLibrary( $this->registry );
}
//-----------------------------------------
// Trash-can set up
//-----------------------------------------
$trash_append = '';
if ( $this->settings['forum_trash_can_enable'] and $this->settings['forum_trash_can_id'] )
{
if ( $this->registry->class_forums->forum_by_id[ $this->settings['forum_trash_can_id'] ]['sub_can_post'] )
{
if ( $this->request['use_trash_can'] )
{
$this->trash_forum = $this->settings['forum_trash_can_id'];
$trash_append = " AND forum_id<>{$this->trash_forum}";
}
}
}
//-----------------------------------------
// Get member
//-----------------------------------------
$member = IPSMember::load( $member_id, 'core' );
//-----------------------------------------
// Avoid limit...
//-----------------------------------------
$this->DB->build( array( 'select' => 'p.*',
'from' => array( 'posts' => 'p' ),
'where' => "p.author_id={$member_id}{$trash_append}",
'order' => 'p.pid ASC',
'limit' => array( $start, $end ),
'add_join' => array(
array(
'select' => 't.*',
'from' => array( 'topics' => 't' ),
'where' => 't.tid=p.topic_id',
'type' => 'left',
)
)
) );
$outer = $this->DB->execute();
//-----------------------------------------
// Process...
//-----------------------------------------
while( $r = $this->DB->fetch( $outer ) )
{
//-----------------------------------------
// Copy record to topic array
//-----------------------------------------
$topic = $r;
//-----------------------------------------
// No longer a topic?
//-----------------------------------------
if ( ! $topic['tid'] )
{
continue;
}
$done++;
//-----------------------------------------
// Get number of MID posters
//-----------------------------------------
$topic_i_posted = $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as count',
'from' => 'posts',
'where' => 'author_id=' . $member_id . ' AND topic_id=' . $r['topic_id'] ) );
//-----------------------------------------
// Aready deleted this topic?
//-----------------------------------------
if ( ! $topic_i_posted['count'])
{
continue;
}
//-----------------------------------------
// First check: Our topic and no other replies?
//-----------------------------------------
if ( $topic['starter_id'] == $member_id AND $topic_i_posted['count'] == ( $topic['posts'] + 1 ) )
{
//-----------------------------------------
// Ok, deleting topics or posts?
//-----------------------------------------
if ( ( $delete_posts OR $delete_topics ) AND ( $this->trash_forum and $this->trash_forum != $topic['forum_id'] ) )
{
//-----------------------------------------
// Move, don't delete
//-----------------------------------------
$mod_func->topicMove( $r['topic_id'], $topic['forum_id'], $this->trash_forum );
$forums_affected[ $topic['forum_id'] ] = $topic['forum_id'];
$forums_affected[ $this->trash_forum ] = $this->trash_forum;
$topics_deleted++;
$posts_deleted += $topic_i_posted['count'];
}
else if ( $delete_posts OR $delete_topics )
{
$this->DB->delete( 'posts', 'author_id=' . $member_id . ' AND topic_id=' . $r['topic_id'] );
$this->DB->delete('topics', 'tid=' . $r['topic_id'] );
$forums_affected[ $topic['forum_id'] ] = $topic['forum_id'];
$topics_deleted++;
$posts_deleted += $topic_i_posted['count'];
}
}
//-----------------------------------------
// Is this a topic we started?
//-----------------------------------------
else if ( $topic['starter_id'] == $member_id AND $delete_topics )
{
if ( $this->trash_forum and $this->trash_forum != $topic['forum_id'] )
{
//-----------------------------------------
// Move, don't delete
//-----------------------------------------
$mod_func->topicMove( $r['topic_id'], $topic['forum_id'], $this->trash_forum );
$forums_affected[ $topic['forum_id'] ] = $topic['forum_id'];
$forums_affected[ $this->trash_forum ] = $this->trash_forum;
$topics_deleted++;
$posts_deleted += $topic_i_posted['count'];
}
else
{
$this->DB->delete( 'posts', 'topic_id=' . $r['topic_id'] );
$this->DB->delete( 'topics', 'tid=' . $r['topic_id'] );
$forums_affected[ $topic['forum_id'] ] = $topic['forum_id'];
$topics_deleted++;
$posts_deleted += $topic['posts'] + 1;
}
}
//-----------------------------------------
// Just delete the post, then
//-----------------------------------------
else if ( $delete_posts AND ! $r['new_topic'] )
{
if ( $this->trash_forum and $this->trash_forum != $topic['forum_id'] )
{
//-----------------------------------------
// Set up and pass to split topic handler
//-----------------------------------------
$new_title = $this->lang->words['acp_posts_deleted_from'] . $topic['title'];
$new_desc = $this->lang->words['acp_posts_deleted_from_tid'] . $topic['tid'];
//-----------------------------------------
// Is first post queued?
//-----------------------------------------
$topic_approved = 1;
$first_post = $this->DB->buildAndFetch( array( 'select' => 'pid, queued',
'from' => 'posts',
'where' => "pid=" . $r['pid'],
) );
if( $first_post['queued'] )
{
$topic_approved = 0;
$this->DB->update( 'posts', array( 'queued' => 0 ), 'pid=' . $first_post['pid'] );
}
//-----------------------------------------
// Complete a new dummy topic
//-----------------------------------------
$this->DB->insert( 'topics', array(
'title' => $new_title,
'description' => $new_desc,
'state' => 'open',
'posts' => 0,
'starter_id' => $member_id,
'starter_name' => $member['members_display_name'],
'start_date' => time(),
'last_poster_id' => $member_id,
'last_poster_name' => $member['members_display_name'],
'last_post' => time(),
'icon_id' => 0,
'author_mode' => 1,
'poll_state' => 0,
'last_vote' => 0,
'views' => 0,
'forum_id' => $this->trash_forum,
'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, 'queued' => 0 ), "pid={$r['pid']}" );
$this->DB->update( 'posts', array( 'new_topic' => 0 ), "topic_id={$topic['tid']}" );
$forums_affected[ $topic['forum_id'] ] = $topic['forum_id'];
$forums_affected[ $this->trash_forum ] = $this->trash_forum;
$topics_affected[ $topic['tid'] ] = $topic['tid'];
$topics_affected[ $new_topic_id ] = $new_topic_id;
$posts_deleted++;
}
else
{
$this->DB->delete( 'posts', 'pid=' . $r['pid'] );
$forums_affected[ $topic['forum_id'] ] = $topic['forum_id'];
$topics_affected[ $topic['tid'] ] = $topic['tid'];
$posts_deleted++;
}
}
}
//-----------------------------------------
// Rebuild topics and forums
//-----------------------------------------
if ( count( $topics_affected ) )
{
foreach( $topics_affected as $tid )
{
$mod_func->rebuildTopic( $tid, 0 );
}
}
if ( count( $forums_affected ) )
{
foreach( $forums_affected as $fid )
{
$mod_func->forumRecount( $fid );
}
}
//-----------------------------------------
// Finish - or more?...
//-----------------------------------------
if ( ! $done )
{
//-----------------------------------------
// Recount stats..
//-----------------------------------------
$mod_func->statsRecount();
//-----------------------------------------
// Reset member's posts
//-----------------------------------------
$forums = array();
foreach( $this->registry->class_forums->forum_by_id as $data )
{
if ( ! $data['inc_postcount'] )
{
$forums[] = $data['id'];
}
}
if ( ! count( $forums ) )
{
$count = $this->DB->buildAndFetch( array( 'select' => 'count(*) as count', 'from' => 'posts', 'where' => 'queued != 1 AND author_id=' . $member_id ) );
}
else
{
$count = $this->DB->buildAndFetch( array( 'select' => 'count(p.pid) as count',
'from' => array( 'posts' => 'p' ),
'where' => 'p.queued <> 1 AND p.author_id=' . $member_id . ' AND t.forum_id NOT IN (' . implode( ",", $forums ) . ')',
'add_join' => array(
array( 'type' => 'left',
'from' => array( 'topics' => 't' ),
'where' => 't.tid=p.topic_id'
)
)
) );
}
$new_post_count = intval( $count['count'] );
$this->registry->adminFunctions->saveAdminLog( sprintf( $this->lang->words['member_posts_deleted'], $member['members_display_name'] ) );
IPSMember::save( $member_id, array( 'core' => array( 'posts' => $new_post_count ) ) );
$this->registry->output->multipleRedirectFinish( $this->lang->words['mem_posts_process_done'] );
}
else
{
//-----------------------------------------
// More..
//-----------------------------------------
$next = $start + $end;
$url = $this->settings['base_url'] . '&' . $this->form_code_js . "&do=deleteposts_process&dpergo={$end}"
."&st={$next}"
."&init=1"
."&dposts={$delete_posts}"
."&dtopics={$delete_topics}"
."&use_trash_can=".intval($this->request['use_trash_can'])
."&member_id={$member_id}";
$text = sprintf( $this->lang->words['mem_posts_process_more'], $end, $posts_deleted, $topics_deleted );
$this->registry->output->multipleRedirectHit( $url, $img . ' ' . $text );
}
}
/**
* Delete a member's posts [form/confirmation]
*
* @access private
* @return void [Outputs to screen]
*/
private function _deletePostsStart()
{
//-----------------------------------------
// Page set up
//-----------------------------------------
$this->registry->output->extra_nav[] = array( '', $this->lang->words['mem_delete_title'] );
//-----------------------------------------
// INIT
//-----------------------------------------
$member_id = intval($this->request['member_id']);
//-----------------------------------------
// Get member
//-----------------------------------------
$member = IPSMember::load( $member_id, 'core' );
//-----------------------------------------
// Get number of topics member has started
//-----------------------------------------
$topics = $this->DB->buildAndFetch( array( 'select' => 'count(*) as count',
'from' => 'topics',
'where' => 'starter_id=' . $member_id ) );
$posts = $this->DB->buildAndFetch( array( 'select' => 'count(*) as count',
'from' => 'posts',
'where' => 'author_id=' . $member_id ) );
//-----------------------------------------
// Got any posts?
//-----------------------------------------
if ( ! $posts['count'] )
{
$this->registry->output->showError( $this->lang->words['t_noposts'], 11363 );
}
//-----------------------------------------
// Get number of topics member has started
//-----------------------------------------
$this->lang->words['mem_delete_delete_posts'] = sprintf( $this->lang->words['mem_delete_delete_posts'] , intval($posts['count']) );
$this->lang->words['mem_delete_delete_topics'] = sprintf( $this->lang->words['mem_delete_delete_topics'], intval($topics['count']) );
$this->registry->output->html .= $this->html->deletePostsStart( $member, intval($topics['count']), intval($posts['count']) );
}
}