Вход Регистрация
Файл: IPBMafia.ru_IPB_3.4.6_Final_Rus _Nulled/board/upload/admin/applications/forums/sources/classes/forums/class_forums.php
Строк: 1513
<?php
/**
 * <pre>
 * Invision Power Services
 * IP.Board v3.4.6
 * Forums Class
 * Last Updated: $Date: 2013-03-27 20:18:32 -0400 (Wed, 27 Mar 2013) $
 * </pre>
 *
 * @author         $Author: bfarber $
 * @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
 * @since        26th January 2004
 * @version        $Rev: 12132 $
 */

if ( ! defined'IN_IPB' ) )
{
    print 
"<h1>Incorrect access</h1>You cannot access this file directly. If you have recently upgraded, make sure you upgraded all the relevant files.";
    exit();
}

class 
class_forums
{
    
/**
     * Cache of visible forums
     *
     * @var        array
     */
    
public $forum_cache        = array();
    
    
/**
     * Cache of all forums, regardless of perms
     *
     * @var        array
     */
    
public $allForums        = array();
    
    
/**
     * Cache of visible forums mapped by ID
     *
     * @var        array
     */
    
public $forum_by_id        = array();
    
    
/**
     * Depth guide
     *
     * @var        string
     */
    
public $depth_guide        "--";
    
    
/**
     * Strip invisible forums?
     *
     * @var        bool
     */
    
public $strip_invisible    false;
    
    
/**
     * Cache of moderators
     *
     * @var        array
     */
    
public $mod_cache        = array();
    
    
/**
     * Mod cache loaded
     *
     * @var        bool
     */
    
public $mod_cache_got    false;
    
    
/**
     * Is a read topic only forum
     *
     * @var        bool
     */
    
public $read_topic_only    false;

    
/**#@+
     * Registry Object Shortcuts
     *
     * @var        object
     */
    
protected $registry;
    protected 
$DB;
    protected 
$settings;
    protected 
$request;
    protected 
$lang;
    protected 
$member;
    protected 
$memberData;
    protected 
$cache;
    protected 
$caches;
    
/**#@-*/
    
    /**
     * Posts per day status string
     *
     * @var       string
     */
    
public $ppdStatusMessage '';
    
    
/**
     * Ability to set a different member for permission checks, etc
     * @var array
     */
    
protected $_memberData     = array();
    
    
/**
     * CONSTRUCTOR
     *
     * @param    object    ipsRegistry  $registry
     * @return    @e void
     */
    
public function __constructipsRegistry $registry )
    {
        
/* Make objects */
        
$this->registry $registry;
        
$this->DB       $this->registry->DB();
        
$this->settings =& $this->registry->fetchSettings();
        
$this->request  =& $this->registry->fetchRequest();
        
$this->lang     $this->registry->getClass('class_localization');
        
$this->member   $this->registry->member();
        
$this->memberData =& $this->registry->member()->fetchMemberData();
        
$this->cache    $this->registry->cache();
        
$this->caches   =& $this->registry->cache()->fetchCaches();
        
        
/* Set default memberData */
        
$this->setMemberData$this->memberData );
    }
    
    
/**
     * Grab all forums and stuff into array
     *
     * @return    @e void
     */
    
public function forumsInit()
    {
        
/* Query Forum Data */
        
$forum_list $this->getForumList();
        
        
$hide_parents ',';

        
$this->forum_cache = array();
        
$this->forum_by_id = array();

        foreach( 
$forum_list as $f )
        {
            if( 
$this->strip_invisible )
            {
                
/* Don't show any children of hidden parents */
                
if( strstr$hide_parents','$f['parent_id'] .',' ) )
                {
                    
$hide_parents .= $f['id'].',';
                    continue;
                }
                
                
/* Don't show forums that we do not have view permissions for */
                
if( $f['perm_view'] != '*' )
                { 
                    if ( 
$this->registry->permissions->check'view'$f ) != TRUE )
                    {
                        
$hide_parents .= $f['id'].',';
                        continue;
                    }
                }
                
                
/* Don't show forums that we can not see based on the minimum posts to view setting */
                
if( !empty( $f['min_posts_view'] ) AND ( $this->_memberData['posts'] < $f['min_posts_view'] ) AND !$this->_memberData['g_is_supmod'] )
                {
                    continue;
                }        
            }
            
            
/* We lump in archived counts here */
            //$f['posts']  += intval( $f['archived_posts'] );
            //$f['topics'] += intval( $f['archived_topics'] );
            
            /* Set the aprent id for root categories */
            
if( $f['parent_id'] < )
            {
                
$f['parent_id'] = 'root';
            }
            
            
$f['fid'] = $f['id'];
            
            
/* Store the forum arrays */
            
$this->forum_cache$f['parent_id'] ][ $f['id'] ] = $f;
            
$this->forum_by_id$f['id'] ] = $this->forum_cache$f['parent_id'] ][ $f['id'] ];
        }
    }
    
    
/**
     * Returns a forum based on an ID
     * Added in 3.2 to abstract out some forum functionality
     *
     * @return    array
     * @note    This function DOES NOT perform any check on the forum data before returning it, you should check yourself if the member can view the forum
     */
    
public function getForumById$id )
    {
        
/* Init vars */
        
$id intval$id );
        
        
/* Got a forum already? */
        
if ( ! isset($this->allForums$id ]) )
        {
            
$forum $this->DB->buildAndFetch( array( 'select'   => 'f.*',
                                                      
'from'     => array( 'forums' => 'f' ),
                                                      
'where'    => 'f.id=' intval$id ),
                                                      
'add_join' => array( array( 'select' => 'p.*',
                                                                                  
'from'   => array( 'permission_index' => 'p' ),
                                                                                  
'where'  => "p.perm_type_id=f.id AND p.app='forums' AND p.perm_type='forum'",
                                                                                  
'type'   => 'left' ) ) ) );
            
            
/* Got a result? */
            
if ( ! empty( $forum['id'] ) )
            {
                
/* Unpack bitwise fields */
                
$_tmp IPSBWOptions::thaw$forum['forums_bitoptions'], 'forums''forums' );
    
                if ( 
count$_tmp ) )
                {
                    foreach( 
$_tmp as $k => $v )
                    {
                        
$forum$k ] = $v;
                    }
                }
                
                
$forum array_merge$forum$this->registry->permissions->parse$forum ) );
            }
            else
            {
                
$forum = array(); // Prevents trying to load the forum again if it doesn't exist
            
}
            
            
$this->allForums$id ]   = $forum;
        }
        
        return 
$this->allForums$id ];
    }
    
    
/**
     * Can start topics in this forum?
     * @param int $forumId
     */
    
public function canStartTopic$forumId )
    {
        
$forumData $this->getForumById$forumId );
        
        
/* Posting Allowed? */
        
$canPost true;
        
        if( ! 
$this->registry->permissions->check'start'$forumData ) )
        {
            
$canPost false;
        }

        if( ! 
$forumData['sub_can_post'] )
        {
            
$canPost false;
        }

        if( 
$forumData['min_posts_post'] && $forumData['min_posts_post'] > $this->_memberData['posts'] && !$this->_memberData['g_is_supmod'] )
        {
            
$canPost false;
        }
        
        if( ! 
$this->_memberData['g_post_new_topics'] )
        {
            
$canPost false;
        }
        
        return 
$canPost;
    }
    
    
/**
     * is the answer system enabled?
     * @param int $forumId
     */
    
public function answerTopicsEnabled$forumId )
    { 
        
$forumData $this->getForumById$forumId );
    
        return ( ! empty( 
$forumData['bw_enable_answers'] ) ) ? true false;
    }
    
    
/**
     * Returns a list of all forums
     *
     * @return    array
     */
    
public function getForumList()
    {
        
/* Get the forums */            
        
$this->DB->build( array( 'select'   => 'f.*',
                                 
'from'     => array( 'forums' => 'f' ),
                                 
'add_join' => array( array( 'select' => 'p.*',
                                                             
'from'   => array( 'permission_index' => 'p' ),
                                                             
'where'  => "p.perm_type='forum' AND p.app='forums' AND p.perm_type_id=f.id",
                                                             
'type'   => 'left' ),
                                                      
$this->registry->classItemMarking->getSqlJoin( array( 'item_app_key_1' => 'f.id' ) ) ) ) );
                        
        
$q $this->DB->execute();
        
        
/* Loop through and build an array of forums */
        
$forums_list    = array();
        
$update_seo        = array();
        
$tempForums     = array();
        
        while( 
$f $this->DB->fetch$q ) )
        {
            
$tempForums$f['parent_id'] . '.' $f['position'] . '.' $f['id'] ] = $f;
        }

        
/* Sort in PHP */
        
$tempForums IPSLib::knatsort$tempForums );
        
        foreach( 
$tempForums as $posData => $f )
        {
            
$fr = array();
            
            
/* Add back into topic markers */
            
$f $this->registry->classItemMarking->setFromSqlJoin$f'forums' );
            
            
/**
             * This is here in case the SEO name isn't stored for some reason.
             * We'll parse it and then update the forums table - should only happen once
             */
            
if ( ! $f['name_seo'] )
            {
                
/* SEO name */
                
$f['name_seo'] = IPSText::makeSeoTitle$f['name'] );
                
                
$update_seo$f['id'] ]    = $f['name_seo'];
            }
            
            
/* Reformat the array for a category */
            
if ( $f['parent_id'] == -)
            {
                
$fr $f;
                
                
$fr['parent_id']            = 'root';
                
$fr['hide_last_info']        = 0;
                
$fr['can_view_others']        = 0;
            }
            else
            {
                
$fr $f;

                
$fr['description'] = isset( $f['description'] ) ? $f['description'] : '';
            }
            
            
$fr array_merge$fr$this->registry->permissions->parse$f ) );

            
/* Unpack bitwise fields */
            
$_tmp IPSBWOptions::thaw$fr['forums_bitoptions'], 'forums''forums' );

            if ( 
count$_tmp ) )
            {
                foreach( 
$_tmp as $k => $v )
                {
                    
/* Trigger notice if we have DB field */
                    
if ( isset( $fr$k ] ) )
                    {
                        
trigger_error"Thawing bitwise options for FORUMS: Bitwise field '$k' has overwritten DB field '$k'"E_USER_WARNING );
                    }

                    
$fr$k ] = $v;
                }
            }
            
            
/* Add... */
            
$forums_list$fr['id'] ] = $fr;
        }

        
$this->allForums    $forums_list;
        
        
/**
         * Update forums table if SEO name wasn't cached yet
         */
        
if( count($update_seo) )
        {
            foreach( 
$update_seo as $k => $v )
            {
                
$this->DB->update'forums', array( 'name_seo' => $v ), 'id=' $k );
            }
        }
        
        return 
$forums_list;
    }
    
    
/**
     * @return the $_memberData
     */
    
public function getMemberData$k='' )
    {
        return ( ! empty( 
$k ) ) ? $this->_memberData$k ] : $this->_memberData;
    }

    
/**
     * @param    string    key
     * @param    string    value
     */
    
public function setMemberData$k$v='' )
    {
        if ( 
is_integer$k ) )
        {
            
$this->_memberData = empty( $k ) ? IPSMember::setUpGuest() : IPSMember::load$k );
        }
        else if ( 
is_string($k) && $k == intval($k) )
        {
            
$this->_memberData = empty( $k ) ? IPSMember::setUpGuest() : IPSMember::load$k );
        }
        else if ( 
is_array$k ) )
        {
            
$this->_memberData $k;
        }
        else if ( ! empty( 
$k ) )
        {
            
$this->_memberData$k ] = $v;
        }
        
        
$this->_memberData IPSMember::setUpModerator$this->_memberData );
    }
    
    
/**
     * Check to see if we have any group restrictions on whether we can post or not
     * Naturally, this would be better off in the classPost class but this means we'd have
     * to load it in topic view for the fast reply box.
     *
     * Optionally populates a status message in ppdStatusMessage
     *
     * @param    array         [Member data (assumes $this->_memberData if nothing passed )]
     * @param    boolean        Populate ppdStatusMessage?
     * @return    boolean        TRUE = ok to post, FALSE cannot post
     */
    
public function checkGroupPostPerDay$memberData = array(), $setStatus=FALSE )
    {
        
$memberData = ( is_array$memberData ) and count$memberData ) ) ? $memberData $this->_memberData;
        
$group      $this->caches['group_cache'][ $memberData['member_group_id'] ];
        
$_data      explode','$memberData['members_day_posts'] );
        
$_count     intval$_data[0] );
        
$_time      intval$_data[1] );
        
        
/* Ok? */
        
if ( is_array$group ) AND is_array$memberData ) )
        {
            
/* Check posts per day */
            
if ( $group['g_ppd_limit'] )
            {
                
/* Check to see if we're past our 24hrs */
                
if ( ( time() - 86400 ) >= $_time AND ( $_time ) )
                {
                    
$count  $this->fetchMemberPpdCount$memberData['member_id'], time() - 86400 );
                    
$_count $count['count'];
                    
$_time  $count['min'];
                    
                    
/* Update member immediately */
                    
IPSMember::save$memberData['member_id'], array( 'core' => array( 'members_day_posts' => $_count ',' $_time  ) ) );
                }
                
                
/* Grab the correct lang file */
                
if ( $setStatus )
                {
                    if ( ! isset( 
$this->lang->words['status_ppd_posts'] ) )
                    {
                        
$this->registry->class_localization->loadLanguageFile( array( 'public_topic' ), 'forums' );
                    }
                }
                
                
/* Do we only limit for x posts/days? */
                
if ( $group['g_ppd_unit'] )
                {
                    if ( 
$group['gbw_ppd_unit_type'] )
                    {
                        
/* Days.. .*/
                        
if ( $memberData['joined'] > ( time() - ( 86400 $group['g_ppd_unit'] ) ) )
                        {
                            if ( 
$_count >= $group['g_ppd_limit'] )
                            {
                                return 
FALSE;
                            }
                            else if ( 
$setStatus )
                            {
                                if ( 
$_time )
                                {
                                    
$this->ppdStatusMessage sprintf$this->lang->words['status_ppd_posts_joined'], $group['g_ppd_limit'] - $_count$this->lang->getDate$_time 86400'long' ), $this->lang->getDate$memberData['joined'] + ( 86400 $group['g_ppd_unit'] ), 'long' ) );
                                }
                                else
                                {
                                    
$this->ppdStatusMessage sprintf$this->lang->words['status_ppd_posts_joined_no_time'], $group['g_ppd_limit'] - $_count$this->lang->getDate$memberData['joined'] + ( 86400 $group['g_ppd_unit'] ), 'long' ) );
                                }
                            }
                        }
                    }
                    else
                    {
                        
/* Posts */
                        
if ( $memberData['posts'] < $group['g_ppd_unit'] )
                        {
                            if ( 
$_count >= $group['g_ppd_limit'] ) 
                            {
                                return 
FALSE;
                            }
                            else
                            { 
                                if ( 
$_time )
                                {
                                    
$this->ppdStatusMessage sprintf$this->lang->words['status_ppd_posts'], $group['g_ppd_limit'] - $_count$this->lang->getDate$_time 86400'long' ), ( $group['g_ppd_unit'] - $memberData['posts'] ) );
                                }
                                else
                                {
                                    
$this->ppdStatusMessage sprintf$this->lang->words['status_ppd_posts_no_time'], $group['g_ppd_limit'] - $_count, ( $group['g_ppd_unit'] - $memberData['posts'] ) );
                                }
                            }
                        }
                    }
                }
                else
                {
                    
/* No PPD limit, but still checking PPD */
                    
if ( $_count >= $group['g_ppd_limit'] )
                    {
                        return 
FALSE;
                    }
                    else
                    {
                        if ( 
$_time )
                        {
                            
$this->ppdStatusMessage sprintf$this->lang->words['status_ppd_posts_nolimit'], $group['g_ppd_limit'] - $_count$this->lang->getDate$_time 86400'long' ) );
                        }
                        else
                        {
                            
$this->ppdStatusMessage sprintf$this->lang->words['status_ppd_posts_nolimit_no_time'], $group['g_ppd_limit'] - $_count );
                        }
                    }
                }
            }
            
            
/* Still here? */
            
return TRUE;
        }
        else
        {
            return 
FALSE;
        }
    }
    
    
/**
     * Fetch member's PPD details
     *
     * @param    int        member id
     * @param    int        timestamp 'from'
     * @return    array    min, count
     */
    
public function fetchMemberPpdCount$memberId$time )
    {
        
/* Recount today's posts BOTH approved and unapproved */
        
$count $this->DB->buildAndFetch( array( 'select' => 'COUNT(*) as count, MIN(post_date) as min',
                                                    
'from'   => 'posts',
                                                    
'where'  => 'author_id=' intval($memberId) . ' AND post_date > ' $time ' AND ' $this->fetchPostHiddenQuery( array( 'visible''hidden' ) ) ) );
                                        
        return 
$count;
    }
    
    
/**
     * Fetch forum data
     *
     * @param    int            Forum ID
     * @return    array         Forum Data
     */
    
public function forumsFetchData$id )
    {
        return 
is_array$this->forum_by_id$id ] ) ? $this->forum_by_id$id ] : array( 'id' => );
    }
    
    
/**
     * Grab all mods innit
     *
     * @return    @e void
     */
    
public function forumsGetModeratorCache()
    {
        
$this->can_see_queued = array();
        
        if ( ! 
is_array$this->caches['moderators'] ) )
        {
            
$this->cache->rebuildCache'moderators''forums' );
        }
        
        
/* Set Up */
        
if ( count$this->caches['moderators'] ) )
        {
            foreach( 
$this->caches['moderators'] as $r )
            {
                
$forumIds explode','IPSText::cleanPermString$r['forum_id'] ) );
                
                foreach( 
$forumIds as $forumId )
                {
                    
$this->mod_cache$forumId ][ $r['mid'] ] = array( 
                                                                        
'name'    => $r['members_display_name'],
                                                                        
'seoname' => $r['members_seo_name'],
                                                                        
'memid'   => $r['member_id'],
                                                                        
'id'      => $r['mid'],
                                                                        
'isg'     => $r['is_group'],
                                                                        
'gname'   => $r['group_name'],
                                                                        
'gid'     => $r['group_id'],
                                                                    );    
                }
            }
        }
        
        
$this->mod_cache_got 1;
    }
    
    
/**
     * Get moderator status from DB
     *
     * @return    @e array
     */
    
public function getModerator()
    {
        
//-----------------------------------------
        // Init
        //-----------------------------------------

        
$permissions    = array();
        
        
//-----------------------------------------
        // If we are a mod, get our permissions from DB
        //-----------------------------------------
        
        
if( $this->_memberData['is_mod'] )
        {
            
$other_mgroups    = array();
            
$_other_mgroups    IPSText::cleanPermString$this->_memberData['mgroup_others'] );
            
            if( 
$_other_mgroups )
            {
                
$other_mgroups    explode","$_other_mgroups );
            }
            
            
$other_mgroups[]    = $this->_memberData['member_group_id'];

            
$this->DB->build( array( 
                                    
'select' => '*',
                                    
'from'   => 'moderators',
                                    
'where'  => "(member_id='" $this->_memberData['member_id'] . "' OR (is_group=1 AND group_id IN(" implode","$other_mgroups ) . ")))" 
                            
)    );
                                          
            
$this->DB->execute();
            
            
//-----------------------------------------
            // We do it this way to allow member-specific mod privileges
            // to override group-inherited mod privileges
            //-----------------------------------------
            
            
while ( $moderator $this->DB->fetch() )
            {
                if ( 
$moderator['member_id'] == $this->_memberData['member_id'] )
                {
                    return 
$moderator;
                }
                else
                {
                    
$permissions    $moderator;
                }
            }
        }
        
        return 
$permissions;
    }
    
    
/**
     * Get Moderators
     *
     * @param    integer    $forum_id
     * @return    string
     */
    
public function forumsGetModerators$forum_id="" )
    {
        if ( ! 
$this->mod_cache_got )
        {
            
$this->forumsGetModeratorCache();
        }
        
        
$mod_string = array();
        
        if ( 
$forum_id == "" )
        {
            return 
$mod_string;
        }
        
        if (isset(
$this->mod_cache$forum_id ] ) )
        {
            if (
is_array($this->mod_cache$forum_id ]) )
            {
                foreach (
$this->mod_cache$forum_id ] as $moderator)
                {
                    if (
$moderator['isg'] == 1)
                    {
                        
$mod_string[] = array( $this->registry->getClass("output")->buildSEOUrl"app=members&amp;module=list&amp;max_results=30&amp;filter={$moderator['gid']}&amp;sort_order=asc&amp;sort_key=members_display_name&amp;st=0&amp;b=1""public""false" ), $moderator['gname'], );
                    }
                    else if( 
$moderator['memid'] )
                    {
                        if ( ! 
$moderator['name'] )
                        {
                            continue;
                        }
                        
$mod_string[] = array( $this->registry->getClass("output")->buildSEOUrl"showuser={$moderator['memid']}""public"$moderator['seoname'], 'showuser' ), $moderator['name'], $moderator['memid'] );
                    }
                }
            }
            else
            {
                if (
$this->mods[$forum_id]['isg'] == 1)
                {
                    
$mod_string[] = array( $this->registry->getClass("output")->buildSEOUrl"app=members&amp;max_results=30&amp;filter={$this->mods[$forum_id]['gid']}&amp;sort_order=asc&amp;sort_key=name&amp;st=0&amp;b=1""public""false" ), $this->mods[$forum_id]['gname'], );
                }
                else if( 
$this->mods[$forum_id]['memid'] )
                {
                    
$mod_string[] = array( $this->registry->getClass("output")->buildSEOUrl"showuser={$this->mods[$forum_id]['memid']}""public"$this->mods[$forum_id]['seoname'], 'showuser' ), $this->mods[$forum_id]['name_seo'], $this->mods[$forum_id]['memid'] );
                }
            }
        }
        
        return 
$mod_string;
        
    }

    
/**
     * Check Forum Access
     *
     * @param    integer    $fid            Forum id
     * @param    bool    $prompt_login    Prompt login/show error
     * @param    string    $in                [topic|forum]
     * @param    array     $topic            Topic data
     * @param    bool    $return            Return instead of displaying an error
     * @return    bool
     */
    
public function forumsCheckAccess$fid$prompt_login=0$in='forum'$topic=array(), $return=false )
    {
        
$fid         intval$fid );
        
$deny_access 1;
        
        
/* Pass it along */
        
$this->registry->permissions->setMemberData$this->getMemberData() );
        
        if ( 
$this->registry->permissions->check'view'$this->allForums[$fid] ) == TRUE )
        {
            if ( 
$this->registry->permissions->check'read'$this->allForums[$fid] ) == TRUE )
            {
                
$deny_access 0;
            }
            else
            {
                
//-----------------------------------------
                // Can see topics?
                //-----------------------------------------
        
                
if ( $this->allForums[$fid]['permission_showtopic'] )
                {
                    
$this->read_topic_only 1;
                    
                    if ( 
$in == 'forum' )
                    {
                        
$deny_access 0;
                    }
                    else
                    {
                        if( 
$return )
                        {
                            return 
false;
                        }
                        
                        
$this->forumsCustomError$fid );
                        
                        
$deny_access 1;                        
                    }
                }
                else
                {
                    if( 
$return )
                    {
                        return 
false;
                    }
                        
                    
$this->forumsCustomError$fid );
                    
                    
$deny_access 1;
                }
            }
        }
        else
        {
            if( 
$return )
            {
                return 
false;
            }
                        
            
$this->forumsCustomError$fid );
            
            
$deny_access 1;
        }
        
        
/* Reset member data after use */
        
$this->registry->permissions->setMemberData$this->memberData );
        
        
//-----------------------------------------
        // Do we have permission to even see the password page?
        //-----------------------------------------
        
        
if ( $deny_access == )
        {
            
$group_exempt 0;
            
            if ( isset( 
$this->allForums[$fid]['password'] ) AND $this->allForums[$fid]['password'] != '' AND $this->allForums[$fid]['sub_can_post'] )
            {
                if ( isset( 
$this->allForums[$fid]['password_override'] ) && IPSText::cleanPermString($this->allForums[$fid]['password_override']) != '' )
                {
                    if ( 
IPSMember::isInGroup$this->_memberDataexplode","IPSText::cleanPermString($this->allForums[$fid]['password_override']) ) ) )
                    {
                        
$group_exempt 1;
                        
$deny_access 0;
                    }
                }
                
                if ( 
$group_exempt == )
                {
                    if ( 
$this->forumsComparePassword$fid ) == TRUE )
                    {
                        
$deny_access 0;
                    }
                    else
                    {
                        
$deny_access 1;
                        
                        if ( 
$prompt_login == )
                        {
                            if( 
$return )
                            {
                                return 
false;
                            }

                            
$this->forumsShowLogin$fid );
                        }
                    }
                }
            }
        }
        
        if( 
is_array$topic ) && count$topic ) )
        {
            if ( ( ! 
$this->_memberData['g_other_topics'] ) AND ( $topic['starter_id'] != $this->_memberData['member_id'] ) )
            {
                if( 
$return )
                {
                    return 
false;
                }
                
                
$this->registry->getClass('output')->showError'forums_no_view_topic'103136nullnull404 );
            }
            else if( (!
$this->allForums[$fid]['can_view_others'] AND !$this->_memberData['is_mod'] ) AND ( $topic['starter_id'] != $this->_memberData['member_id'] ) )
            {
                if( 
$return )
                {
                    return 
false;
                }
                
                
$this->registry->getClass('output')->showError'forums_no_view_topic'103137nullnull404 );
            }
        }

        if( 
$this->allForums[$fid]['min_posts_view'] && $this->allForums[$fid]['min_posts_view'] > $this->_memberData['posts'] && !$this->_memberData['g_is_supmod'] )
        {
            if( 
$return )
            {
                return 
false;
            }

            
$this->registry->getClass('output')->showError'forums_not_enough_posts'103138nullnull403 );
        }
        
        if ( 
$deny_access == )
        {
            if( 
$return )
            {
                return 
false;
            }

            
$this->registry->getClass('output')->showError'forums_no_permission'103139nullnull404 );
        }
        else
        {
            return 
TRUE;
        }
    }

    
/**
     * Compare forum pasword
     *
     * @param    integer    $fid    Forum ID
     * @return    bool
     */
    
public function forumsComparePassword$fid )
    {
        
$cookie_pass IPSCookie::get'ipbforumpass_'.$fid );
        
        if ( 
trim$cookie_pass ) == md5$this->forum_by_id[$fid]['password'] ) )
        {
            return 
TRUE;
        }
        else
        {
            return 
FALSE;
        }
    }
    
    
/**
     * Forums custom error
     *
     * @param    integer    $fid    Forum ID
     * @return    @e void
     */
    
public function forumsCustomError$fid )
    {
        
$tmp $this->DB->buildAndFetch( array( 'select' => 'permission_custom_error''from' => 'forums''where' => "id=".$fid ) );
        
        if ( 
$tmp['permission_custom_error'] )
        {
            
$this->registry->output->showError$tmp['permission_custom_error'], 103149nullnull403 );
        }
    }
        
    
/**
     * Forums log in screen
     *
     * @param    integer    $fid    Forum ID
     * @return    @e void
     */
    
public function forumsShowLogin$fid )
    {
        
/* Lang */
        
$this->registry->class_localization->loadLanguageFile( array( 'public_forums' ), 'forums' );
        
        
/* Output */
        
$content $this->registry->getClass('output')->getTemplate('forum')->forumPasswordLogIn$fid );
        
$nav     $this->forumsBreadcrumbNav$fid );
        
        if( 
is_array$nav ) AND count$nav ) )
        {
            foreach( 
$nav as $_id => $_nav )
            {
                
$this->registry->getClass('output')->addNavigation$_nav[0], $_nav[1], $_nav[2], $_nav[3] );
            }
        }
        
        
$this->registry->getClass('output')->setTitle$this->settings['board_name'] . ' -> ' $this->forum_by_id[$fid]['name'] );
        
$this->registry->getClass('output')->addContent$content );
        
        
$this->registry->getClass('output')->sendOutput();
    }
    
    
/**
     * Find all the parents of a child without getting the nice lady to 
     * use the superstore tannoy to shout "Small ugly boy in tears at reception"
     *
     * @param    integer    $root_id
     * @param    array     $ids
     * @return    array
     */
    
public function forumsGetParents$root_id$ids=array() )
    {
        if ( 
$this->forum_by_id$root_id ]['parent_id'] and $this->forum_by_id$root_id ]['parent_id'] != 'root' )
        {
            
$ids[] = $this->forum_by_id$root_id ]['parent_id'];
            
            
// Stop endless loop setting cat as it's own parent?
            
if ( in_array$root_id$ids ) )
            {
                
//return $ids;
            
}
            
            
$ids $this->forumsGetParents$this->forum_by_id$root_id ]['parent_id'], $ids );
        }
    
        return 
$ids;
    }

    
/**
     * Get all the children
     *
     * @param    integer    $root_id
     * @param    array     $ids
     * @return    array
     */
    
public function forumsGetChildren$root_id$ids=array() )
    {
        if ( isset( 
$this->forum_cache$root_id ]) AND is_array$this->forum_cache$root_id ] ) )
        {
            foreach( 
$this->forum_cache$root_id ] as $forum_data )
            {
                
$ids[] = $forum_data['id'];
                
                
$ids $this->forumsGetChildren($forum_data['id'], $ids);
            }
        }
        
        return 
$ids;
    }
    
    
/**
     * Gets cumulative posts/topics - sets new post marker and last topic id
     *
     * @param    integer    $root_id
     * @param    array     $forum_data
     * @param    bool    $done_pass
     * @return    array
     */
    
public function forumsCalcChildren$root_id$forum_data=array(), $done_pass=)
    {
        
//-----------------------------------------
        // Markers
        //-----------------------------------------

        
$rtime $this->registry->classItemMarking->fetchTimeLastMarked( array( 'forumID' => $forum_data['id'], 'itemLastUpdate' => $forum_data['last_post'] ), 'forums' );

        if( !isset(
$forum_data['_has_unread']) )
        {
            
$forum_data['_has_unread'] = ( $forum_data['last_post'] && $forum_data['last_post'] > $rtime ) ? 0;
        }
        
        
/* Let's fix an empty forum ID... Bug #38436 */
        
if ( empty($forum_data['fid']) && $forum_data['id'] )
        {
            
$forum_data['fid'] = $forum_data['id'];
        }
        
        if ( isset( 
$this->forum_cache$root_id ]) AND is_array$this->forum_cache$root_id ] ) )
        {
            foreach( 
$this->forum_cache$root_id ] as $data )
            {
                if ( 
$data['last_post'] > $forum_data['last_post'] AND ! $data['hide_last_info'] )
                {
                    
$forum_data['last_post']            = $data['last_post'];
                    
$forum_data['fid']                    = $data['id'];
                    
$forum_data['last_id']                = $data['last_id'];
                    
$forum_data['last_title']            = $data['last_title'];
                    
$forum_data['seo_last_title']        = $data['seo_last_title'];
                    
$forum_data['password']                = isset( $data['password'] ) ? $data['password'] : '';
                    
$forum_data['password_override']    = isset( $data['password_override'] ) ? $data['password_override'] : '';
                    
$forum_data['last_poster_id']        = $data['last_poster_id'];
                    
$forum_data['last_poster_name']        = $data['last_poster_name'];
                    
$forum_data['seo_last_name']        = $data['seo_last_name'];
                    
$forum_data['_has_unread']          = $forum_data['_has_unread'];
                }
                
                
//-----------------------------------------
                // Markers.  We never set false from inside loop.
                //-----------------------------------------
                
                
$rtime                 $this->registry->classItemMarking->fetchTimeLastMarked( array( 'forumID' => $data['id'], 'itemLastUpdate' => $data['last_post'] ), 'forums' );
                
$data['_has_unread'] = 0;
                
                if( 
$data['last_post'] && $data['last_post'] > $rtime )
                {
                    
$forum_data['_has_unread']        = 1;
                    
$data['_has_unread']            = 1;
                }
                
                
//-----------------------------------------
                // If this forum isn't 'lit' yet, check it's children
                //-----------------------------------------
                
                
if ( ! $data['_has_unread'] )
                {
                    
$children            $this->forumsGetChildren$data['id'] );
                    
                    if( 
count($children) )
                    {
                        foreach( 
$children as $_child )
                        {
                            
$_child    $this->getForumById$_child );
                            
                            
$rtime                 $this->registry->classItemMarking->fetchTimeLastMarked( array( 'forumID' => $_child['id'], 'itemLastUpdate' => $_child['last_post'] ), 'forums' );
                            
                            if( 
$_child['last_post'] && $_child['last_post'] > $rtime )
                            {
                                
$forum_data['_has_unread']        = 1;
                                
$data['_has_unread']            = 1;
                                break;
                            }
                        }
                    }
                }

                
//-----------------------------------------
                // Topics and posts
                //-----------------------------------------
                
                
$forum_data['posts']  += $data['posts'];
                
$forum_data['topics'] += $data['topics'];
                
                
$_mod = ( isset( $this->_memberData['forumsModeratorData'] ) ) ? $this->_memberData['forumsModeratorData'] : array();
                
                if ( 
$this->_memberData['g_is_supmod'] or ( $_mod && !empty( $_mod$data['id'] ]['post_q'] ) ) )
                {
                    
$forum_data['queued_posts']  += $data['queued_posts'];
                    
$forum_data['queued_topics'] += $data['queued_topics'];
                }
                
                if ( ! 
$done_pass )
                {
                    
$forum_data['subforums'][ $data['id'] ] = array($data['id'], $data['name'], $data['name_seo'], intval$data['_has_unread']  ), );
                }
                
                
$forum_data $this->forumsCalcChildren$data['id'], $forum_data);
            }
        }

        return 
$forum_data;
    }
    
    
/**
     * Create forum breadcrumb nav
     *
     * @param    integer    $root_id
     * @param    string    $url
     * @return    array
     */
    
public function forumsBreadcrumbNav($root_id$url='showforum='$omitLast=false)
    {
        
$nav_array[] = array( $this->forum_by_id[$root_id]['name'], $url $root_id$this->forum_by_id[$root_id]['name_seo'], 'showforum' );
    
        
$ids $this->forumsGetParents$root_id );
        
        if ( 
is_array($ids) and count($ids) )
        {
            foreach( 
$ids as $id )
            {
                
$data $this->forum_by_id[$id];
                
                
$nav_array[] = array( $data['name'], $url $data['id'], $data['name_seo'], 'showforum' );
            }
        }
        
        if ( 
$omitLast )
        {
            
$x array_shift$nav_array );
        }
        
        return 
array_reverse$nav_array );
    }
    
    
/**
     * Builds the forum jump
     *
     * @param    bool    $html
     * @param    bool    $override
     * @param    bool    $remove_redirects
     * @param    mixed    $defaulted        Single forum id to check against, or array of forum ids to check
     * @return    string
     */
    
public function forumsForumJump$html=0$override=0$remove_redirects=0$defaulted=array(), $noSelectRoot=false )
    {
        
$jump_string    "";
        
$defaulted        = ( is_array($defaulted) AND count($defaulted) ) ? $defaulted : ( is_int($defaulted) ? array( $defaulted ) : ( $this->request['f'] ? array( $this->request['f']) : array() ) );
        
        if( 
is_array$this->forum_cache['root'] ) AND count$this->forum_cache['root'] ) )
        {
            foreach( 
$this->forum_cache['root'] as $forum_data )
            {
                if ( 
$forum_data['sub_can_post'] or ( isset( $this->forum_cache$forum_data['id'] ] ) AND is_array$this->forum_cache$forum_data['id'] ] ) AND count$this->forum_cache$forum_data['id'] ] ) ) )
                {
                    
$forum_data['redirect_on'] = isset( $forum_data['redirect_on'] ) ? $forum_data['redirect_on'] : 0;
                    
                    if( 
$remove_redirects == AND $forum_data['redirect_on'] == )
                    {
                        continue;
                    }
                    
                    
$selected "";
                    
                    if (
$html == or $override == 1)
                    {
                        if( 
in_array$forum_data['id'], $defaulted ) )
                        {
                            
$selected ' selected="selected"';
                        }
                    }
                    
                    if ( 
$noSelectRoot )
                    {
                        
$selected "disabled='disabed'";
                    }
                    
                    
$jump_string .= "<option value="{$forum_data['id']}"".$selected.">".$forum_data['name']."</option>n";
                    
                    
$depth_guide $this->depth_guide;
                    
                    if ( isset(
$this->forum_cache$forum_data['id'] ]) AND is_array$this->forum_cache$forum_data['id'] ] ) )
                    {
                        foreach( 
$this->forum_cache$forum_data['id'] ] as $forum_data )
                        {
                            if( 
$remove_redirects == AND $forum_data['redirect_on'] == )
                            {
                                continue;
                            }                        
                            
                            if (
$html == or $override == 1)
                            {
                                
$selected "";
                                
                                if( 
in_array$forum_data['id'], $defaulted ) )
                                {
                                    
$selected ' selected="selected"';
                                }
                            }
                            
                            
$jump_string .= "<option value="{$forum_data['id']}"".$selected.">&nbsp;&nbsp;&#0124;".$depth_guide." ".$forum_data['name']."</option>n";
                            
                            
$jump_string $this->_forumsForumJumpInternal$forum_data['id'], $jump_string$depth_guide $this->depth_guide$html$override$remove_redirects$defaulted );
                        }
                    }
                }
            }
        }
        
        return 
$jump_string;
    }
    
    
/**
     * Internal helper function for forumsForumJump
     *
     * @param    integer    $root_id
     * @param    string    $jump_string
     * @param    string    $depth_guide
     * @param    bool    $html
     * @param    bool    $override
     * @param    bool    $remove_redirects
     * @param    array    $defaulted
     * @return    string
     */
    
protected function _forumsForumJumpInternal$root_id$jump_string=""$depth_guide="",$html=0$override=0$remove_redirects=0$defaulted=array() )
    {
        if ( isset(
$this->forum_cache$root_id ]) AND is_array$this->forum_cache$root_id ] ) )
        {
            foreach( 
$this->forum_cache$root_id ] as $forum_data )
            {
                if( 
$remove_redirects == AND $forum_data['redirect_on'] == )
                {
                    continue;
                }
                
                
$selected "";
                                
                if (
$html == or $override == 1)
                {
                    if( 
in_array$forum_data['id'], $defaulted ) )
                    {
                        
$selected ' selected="selected"';
                    }
                }
                    
                
$jump_string .= "<option value="{$forum_data['id']}"".$selected.">&nbsp;&nbsp;&#0124;".$depth_guide." ".$forum_data['name']."</option>n";
                
                
$jump_string $this->_forumsForumJumpInternal$forum_data['id'], $jump_string$depth_guide $this->depth_guide$html$override$defaulted );
            }
        }
        
        
        return 
$jump_string;
    }
    
    
/**
     * Sorts out the last poster, etc
     *
     * @param    array     $forum_data
     * @return    array
     */
    
public function forumsFormatLastinfo$forum_data )
    {
        
//-----------------------------------------
        // INIT
        //-----------------------------------------
        
        
$this->settings['disable_subforum_show'] = intval$this->settings['disable_subforum_show'] );
        
        
$show_subforums                    $this->registry->permissions->check'view'$this->forum_by_id$forum_data['id'] ] ) ? 0;
        
$this->request['f']                = isset( $this->request['f'] ) ? intval$this->request['f'] ) : 0;

        
$forum_data['img_new_post']        = $this->forumsNewPosts$forum_data );
        
$forum_data['last_topic_title']    = $this->lang->words['f_none'];
        
$forum_data['last_topic_id']    = 0;
        
$forum_data['full_last_title']    = isset( $forum_data['last_title'] ) ? $forum_data['last_title'] : '';
        
$forum_data['_hide_last_date']    = false;
        
        if ( isset(
$forum_data['last_title']) && $forum_data['last_id'] )
        {
            
$forum_data['last_title'] = strip_tags$forum_data['last_title'] );
            
$forum_data['last_title'] = str_replace"&#33;" "!"$forum_data['last_title'] );
            
$forum_data['last_title'] = str_replace"&quot;"'"'$forum_data['last_title'] );
            
            
$forum_data['last_title'] = IPSText::truncate($forum_data['last_title'], 30);
            
            if ( ( ! empty(
$forum_data['password']) ) OR ( $this->registry->permissions->check'read'$this->forum_by_id$forum_data['fid'] ] ) != TRUE AND $this->forum_by_id$forum_data['fid'] ]['permission_showtopic'] == ) )
            {
                
$forum_data['last_topic_title']    = $this->lang->words['f_protected'];
                
$forum_data['_hide_last_date']    = true;
            }
            else if( 
$forum_data['hide_last_info'] )
            {
                
$forum_data['last_topic_title']    = $this->lang->words['f_protected'];
                
$forum_data['_hide_last_date']    = true;
            }
            else
            {
                
$forum_data['last_topic_id']    = $forum_data['last_id'];
                
                if ( 
$this->memberData['member_id'] || $this->settings['topic_marking_guests'] )
                {
                    
$forum_data['last_topic_title']    = "<a href='" $this->registry->getClass('output')->formatUrl$this->registry->getClass('output')->buildUrl"showtopic={$forum_data['last_id']}&amp;view=getnewpost"'public' ), $forum_data['seo_last_title'], 'showtopic' ) . "' title='{$forum_data['full_last_title']}'>{$forum_data['last_title']}</a>";
                }
                else
                {
                    
$forum_data['last_topic_title']    = "<a href='" $this->registry->getClass('output')->formatUrl$this->registry->getClass('output')->buildUrl"showtopic={$forum_data['last_id']}"'public' ), $forum_data['seo_last_title'], 'showtopic' ) . "' title='{$forum_data['full_last_title']}'>{$forum_data['last_title']}</a>";
                }
            }
        }
        
        
$forum_data['posts']    = $this->registry->getClass('class_localization')->formatNumber$forum_data['posts'] );
        
$forum_data['topics']    = $this->registry->getClass('class_localization')->formatNumber$forum_data['topics'] );
        
        if ( 
$this->settings['disable_subforum_show'] == AND $show_subforums == )
        {
            if ( isset(
$forum_data['subforums']) and is_array$forum_data['subforums'] ) and count$forum_data['subforums'] ) )
            {
                
$forum_data['show_subforums'] = 1;
                
                
/* Rock star programming yo */
                
$lastSubForum array_pop$forum_data['subforums'] );
                
$lastSubForum[4] = 1;
                
                
$forum_data['subforums'][ $lastSubForum['id'] ] = $lastSubForum;
            }
        }
        
        
$_mod    = ( isset( $this->_memberData['forumsModeratorData'] ) ) ? $this->_memberData['forumsModeratorData'] : array();
        
        if ( 
$this->_memberData['g_is_supmod'] or !empty($_mod$forum_data['id'] ]['post_q']) )
        {
            if ( 
$forum_data['queued_posts'] or $forum_data['queued_topics'] )
            {
                
$forum_data['_has_queued_and_can_see_icon']    = 1;
                
$forum_data['queued_posts']                    = intval($forum_data['queued_posts']);
                
$forum_data['queued_topics']                = intval($forum_data['queued_topics']);
            }
        }
        
        return 
$forum_data;
    }
    
    
/**
     * Generate the appropriate folder icon for a forum
     *
     * @param    array     $forum_data
     * @return    string
     */
    
public function forumsNewPosts$forum_data )
    {
        
$sub 0;
        
        if ( isset(
$forum_data['subforums']) AND count($forum_data['subforums']) )
        {
            
$sub 1;
        }

        
//-----------------------------------------
        // Sub forum?
        //-----------------------------------------
        
        
if ($sub ==  0)
        {
            
$sub_cat_img '';
        }
        else
        {
            
$sub_cat_img '_cat';
        }
        
        if ( isset(
$forum_data['password']) AND $forum_data['password'] != '' AND $sub == )
        {
            return 
$forum_data['_has_unread'] ? "f_pass_unread" "f_pass_read";
        }
        
        return 
$forum_data['_has_unread'] ? "f".$sub_cat_img."_unread" "f".$sub_cat_img."_read";
    }
    
    
/**
     * Locate the category of any forum
     *
     * @param    int        Forum ID
     * @return    int        Category ID (root forum ID)
     */
    
public function fetchTopParentID$forumID )
    {
        
$ids $this->forumsGetParents$forumID );
    
        return 
array_pop$ids );
    }
    
    
/**
     * Generate the appropriate folder icon for a topic
     *
     * @param    array    Topic data array
     * @param    string    Dot flag
     * @param    bool    Whether item is read or not
     * @return    array
     */
    
public function fetchTopicFolderIcon$topic$dot=""$is_read=false )
    {
        return array(
                    
'is_read'        => $is_read,
                    
'is_closed'        => ( $topic['state'] == 'closed' OR $this->registry->getClass('class_forums')->fetchHiddenTopicType$topic ) == 'sdelete' ) ? true false,
                    
'is_poll'        => $topic['poll_state'] ? true false,
                    
'show_dot'        => $dot,
                    
'is_moved'        => ( $topic['state'] == 'moved' or $topic['state'] == 'link' ) ? true false,
                    
'is_hot'        => ( $topic['posts'] + >= $this->settings['hot_topic'] ) ? true false,
                    );
    }
    
    
/**
     * Build <select> jump menu
     * $html = 0 means don't return the select html stuff
     * $html = 1 means return the jump menu with select and option stuff
     *
     * @param    integer    HTML flag (see above)
     * @param    integer    Override flag
     * @param    integer
     * @return    string    Parsed HTML
     */
    
public function buildForumJump$html=1$override=0$remove_redirects=0$selected = array() )
    {
        
$the_html    $this->forumsForumJump$html$override$remove_redirects$selected );
        
        if( 
$html )
        {
            
$the_html    $this->registry->getClass('output')->getTemplate('global')->forum_jump$the_html );
        }

        return 
$the_html;
    }
    
    
/**
     * Determine if this user / forum combo can manage mod queue
     *
     * @param    integer    Forum ID
     * @return    integer Boolean
     */
    
public function canQueuePosts$fid=)
    {
        
$return 0;
        
$_mod   $this->_memberData['forumsModeratorData'];
        
        if ( 
$this->_memberData['g_is_supmod'] )
        {
            
$return 1;
        }
        else if ( 
$fid AND $this->_memberData['is_mod'] AND !empty($_mod$fid ]['post_q']) )
        {
            
$return 1;
        }
        
        return 
$return;
    }
    
    
/**
     * Determine if this user / forum combo can soft delete
     *
     * @param    integer    Forum ID
     * @param    array    Post information
     * @return    integer Boolean
     */
    
public function canSoftDeletePosts$fid=0$post )
    {
        if ( 
$fid and $this->_memberData['is_mod'] and !empty( $this->_memberData['forumsModeratorData'][ $fid ]['bw_mod_soft_delete'] ) )
        {
            return 
TRUE;
        }
        else
        {
            return 
IPSMember::canModerateContent$this->_memberDataIPSMember::CONTENT_HIDE$post['author_id'] );
        }
    }
    
    
/**
     * Determine if this user / forum combo can hard delete
     *
     * @param    integer    Forum ID
     * @param    array    Post information
     * @return    integer Boolean
     */
    
public function canHardDeletePosts$fid=0$post )
    {
        if ( 
$fid and $this->_memberData['is_mod'] and !empty( $this->_memberData['forumsModeratorData'][ $fid ]['delete_post'] ) )
        {
            return 
TRUE;
        }
        else
        {
            return 
IPSMember::canModerateContent$this->_memberDataIPSMember::CONTENT_DELETE$post['author_id'] );
        }
    }
    
    
/**
     * Determine if this user / forum combo can un soft delete
     *
     * @param    integer    Forum ID
     * @return    integer Boolean
     */
    
public function can_Un_SoftDeletePosts$fid=)
    {
        if ( 
$fid and $this->_memberData['is_mod'] and !empty( $this->_memberData['forumsModeratorData'][ $fid ]['bw_mod_un_soft_delete'] ) )
        {
            return 
TRUE;
        }
        else
        {
            return 
IPSMember::canModerateContent$this->_memberDataIPSMember::CONTENT_UNHIDE );
        }
    }

    
    
/**
     * Determine if this user / forum combo can see soft deleted posts
     *
     * @param    integer    Forum ID
     * @return    integer Boolean
     */
    
public function canSeeSoftDeletedPosts$fid=)
    {
        if ( 
$this->_memberData['g_is_supmod'] or ( $fid and $this->_memberData['is_mod'] and !empty( $this->_memberData['forumsModeratorData'][ $fid ]['bw_mod_soft_delete_see'] ) ) )
        {
            return 
TRUE;
        }
        
        return 
FALSE;
    }
    
    
/**
     * Determine if this user / forum combo can soft delete
     *
     * @param    array    Topic Data
     * @return    integer Boolean
     */
    
public function canSoftDeleteTopics$fid$topic=array() )
    {
        if ( 
$fid and $this->_memberData['is_mod'] and !empty( $this->_memberData['forumsModeratorData'][ $fid ]['bw_mod_soft_delete'] ) )
        {
            return 
TRUE;
        }
        else
        {
            return 
IPSMember::canModerateContent$this->_memberDataIPSMember::CONTENT_HIDE$topic['starter_id'] );
        }
    }
    
    
/**
     * Determine if this user / forum combo can un soft delete
     *
     * @param    integer    Forum ID
     * @return    integer Boolean
     *
     * @deprecated
     */
    
public function can_Un_SoftDeleteTopics$fid=)
    {
        return 
$this->can_Un_SoftDeletePosts$fid );
    }
    
    
/**
     * Determine if this user / forum combo can hard delete
     *
     * @param    integer    Forum ID
     * @param    array    Topic information
     * @return    integer Boolean
     */
    
public function canHardDeleteTopics$fid=0$topic )
    {
        if ( 
$fid and $this->_memberData['is_mod'] and !empty( $this->_memberData['forumsModeratorData'][ $fid ]['delete_topic'] ) )
        {
            return 
TRUE;
        }
        elseif ( 
$topic['starter_id'] == $this->_memberData['member_id'] and $this->_memberData['g_delete_own_topics'] )
        {
            return 
TRUE;
        }
        else
        {
            return 
IPSMember::canModerateContent$this->_memberDataIPSMember::CONTENT_DELETE$topic['starter_id'] );
        }
    }
    
    
/**
     * Determine if this user / forum combo can see soft deleted posts
     *
     * @param    integer    Forum ID
     * @return    integer Boolean
     *
     * @deprecated
     */
    
public function canSeeSoftDeletedTopics$fid=)
    {
        return 
$this->canSeeSoftDeletedPosts$fid );
    }
    
    
/**
     * Determine if this user / forum combo can see soft delete reason
     *
     * @param    integer    Forum ID
     * @return    integer Boolean
     *
     * @deprecated
     */
    
public function canSeeSoftDeleteReason$fid=)
    {
        return 
$this->canSeeSoftDeletedPosts$fid );
    }
    
    
/**
     * Determine if this user / forum combo can soft delete
     *
     * @param    integer    Forum ID
     * @return    integer Boolean
     *
     * @deprecated
     */
    
public function canSeeSoftDeleteContent$fid=)
    {
        return 
$this->canSeeSoftDeletedPosts$fid );
    }
    
    
/**
     * Post queue type
     *
     * @param    array        Post data
     * @return    string        'visible', 'hidden' or 'sdelete'
     */
    
public function fetchHiddenType$post )
    {
        if ( isset( 
$post['queued'] ) )
        {
            switch ( 
intval$post['queued'] ) )
            {
                case 
4:
                    return 
'oktoremove';
                break;
                case 
3:
                    return 
'pdelete';
                break;
                case 
2:
                    return 
'sdelete';
                break;
                case 
1:
                    return 
'hidden';
                break;
                case 
0:
                    return 
'visible';
                break;
            }
        }
        
        return 
'visible';
    }
    
    
/**
     * Fetch correct flag
     * Pass several or one field through ->fetchPostHiddenQuery( array('hidden', 'sdelete' ) );
     *
     * @param    array        Type: 'sdelete', 'hidden', 'visible', 'notVisible' (notVisible can mean either sDelete or hidden)
     * @return    string
     * @todo    "notVisible" is not relevant here = we should remove it as an option.  It can mean hidden OR soft deleted, but both can't be returned.
     */
    
public function fetchPostHiddenFlag$type )
    {
        
$value  0;
        
        switch( 
$type )
        {
            case 
'oktoremove':
                
$value 4;
            break;
            case 
'pdeleted':
            case 
'pdelete':
                
$value 3;
            break;
            case 
'sdeleted':
            case 
'sdelete':
            case 
'notVisible':
                
$value 2;
            break;
            case 
'queued':
            case 
'hidden':
                
$value 1;
            break;
            case 
'approved':
            case 
'visible':
                
$value 0;
            break;
        }
        
        return 
$value;
    }
    
    
/**
     * Fetch correct fields and data
     * Pass several or one field through ->fetchPostHiddenQuery( array('hidden', 'sdelete' ) );
     *
     * @param    array        Type: 'sdelete', 'hidden', 'visible', 'notVisible' (notVisible can mean either sDelete or hidden)
     * @param    string        Table prefix (t.)
     * @return    string
     */
    
public function fetchPostHiddenQuery$type$tPrefix='' )
    {
        
$type   = ( is_array$type ) ) ? $type : array( $type );
        
$values = array();
        
        foreach( 
$type as $_t )
        {
            switch( 
$_t )
            {
                case 
'oktoremove':
                    
$values[] = 4;
                break;
                case 
'pdeleted':
                case 
'pdelete':
                    
$values[] = 3;
                break;
                case 
'sdeleted':
                case 
'sdelete':
                    
$values[] = 2;
                break;
                case 
'queued':
                case 
'hidden':
                    
$values[] = 1;
                break;
                case 
'approved':
                case 
'visible':
                    
$values[] = 0;
                break;
                
                case 
'notVisible':
                    
$values[] = 1;
                    
$values[] = 2;
                break;
            }
        }
        
        if ( 
count$values ) )
        {
            if ( 
count$values ) == )
            {
                return 
' ' $tPrefix 'queued=' $values[0] . ' ';
            }
            else
            {
                return 
' ' $tPrefix 'queued IN (' implode','$values ) . ') ';
            }
        }
        
        
/* oops, return something to not break the query */
        
return '1=1';
    }
    
    
/**
     * Topic queue type
     *
     * @param    array        Post data
     * @return    string        'visible', 'hidden' or 'sdelete'
     */
    
public function fetchHiddenTopicType$topic )
    {
        if ( isset( 
$topic['approved'] ) )
        {
            switch ( 
intval$topic['approved'] ) )
            {
                case -
1:
                    return 
'sdelete';
                break;
                case 
0:
                    return 
'hidden';
                break;
                case 
1:
                    return 
'visible';
                break;
                case 
3:
                    return 
'oktoremove';
                break;
                case 
2:
                    return 
'pdelete';
                break;
            }
        }
        
        return 
'visible';
    }
    
    
/**
     * Fetch correct flag
     * Pass several or one field through ->fetchTopicHiddenFlag( array('hidden', 'sdelete' ) );
     *
     * @param    array        Type: 'sdelete', 'hidden', 'visible', 'notVisible' (notVisible can mean either sDelete or hidden)
     * @return    string
     */
    
public function fetchTopicHiddenFlag$type )
    {
        
$value  1;
        
        switch( 
$type )
        {
            case 
'sdeleted':
            case 
'sdelete':
                
$value = -1;
            break;
            case 
'queued':
            case 
'hidden':
                
$value 0;
            break;
            case 
'approved':
            case 
'visible':
                
$value 1;
            break;
            case 
'pdelete':
            case 
'pdeleted':
                
$value 2;
            break;
            case 
'oktoremove':
                
$value 3;
            break;
        }
        
        return 
$value;
    }
    
    
/**
     * Fetch correct fields and data
     * Pass several or one field through ->fetchPostHiddenQuery( array('hidden', 'sdelete' ) );
     *
     * @param    array        Type: 'sdelete', 'hidden', 'visible', 'notVisible' (notVisible can mean either sDelete or hidden)
     * @param    string        Table prefix (t.)
     * @return    string
     */
    
public function fetchTopicHiddenQuery$type$tPrefix='' )
    {
        
$type   = ( is_array$type ) ) ? $type : array( $type );
        
$values = array();
        
        if ( 
in_array'all'$type ) )
        {
            return 
'1=1';
        }
        
        foreach( 
$type as $_t )
        {
            switch( 
$_t )
            {
                case 
'sdeleted':
                case 
'sdelete':
                    
$values[] = -1;
                break;
                case 
'queued':
                case 
'hidden':
                    
$values[] = 0;
                break;
                case 
'approved':
                case 
'visible':
                    
$values[] = 1;
                break;
                case 
'pdelete':
                case 
'pdeleted':
                    
$values[] = 2;
                break;
                case 
'oktoremove':
                    
$values[] = 3;
                break;
            }
        }
        
        if ( 
count$values ) )
        {
            if ( 
count$values ) == )
            {
                return 
' ' $tPrefix 'approved=' $values[0] . ' ';
            }
            else
            {
                return 
' ' $tPrefix 'approved IN (' implode','$values ) . ') ';
            }
        }
        
        
/* oops, return something to not break the query */
        
return '1=1';
    }
    
    
/**
     * Fetch correct fields and data
     *
     * @param    array        Type: 'not', 'archived', 'working', 'exclude'
     * @param    string        Table prefix (t.)
     * @return    string
     */
    
public function fetchTopicArchiveQuery$type$tPrefix='' )
    {
        
$type   = ( is_array$type ) ) ? $type : array( $type );
        
$values = array();
        
        foreach( 
$type as $_t )
        {
            switch( 
$_t )
            {
                case 
'not':
                    
$values[] = 0;
                break;
                case 
'archived':
                    
$values[] = 1;
                break;
                case 
'working':
                    
$values[] = 2;
                break;
                case 
'exclude':
                    
$values[] = 3;
                break;
                case 
'restore':
                    
$values[] = 4;
                break;
            }
        }
        
        if ( 
count$values ) )
        {
            if ( 
count$values ) == )
            {
                return 
' ' $tPrefix 'topic_archive_status=' $values[0] . ' ';
            }
            else
            {
                return 
' ' $tPrefix 'topic_archive_status IN (' implode','$values ) . ') ';
            }
        }
        
        
/* oops, return something to not break the query */
        
return '1=1';
    }
    
    
/**
     * Fetch correct flag
     * Pass several or one field through ->fetchTopicHiddenFlag( array('not', 'archived', 'working', 'exclude' ) );
     *
     * @param    string
     * @return    integer
     */
    
public function fetchTopicArchiveFlag$type )
    {
        
$value  0;
        
        switch( 
$type )
        {
            case 
'not':
                
$value 0;
            break;
            case 
'archived':
                
$value 1;
            break;
            case 
'working':
                
$value 2;
            break;
            case 
'exclude':
                
$value 3;
            break;
            case 
'restore':
                
$value 4;
            break;
        }
        
        return 
$value;
    }
    
    
/**
     * Topic archive status
     *
     * @param    array        Topic data
     * @return    string        not, archived, working, exclude
     */
    
public function fetchArchiveTopicType$topic )
    {
        if ( isset( 
$topic['topic_archive_status'] ) )
        {
            switch ( 
intval$topic['topic_archive_status'] ) )
            {
                default:
                case 
0:
                    return 
'not';
                break;
                case 
1:
                    return 
'archived';
                break;
                case 
2:
                    return 
'working';
                break;
                case 
3:
                    return 
'exclude';
                break;
                case 
4:
                    return 
'restore';
                break;
            }
        }
        
        return 
'not';
    }
    
    
/**
     * Determine if this user / forum combo can manage multi moderation tasks
     * and return mm_array of allowed tasks
     *
     * @param    integer    Forum ID
     * @return    array    Allowed tasks
     */
    
public function getMultimod$fid )
    {
        
$mm_array = array();
        
$_mod     $this->_memberData['forumsModeratorData'];
        
$pass_go  FALSE;
        
        if ( 
$this->_memberData['member_id'] )
        {
            if ( 
$this->_memberData['g_is_supmod'] )
            {
                
$pass_go TRUE;
            }
            else if ( !empty(
$_mod$fid ]['can_mm']) )
            {
                
$pass_go TRUE;
            }
        }
        
        if ( 
$pass_go != TRUE )
        {
            return 
$mm_array;
        }
        
        if ( ! 
is_array$this->caches['multimod'] ) )
        {
            
$cache = array();
            
            
$this->DB->build( array( 'select' => '*''from' => 'topic_mmod''order' => 'mm_title' ) );
            
$this->DB->execute();
                        
            while (
$i $this->DB->fetch())
            {
                
$cache$i['mm_id'] ] = $i;
            }
            
            
$this->cache->setCache'multimod'$cache,  array( 'array' => ) );
        }
        
        
//-----------------------------------------
        // Get the topic mod thingies
        //-----------------------------------------
        
        
if( count$this->caches['multimod'] ) AND is_array$this->caches['multimod'] ) )
        {
            foreach( 
$this->caches['multimod'] as $r )
            {
                if ( 
$r['mm_forums'] == '*' OR strstr",".$r['mm_forums'].","",".$fid."," ) )
                {
                    
$mm_array[] = array( $r['mm_id'], $r['mm_title'] );
                }
            }
        }
        
        return 
$mm_array;
    }

    
/**
     * Fetch forum IDs safe to use when searching, etc
     *
     * @param    int            Optional member ID, if no member ID is passed, it'll use current member
     * @param    array        Array of ids to skip
     * @param    bool        Return categories too
     * @return    array        Array of "good" IDs
     */
    
public function fetchSearchableForumIds$memberId=null$skipIds=array(), $returnCategories=false )
    {
        
$forumIdsOk = array();
        
$member     = ( $memberId === null || $memberId == $this->_memberData['member_id'] ) ? $this->_memberData IPSMember::load$memberId'core' );
        
$posts         intval$member['posts'] );
        
        
/* Ensure this has been set up */
        
if ( ! is_array$this->forum_by_id ) OR ! count$this->forum_by_id ) )
        {
            
$this->strip_invisible 1;
            
$this->forumsInit();
        }

        
/* Get list of good forum IDs */
        
foreach( $this->forum_by_id as $id => $data )
        {
            
/* Can we read? */
            
if ( ! $this->registry->permissions->check'view'$data ) )
            {
                continue;
            }

            
/* Can we read, or is this a category? */
            
if( ! $returnCategories AND ! $this->registry->permissions->check'read'$data ) )
            {
                continue;
            }
            else if( 
$returnCategories AND ! $data['parent_id'] AND ! $this->registry->permissions->check'read'$data ) )
            {
                continue;
            }
            
            
/* Can read, but is it password protected, etc? */
            
if ( ! $this->forumsCheckAccess$id0'forum', array(), true ) )
            {
                continue;
            }
                                    
            if ( ( ! 
$data['sub_can_post'] OR ! $data['can_view_others'] ) AND !$this->memberData['g_is_supmod'] AND !isset( $this->memberData['forumsModeratorData'][ $id ] ) )
            {
                continue;
            }
            
            if ( 
$data['min_posts_view'] > $posts AND !$member['g_is_supmod'] )
            {
                continue;
            }

            if ( 
is_array$skipIds ) AND count$skipIds ) )
            {
                if ( 
in_array$id$skipIds ) )
                {
                    continue;
                }
            }
            
            
$forumIdsOk[] = $id;
        }
        
        return 
$forumIdsOk;
    }
    
    
/**
     * Rebuild a forum's count
     *
     * @return    boolean
     */
    
public function forumRebuild$fid )
    {
        
$fid intval($fid);
        
        if ( ! 
$fid )
        {
            return 
false;
        }
        
        
/* Topics */
        
$topics            $this->DB->buildAndFetch( array( 'select'    => 'COUNT(*) as count',
                                                           
'from'    => 'topics',
                                                           
'where'    => $this->fetchTopicArchiveQuery( array( 'not''exclude' ) ) . ' AND ' $this->fetchTopicHiddenQuery( array( 'visible' ), '' ) . " and forum_id={$fid}) );

        
/* Queued topics */
        
$queued_topics    $this->DB->buildAndFetch( array( 'select'    => 'COUNT(*) as count',
                                                           
'from'    => 'topics',
                                                           
'where'    => $this->fetchTopicArchiveQuery( array( 'not''exclude' ) ) . ' AND ' $this->fetchTopicHiddenQuery( array( 'hidden' ), '' ) . " and forum_id={$fid}) );
                                                                    
        
/* Deleted topics */
        
$deleted_topics    $this->DB->buildAndFetch( array( 'select'    => 'COUNT(*) as count',
                                                           
'from'    => 'topics',
                                                           
'where'    => $this->fetchTopicArchiveQuery( array( 'not''exclude' ) ) . ' AND ' $this->fetchTopicHiddenQuery( array( 'sdeleted' ), '' ) . " and forum_id={$fid}) );
        
        
/* Archived topics */
        
$archived_topics    $this->DB->buildAndFetch( array( 'select'    => 'COUNT(*) as count',
                                                               
'from'    => 'topics',
                                                               
'where'    => $this->fetchTopicArchiveQuery( array( 'archived''working' ) ) . " and forum_id={$fid}) );
        
        
/* Posts */
        
$posts            $this->DB->buildAndFetch( array( 'select'    => 'SUM(posts) as replies',
                                                           
'from'    => 'topics',
                                                           
'where'    => $this->fetchTopicArchiveQuery( array( 'not''exclude' ) ) . ' AND ' $this->fetchTopicHiddenQuery( array( 'visible' ), '' ) . " and forum_id={$fid}) );
        
        
/* Queued posts */
        
$queued_posts    $this->DB->buildAndFetch( array( 'select'    => 'SUM(topic_queuedposts) as replies',
                                                           
'from'    => 'topics',
                                                           
'where'    => $this->fetchTopicArchiveQuery( array( 'not''exclude' ) ) . ' AND ' $this->fetchTopicHiddenQuery( array( 'visible''hidden' ), '' ) . " and forum_id={$fid}) );
        
        
/* Deleted posts */
        
$deleted_posts    $this->DB->buildAndFetch( array( 'select'    => 'SUM(topic_deleted_posts) as replies',
                                                           
'from'    => 'topics',
                                                           
'where'    => $this->fetchTopicArchiveQuery( array( 'not''exclude' ) ) . ' AND ' "forum_id={$fid}) );
        
        
/* Archived posts */
        
$archived_posts    $this->DB->buildAndFetch( array( 'select'    => 'SUM(posts) as replies',
                                                           
'from'    => 'topics',
                                                           
'where'    => $this->fetchTopicArchiveQuery( array( 'archived''working' ) ) . " and forum_id={$fid}) );
        
        
/* Last poster */
        
$last_post        $this->DB->buildAndFetch( array( 'select'    => 'tid, title, last_poster_id, last_poster_name, seo_last_name, last_post',
                                                           
'from'    => 'topics',
                                                           
'where'    => $this->fetchTopicHiddenQuery( array( 'visible' ), '' ) . " and forum_id={$fid}" AND state != 'link'",
                                                           
'order'    => 'last_post DESC',
                                                           
'limit'    => array( ) ) );
        
        
/* Newest topic */
        
$newest_topic    $this->DB->buildAndFetch( array( 'select'    => 'title, tid, seo_first_name',
                                                           
'from'    => 'topics',
                                                           
'where'    => 'forum_id=' $fid ' and ' $this->fetchTopicHiddenQuery( array( 'visible' ), '' ) . " AND state != 'link'",
                                                           
'order'    => 'start_date desc',
                                                           
'limit'    => array( ) ) );
        
        
/* Rebuild last topics */
        
$lastXTopics    $this->lastXFreeze$this->buildLastXTopicIds$fidFALSE ) );
        
        
/* Save */
        
$dbs = array( 'name_seo'            => IPSText::makeSeoTitle$this->allForums$fid ]['name'] ),
                      
'last_poster_id'        => intval($last_post['last_poster_id']),
                      
'last_poster_name'    => $last_post['last_poster_name'],
                      
'seo_last_name'       => IPSText::makeSeoTitle$last_post['last_poster_name'] ),
                      
'last_post'            => intval($last_post['last_post']),
                      
'last_title'            => $last_post['title'],
                      
'seo_last_title'      => IPSText::makeSeoTitle$last_post['title'] ),
                      
'last_id'                => intval($last_post['tid']),
                      
'topics'                => intval($topics['count']) + intval($archived_topics['count']),
                      
'posts'                => intval($posts['replies']) + intval($archived_posts['replies']),
                      
'queued_topics'        => intval($queued_topics['count']),
                      
'queued_posts'        => intval($queued_posts['replies']),
                      
'deleted_posts'        => intval($deleted_posts['replies']),
                      
'archived_topics'        => intval($archived_topics['count']),
                      
'archived_posts'        => intval($archived_posts['replies']),
                      
'deleted_topics'        => intval($deleted_topics['count']),
                      
'newest_id'            => intval($newest_topic['tid']),
                      
'newest_title'        => $newest_topic['title'],
                      
'last_x_topic_ids'    => $lastXTopics );
                    
        if ( 
$this->allForums$fid ]['_update_deletion'] )
        {
            
$dbs['forum_last_deletion'] = time();
        }
        
        
$this->DB->setDataType( array( 'last_poster_name''last_title''newest_title''seo_last_title''seo_last_name' ), 'string' );

        
$this->DB->update'forums'$dbs"id=" $fid );

        return 
true;
    }
    
/**
     * Determine if user can still access forum
     *
     * @param    array         Topic/member/forum data
     * @param    boolean        Check topic access
     * @return    boolean
     */
    
public function checkEmailAccess$t$checkTopic=true )
    {
        
//-----------------------------------------
        // Test for group permissions
        //-----------------------------------------
        
        
$member_groups    = array( $t['member_group_id'] );
        
$mgroup_others    "";
        
$temp_mgroups    = array();
        
$mgroup_perms    = array();
        
        
$t['mgroup_others']    = IPSText::cleanPermString$t['mgroup_others'] );
        
        if( 
$t['mgroup_others'] )
        {
            
$temp_mgroups        explode","$t['mgroup_others'] );
            
            if( 
count($temp_mgroups) )
            {
                foreach( 
$temp_mgroups as $other_mgroup )
                {
                    
/* Does it exist? */
                    
if ( $this->caches['group_cache'][ $other_mgroup ]['g_perm_id'] )
                    {
                        
$member_groups[]    = $other_mgroup;
                        
$mgroup_perms[]        = $this->caches['group_cache'][ $other_mgroup ]['g_perm_id'];
                    }
                }
            }
            
            if( 
count($mgroup_perms) )
            {
                
$mgroup_others "," implode","$mgroup_perms ) . ",";
            }
        }

        
$perm_id = ( $t['org_perm_id'] ) ? $t['org_perm_id'] : $this->caches['group_cache'][ $t['member_group_id'] ]['g_perm_id'] . $mgroup_others;

        
//-----------------------------------------
        // Can they view forum?
        //-----------------------------------------

        
if ( $this->registry->permissions->check'view'$this->allForums$t['forum_id'] ], explode','$perm_id ) ) !== TRUE )
        {
            return 
false;
        }

        
//-----------------------------------------
        // Can they read topics in the forum?
        //-----------------------------------------
        
        
if ( $this->registry->permissions->check'read'$this->allForums$t['forum_id'] ], explode','$perm_id ) ) !== TRUE )
        {
            return 
false;
        }
        
        
//-----------------------------------------
        // Can view others topics
        //-----------------------------------------
        
        
if( $checkTopic )
        {
            
$canViewOthers    false;
            
$t                IPSMember::setUpModerator$t );
            
            foreach( 
$member_groups as $mgroup )
            {
                if( 
$this->caches['group_cache'][ $mgroup ]['g_other_topics'] )
                {
                    
$canViewOthers    true;
                }
            }
            
            if( ! 
$canViewOthers AND $t['starter_id'] != $t['member_id'] )
            {
                return 
false;
            }
            else if( !
$this->allForums$t['forum_id'] ]['can_view_others'] AND $t['starter_id'] != $t['member_id'] AND !$t['is_mod'] )
            {
                return 
false;
            }
        }
        
        
//-----------------------------------------
        // Minimum posts to view
        //-----------------------------------------
        
        
if( $this->allForums$t['forum_id'] ]['min_posts_view'] && $this->allForums$t['forum_id'] ]['min_posts_view'] > $t['posts'] && !$t['g_is_supmod'] )
        {
            return 
false;
        }
        
        
//-----------------------------------------
        // Banned?
        //-----------------------------------------
        
        
if( $t['member_banned'] )
        {
            return 
false;
        }
        
        
$_canView    false;
        
        foreach( 
$member_groups as $mgroup )
        {
            if( 
$this->caches['group_cache'][ $mgroup ]['g_view_board'] )
            {
                
$_canView    true;
                break;
            }
        }
        
        return 
$_canView;
    }
    
    
/**
     * Determine if topic is approved (or if they are a mod)
     *
     * @param    array         Topic/member/forum data
     * @return    boolean
     */
    
public function checkEmailApproved$t )
    {
        
$t['mgroup_others']    = IPSText::cleanPermString$t['mgroup_others'] );
        
        
//-----------------------------------------
        // Test for approved/approve perms
        //-----------------------------------------
        
        
if( $t['approved'] > )
        {
            return 
false;
        }

        if( 
$t['approved'] == )
        {
            
$mod false;
            
            
$memberGroups = array( $t['member_group_id'] );
            
            if( 
$t['mgroup_others'] )
            {
                
$memberGroups array_merge$memberGroupsexplode","IPSText::cleanPermString$t['mgroup_others'] ) ) );
            }
            
            foreach( 
$memberGroups as $groupId )
            {
                if( 
$this->caches['group_cache'][ $groupId ]['g_is_supmod'] == )
                {
                    
$mod true;
                    break;
                }
            }
            
            if( !
$mod )
            {
                if ( 
count($this->cache->getCache('moderators')) )
                {
                    
$other_mgroups = array();
                    
                    if( 
$t['mgroup_others'] )
                    {
                        
$other_mgroups explode","IPSText::cleanPermString$t['mgroup_others'] ) );
                    }
                    
                    foreach( 
$this->cache->getCache('moderators') as $moderators )
                    {
                        if ( ( 
$moderators['member_id'] AND $moderators['member_id'] == $t['member_id'] ) OR $moderators['group_id'] == $t['member_group_id'] )
                        {
                            if( 
$moderators['forum_id'] == $t['forum_id'] )
                            {
                                
$mod true;
                            }
                        }
                        else if( 
count($other_mgroups) AND in_array$moderators['group_id'], $other_mgroups ) )
                        {
                            if( 
$moderators['forum_id'] == $t['forum_id'] )
                            {
                                
$mod true;
                            }
                        }
                    }
                }
            }
            
            if( !
$mod )
            {
                return 
false;
            }
        }
        
        return 
true;
    }
    
    
/**
     * Does a guest have access to this forum?
     *
     * @param    int            Forum ID
     * @param    int            Override guest group with another (Facebook bot, spider search engine bots)
     * @return    boolean
     * @author    Matt
     */
    
public function guestCanSeeTopic$forumId=0$groupOverride=)
    {
        
$forumId    = ( $forumId ) ? $forumId intval$this->request['f'] );
        
$gid        = ( $groupOverride ) ? $groupOverride $this->settings['guest_group'];
        
$perms        explode','IPSText::cleanPermString$this->caches['group_cache'][ $gid ]['g_perm_id'] ) );

        if ( 
$forumId )
        {
            
$forum $this->forum_by_id$forumId ];
            
            if ( 
strstr$forum['perm_read'], '*' ) )
            {
                return 
true;
            }
            else
            {
                foreach( 
$perms as $_perm )
                {
                    if ( 
strstr',' $forum['perm_read'] . ','',' $_perm ',' ) )
                    {
                        return 
true;
                    }
                }
            }
        }
        
        return 
false;
    }
    
    
/**
     * Recache the user's watched forums
     *
     * @param    int            Member ID
     * @return    boolean
     * @author    Matt
     */
    
public function recacheWatchedForums$memberID )
    {
        
/* INIT */
        
$final        = array();
        
$memberID    intval$memberID );

        
/* Get forums the member follows */
        
require_once( IPS_ROOT_PATH 'sources/classes/like/composite.php' );/*noLibHook*/
        
$_like    classes_like::bootstrap'forums''forums' );
        
$forums    $_like->getDataByMemberIdAndArea$memberID );
        
$forums    is_array($forums) ? array_keys$forums ) : array();
        
        foreach( 
$forums as $forum )
        {
            if ( 
$this->registry->permissions->check'view'$this->forum_by_id$forum ] ) === TRUE )
            {
                
$final[]    = $forum;
            }
        }

        
IPSMember::packMemberCache$memberID, array( 'watchedForums' => $final ) );
        
        return 
TRUE;
    }
    
    
/**
     * Build (and optionally save) the last X topic IDs from a forum
     *
     * @param    int            Forum ID to save
     * @param    boolean        TRUE = SAVE, FALSE = Return Array of IDs
     * @param    int            No. topics to save ( Default is 5 )
     * @return    array         Array of topic IDs 
     */
    
public function buildLastXTopicIds$forumID$save=TRUE$limit=)
    {
        
$ids   = array();
        
$forum $this->forum_by_id$forumID ];
        
        if ( ! 
$forumID )
        {
            return array();
        }
        
        
//-----------------------------------------
        // Make sure this forum has topics...
        // This causes a problem where the first post
        // in a new forum won't get added as latest topic.
        // Didn't want to try to rejig the process as it's
        // fine otherwise, so just commenting this out.
        //-----------------------------------------
        
        /*if ( ! $forum['topics'] )
        {
            return array();
        }*/
        
        //-----------------------------------------
        // Grab the topics
        //-----------------------------------------
        
        
$this->DB->build( array( 'select' => 'tid, start_date',
                                 
'from'   => 'topics',
                                 
'where'  => 'forum_id=' $forumID ' AND ' $this->fetchTopicHiddenQuery( array( 'visible' ), '' ),
                                 
'order'  => 'start_date DESC',
                                 
'limit'  => array( 0$limit ) ) );
        
$o $this->DB->execute();
        
        while( 
$row $this->DB->fetch$o ) )
        {
            
$ids$row['tid'] ] = $row['start_date'];
        }
        
        if ( 
$save === TRUE )
        {
            if ( 
count$ids ) )
            {
                
$this->DB->update'forums', array( 'last_x_topic_ids' => $this->lastXFreeze$ids ) ), 'id=' $forumID );
            }
        }
        
        return 
$ids;
    }
    
    
/**
     * Format last X topics string for saving
     *
     * @param    array         Array of IDs
     * @return    string        Frozen string format
     */
    
public function lastXFreeze$ids=array() )
    {
        return 
serialize$ids );
    }
    
    
/**
     * Format last X topics string for using
     *
     * @param    array         Array of IDs
     * @return    string        Thawed string format
     */
    
public function lastXThaw$idString=array() )
    {
        return 
unserialize$idString );
    }
    
    
/**
     * getHasUnread
     * Get the next unread topic
     * @param int forums ID
     */
    
public function getHasUnread$forumId )
    {
        
$forumData   $this->getForumById$forumId );
        
$lastPost    $forumData['last_post'];
        
        
$latestStamp intval$this->registry->classItemMarking->fetchTimeLastMarked( array('forumID' => $forumId'itemLastUpdate' => $forumData['last_post'] ), 'forums' ) );
        
        return ( 
$latestStamp $lastPost ) ? true false;
    }
    
    
/**
     * Post process VNC tids
     * @param    array    tid => array( tid,forum_id)
     * @return    array    cleaned tids
     */
    
public function postProcessVncTids$rtids$limit=array(), $maxHit=1000 )
    {
        
$fCache = array( 'marked' => array(), 'lastStamp' => array() );
        
$tids   = array();
        
        if ( ! 
is_array$rtids ) OR ! count$rtids ) )
        {
            return array();
        }
        
        foreach( 
$rtids as $tid => $data )
        {
            if ( ! isset( 
$fCache['canView'][ $data['forum_id'] ] ) )
            {
                
$read $this->registry->permissions->check'view'$this->getForumById$data['forum_id'] ) );
                
$view $this->forumsCheckAccess$data['forum_id'], 0'forum', array(), true );
                
                
$fCache['canView'][ $data['forum_id'] ] = ( $read && $view ) ? true false;
            }
            
            
/* Permission to view? */
            
if ( ! $fCache['canView'][ $data['forum_id'] ] )
            {
                continue;
            }        
            
            if ( 
IPSSearchRegistry::get('in.period') == 'unread' )
            {
                
/* Avoid repeated calls to classItemMarking */
                
if ( ! isset( $fCache['marked'][ $data['forum_id'] ] ) )
                {
                    
$fCache['marked'][ $data['forum_id'] ] = intval$this->registry->classItemMarking->fetchTimeLastMarked( array('forumID' => $data['forum_id'], 'itemLastUpdate' => $data['last_post'] ), 'forums' ) );
                }
                
                
/* May as well cache this too */
                
if ( ! isset( $fCache['lastStamp'][ $data['forum_id'] ] ) )
                {
                    
$_f $this->getForumById$data['forum_id'] );
                    
$fCache['lastStamp'][ $data['forum_id'] ] = intval$_f['last_post'] );
                }
                
                
$lastStamp = ( isset( $fCache['lastStamp'][ $data['forum_id'] ] ) ) ? $fCache['lastStamp'][ $data['forum_id'] ] : 0;
                
$lastRead  = ( isset( $fCache['marked'][ $data['forum_id'] ] ) )    ? $fCache['marked'][ $data['forum_id'] ] : 0;
                
                
/* Lets get jiggy, etc */
                
if ( $lastStamp && ( $lastStamp <= $lastRead ) )
                {
                    continue;
                }
                else
                {
                    if ( ! 
$this->registry->classItemMarking->isRead( array('forumID' => $data['forum_id'], 'itemID' => $tid'itemLastUpdate' => $data['last_post'] ), 'forums' ) )
                    {
                        
$tids$tid ] = $tid;
                    }
                }
            }
            else
            {
                
$tids$tid ] = $tid;
            }
        }
    
        
        
/* Count what's left */
        
$count count$tids );
        
        
/* Simulate limit */
        
if ( isset( $limit[0] ) )
        {
            
$tids array_slice$tidsintval$limit[0] ), intval$limit[1] ) );
        }
        
        
/* return */
        
return array( 'count' => $count'tids' => $tids );
    }
    
    
/**
     * Coverts a page number to a start value
     * @param int $page
     */
    
public function pageToSt$page )
    {
        
$page intval$page );
    
        return ( 
$page ) ? ( ( $page ) * $this->settings['display_max_topics'] ) : 0;
    }
    
    
/**
     * Coverts a st value to a page number
     * @param int $page
     */
    
public function stToPage$st )
    {
        
$st intval$st );
    
        return ( 
$st ) ? ( ceil$st $this->settings['display_max_topics'] ) + ) : 1;
    }
    
    
/**
     * Hook: Facebook sidebar block
     *
     * @return    string        HTML
     */
    
public function hooks_facebookActivity()
    {
        return 
$this->registry->output->getTemplate'boards' )->hookFacebookActivity(); 
    }
    
    
/**
     * Hook: Facebook sidebar block
     *
     * @return    string        HTML
     */
    
public function hooks_facebookLike()
    {
        return 
$this->registry->output->getTemplate'topic' )->hookFacebookLike(); 
    }
    
    
/**
     * Hook: Recent topics
     * Moved here so we can update with out requiring global hook changes
     *
     * @param    int        Number of topics
     * @param    bool    Whether to output directly (true) or return array of topics (false)
     * @return    mixed    String if $output is true, array if $output is false
     */
    
public function hooks_recentTopics$topicCount=5$output=true )
    {
        
/* INIT */
        
$topicIDs    = array();
        
$topic_rows = array();
        
$timesUsed    = array();
        
$bvnp       explode','$this->settings['vnp_block_forums'] );
        
        
$this->registry->class_localization->loadLanguageFile( array( 'public_topic''public_forums' ), 'forums' );
        
        
/* Grab last X data */
        
foreach( $this->forum_by_id as $forumID => $forumData )
        {
            if ( ! 
$forumData['can_view_others'] AND ! $this->_memberData['is_mod'] )
            {
                continue;
            }
            
            if ( 
$forumData['password'] != '' )
            {
                continue;
            }
            
            if ( ! 
$this->registry->permissions->check'read'$forumData ) )
            {
                continue;
            }
            
            if ( 
is_array$bvnp ) AND count$bvnp ) )
            {
                if ( 
in_array$forumID$bvnp ) )
                {
                    continue;
                }
            }

            
/* Still here? */
            
$_topics $this->lastXThaw$forumData['last_x_topic_ids'] );
            
            if ( 
is_array$_topics ) )
            {
                foreach( 
$_topics as $id => $time )
                {
                    if( 
in_array$time$timesUsed ) )
                    {
                        while( 
in_array$time$timesUsed ) )
                        {
                            
$time +=1;
                        }
                    }
                    
                    
$timesUsed[]       = $time;
                    
$topicIDs$time ] = $id;
                }
            }
        }
        
        
$timesUsed    = array();
        
        if ( 
is_array$topicIDs ) && count$topicIDs ) )
        {
            
krsort$topicIDs );
            
            
/* We get up to double in case some of the latest are moved_to links - we do another array_slice afterwards to limit to right limit */
            
$_topics    array_slice$topicIDs0$topicCount );
            
            if ( 
is_array$_topics ) && count$_topics ) )
            {
                
/* Query Topics */
                
$this->registry->DB()->build( array( 
                                                        
'select'   => 't.tid, t.title as topic_title, t.title_seo, t.start_date, t.starter_id, t.starter_name, t.moved_to, t.views, t.posts, t.topic_answered_pid',
                                                        
'from'     => array( 'topics' => 't' ),
                                                        
'where'    => 't.tid IN (' implode','array_values$_topics ) ) . ')',
                                                        
'add_join' => array(
                                                                            array(
                                                                                    
'select'    => 'm.*',
                                                                                    
'from'        => array( 'members' => 'm' ),
                                                                                    
'where'        => 'm.member_id=t.starter_id',
                                                                                    
'type'        => 'left',
                                                                                ),
                                                                            array(
                                                                                    
'select'    => 'pp.*',
                                                                                    
'from'        => array( 'profile_portal' => 'pp' ),
                                                                                    
'where'        => 'm.member_id=pp.pp_member_id',
                                                                                    
'type'        => 'left',
                                                                                ),
                                                                        )
                                            )     );

                
$outer $this->registry->DB()->execute();

                while( 
$r $this->registry->DB()->fetch$outer ) )
                {
                    if( !empty(
$r['moved_to']) )
                    {
                        continue;
                    }

                    
$time    $r['start_date'];
                    
                    if( 
in_array$time$timesUsed ) )
                    {
                        while( 
in_array$time$timesUsed ) )
                        {
                            
$time +=1;
                        }
                    }
                    
                    
$timesUsed[]          = $time;
                    
$topics_rows$time ] = IPSMember::buildDisplayData$r );
                }
                
                
/* Got any results? */
                
if ( count($topics_rows) )
                {
                    
krsort$topics_rows );
                    
$topics_rows array_slice$topics_rows0$topicCount );
                }
            }
        }
        
        if( 
$output )
        {
            return 
$this->registry->output->getTemplate('boards')->hookRecentTopics$topics_rows );
        }
        else
        {
            return 
$topics_rows;
        }
    }
}
Онлайн: 0
Реклама