Файл: admin/sources/classes/tiers/recursiveTiers.php
Строк: 339
<?php
/**
 * <pre>
 * Invision Power Services
 * IP.Board v3.3.3
 * Recurse Tier Management
 * Owner: Matt Mecham
 * Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
 * </pre>
 *
 * @author         $Author: bfarber $
 * @copyright    (c) 2001 - 2009 Invision Power Services, Inc.
 * @license        http://www.invisionpower.com/company/standards.php#license
 * @package        IP.Board
 * @link        http://www.invisionpower.com
 * @since        9th March 2005 11:03
 * @version        $Revision: 10721 $
 */
class recursiveTiers
{
    /**
     * Registry object
     *
     * @access    protected
     * @var        object
     */    
    protected $registry;
    
    /**
     * Database object
     *
     * @access    protected
     * @var        object
     */    
    protected $DB;
    
    /**
     * Settings object
     *
     * @access    protected
     * @var        object
     */    
    protected $settings;
    
    /**
     * Request object
     *
     * @access    protected
     * @var        object
     */    
    protected $request;
    
    /**
     * Language object
     *
     * @access    protected
     * @var        object
     */    
    protected $lang;
    
    /**
     * Member object
     *
     * @access    protected
     * @var        object
     */    
    protected $member;
    protected $memberData;
    
    /**
     * Cache object
     *
     * @access    protected
     * @var        object
     */    
    protected $cache;
    protected $caches;
    
    /**
     * Item Cache
     *
     * @access    protected
     * @var        array
     */
    protected $_itemCache = array();
    
    /**
     * Item By ID
     *
     * @access    protected
     * @var        array
     */
    protected $_itemByID = array();
    
    /**
     * FIELD: item ID
     *
     * @access    protected
     * @var        string
     */
    protected $_sqlPrimaryID  = '';
    
    /**
     * FIELD: parent ID
     *
     * @access    protected
     * @var        string
     */
    protected $_sqlParentID = '';
    
    /**
     * FIELD: Is folder flag
     *
     * @access    protected
     * @var        string
     */
    protected $_sqlFolderFlag = '';
    
    /**
     * FIELD: Item name field
     *
     * @access    protected
     * @var        string
     */
    protected $_sqlTitle     = '';
    
    /**
     * FIELD: Order on field
     *
     * @access    protected
     * @var        string
     */
    protected $_sqlOrder     = '';
    
    /**
     * SQL Field: From
     *
     * @access    protected
     * @var        string
     */
    protected $_sqlTable        = '';
    
    /**
     * SQL Fields: Additional 'where' information
     *
     * @access    protected
     * @var        string
     */
    protected $_sqlWhere       = '';
    
    /**
     * SQL Fields: Select information
     *
     * @access    protected
     * @var        string
     */
    protected $_sqlSelect       = '*';
    
    
    /**
     * Custom method to build the tiers (can prevent SQL query)
     *
     * @access    protected
     * @var        string
     */
    protected $_customBuildMethod    = '';
    
    /**
     * Method constructor
     *
     * @access    public
     * @param    object        Registry Object
     * @param    array         Array of settings:
     *                        [ 'sqlPrimaryID'    (the SQL table field for the item ID)
     *                          'sqlParentID'      (the SQL table field for the parent ID)
     *                          'sqlFolderFlag'    (the SQL table field that tells if the row is a folder or not *Optional)
     *                          'sqlTitle'        (the SQL table field for the item title)
     *                          'sqlOrder'        (the SQL table field(s) to order on or by)
     *                          'sqlSelect'        (the SQL table select fields (* by default))
     *                          'sqlTable'        (the SQL table name)
     *                          'sqlWhere'        (Any additional 'where' information *Optional) ]
     * @return    @e void
     */
    public function __construct( ipsRegistry $registry, $settings )
    {
        /* Make object */
        $this->registry   =  $registry;
        $this->DB          =  $this->registry->DB();
        $this->settings   =& $this->registry->fetchSettings();
        $this->request    =& $this->registry->fetchRequest();
        $this->member     =  $this->registry->member();
        $this->memberData =& $this->registry->member()->fetchMemberData();
        $this->cache      =  $this->registry->cache();
        $this->caches     =& $this->registry->cache()->fetchCaches();
        
        /* Sort out settings */
        $this->_sqlPrimaryID        = isset( $settings['sqlPrimaryID']  ) ? $settings['sqlPrimaryID']  : '';
        $this->_sqlParentID            = isset( $settings['sqlParentID']   ) ? $settings['sqlParentID']   : '';
        $this->_sqlFolderFlag        = isset( $settings['sqlFolderFlag'] ) ? $settings['sqlFolderFlag'] : '';
        $this->_sqlTitle            = isset( $settings['sqlTitle']      ) ? $settings['sqlTitle']      : '';
        $this->_sqlOrder            = isset( $settings['sqlOrder']      ) ? $settings['sqlOrder']      : '';
        $this->_sqlTable            = isset( $settings['sqlTable']      ) ? $settings['sqlTable']      : '';
        $this->_sqlWhere            = isset( $settings['sqlWhere']      ) ? $settings['sqlWhere']      : '';
        $this->_sqlSelect            = isset( $settings['sqlSelect']     ) ? $settings['sqlSelect']     : '*';
        $this->_customBuildMethod    = isset( $settings['customMethod']  ) ? $settings['customMethod']  : '';
        
        /* Build the tiers */
        $this->_buildTiers();
    }
    
    /**
     * Custom method to build skin collections tier.  Data is already 
     * in caches array, so no need to query it.
     *
     * @access    protected
     * @return    @e void
     */
    protected function _buildSkinTiers()
    {
        if ( ! count( $this->_itemCache ) )
        {
            $_cache    = $this->caches['skinsets'];
            
            if( !count($_cache) OR !is_array($_cache) )
            {
                $this->_customBuildMethod    = '';
                
                return $this->_buildTiers();
            }
            
            foreach( $_cache as $item )
            {
                if ( $item[ $this->_sqlParentID ] < 1 )
                {
                    $item[ $this->_sqlParentID ] = 'root';
                }
                
                $this->_itemCache[ $item[$this->_sqlParentID] ][ $item[$this->_sqlPrimaryID] ] = $item;
                $this->_itemByID[ $item[$this->_sqlPrimaryID] ] = $item[$this->_sqlParentID];
            }
        }
    }
    
    /**
     * Build the in-memory information tiers
     *
     * @access     protected
     * @return    @e void
     */
    protected function _buildTiers()
    {
        if ( ! count( $this->_itemCache ) )
        {
            //-----------------------------------------
            // See if there is a specialized function
            // for this first
            //-----------------------------------------
            
            if( method_exists( $this, $this->_customBuildMethod ) )
            {
                $method    = $this->_customBuildMethod;
                $this->$method();
                return;
            }
            
            //-----------------------------------------
            // Get pages from db
            //-----------------------------------------
            
            $this->_sqlOrder = $this->_sqlOrder ? $this->_sqlOrder : $this->_sqlTitle;
            
            $this->DB->build( array( 'select' => $this->_sqlSelect,
                                     'where'  => $this->_sqlWhere,
                                     'from'   => $this->_sqlTable,
                                     'order'  => $this->_sqlOrder ) );
            $this->DB->execute();
            
            while( $item = $this->DB->fetch() )
            {
                if ( $item[ $this->_sqlParentID ] < 1 )
                {
                    $item[ $this->_sqlParentID ] = 'root';
                }
                
                $this->_itemCache[ $item[$this->_sqlParentID] ][ $item[$this->_sqlPrimaryID] ] = $item;
                $this->_itemByID[ $item[$this->_sqlPrimaryID] ] = $item[$this->_sqlParentID];
            }
        }
    }
    
    /**
     * Rebuild the in-memory information
     *
     * @access    public
     * @return    @e void
     */
    public function rebuildTiers()
    {
        $this->_itemCache = array();
        $this->_buildTiers();
    }
    
    /**
     * Returns data
     *
     * @access    public
     * @param    string
     * @return    mixed
     */
    public function getData( $key )
    {
        if ( isset( $this->_itemCache[ $key ] ) )
        {
            return $this->_itemCache[ $key ];
        }
        else
        {
            return FALSE;
        }
    }
    
    /**
     * Return all tier data as an array
     *
     * @access    public
     * @return    array
     */
    public function asArray()
    {
        return is_array( $this->_itemCache ) ? $this->_itemCache : array();
    }
    
    /**
     * Return a data entry by primary ID
     *
     * @access     public
     * @param    int            ID of the data row to return
     * @return    mixed
     */
    public function fetchItemByID( $id )
    {
        return $this->_itemCache[ $this->_itemByID[ $id ] ][ $id ];
    }
    
    /**
     * Fetches all parents of a particular ID
     *
     * @access    public
     * @param    int            ID of the data row to retreive parents
     * @param    array         Array of IDs discovered. Used when recursing.
     * @return    array         Simple array of IDs
     */
    public function fetchItemParents( $root_id, $ids=array() )
    {
        $item = $this->fetchItemByID( $root_id );
        
        if ( $item[ $this->_sqlParentID ] and $item[ $this->_sqlParentID ] != 'root' )
        {
            $ids[] = $item[$this->_sqlParentID];
            
            $ids = $this->fetchItemParents( $item[$this->_sqlParentID], $ids );
        }
        
        return $ids;
    }
    
    /**
     * Fetches all children of a particular ID
     *
     * @access    public
     * @param    int            ID of the data row to retreive children
     * @param    array         Array of IDs discovered. Used when recursing.
     * @return    array         Simple array of IDs
     */
    public function fetchItemChildren( $root_id, $ids=array() )
    {
        if ( is_array( $this->_itemCache[ $root_id ] ) )
        {
            foreach( $this->_itemCache[ $root_id ] as $id => $item_data )
            {
                $ids[] = $id;
                
                $ids = $this->fetchItemChildren($id, $ids);
            }
        }
        
        return $ids;
    }
    
    /**
     * Return a HTML option list of directories
     *
     * @access    public
     * @param    int            Selected ID (shows that item by default in the drop down list)
     * @param    array        Array of primary IDs to skip (miss from the listing
     * @param    string         Text to use at the top of the listing (optional)
     * @param    int         ID to use at the top of the listing
     * @return    array
     */
    public function fetchDirectoriesDropDown($selected_id, $skip_id=array(), $nodir_text='--Выберите директорию--', $nodir_id=0 )
    {
        //-----------------------------------------
        // Got an array?
        //-----------------------------------------
        
        if ( ! is_array( $selected_id ) )
        {
            $_selected_id = $selected_id;
            $selected_id  = array( 0 => $_selected_id );
        }
        
        if ( $nodir_text )
        {
            $jump_string .= "<option value="".$nodir_id."">".$nodir_text."</option>n";
        }
        
        if ( is_array( $this->_itemCache['root'] ) and count( $this->_itemCache['root'] ) )
        {
            foreach( $this->_itemCache['root'] as $id => $item_data )
            {
                if ( in_array( $item_data[$this->_sqlPrimaryID], $skip_id ) )
                {
                    continue;
                }
            
                if ( (IN_DEV AND $item_data[$this->_sqlFolderFlag] ) OR $item_data[$this->_sqlFolderFlag] == 1 )
                {
                    $selected = '';
                    
                    if ( in_array( $item_data[ $this->_sqlPrimaryID ], $selected_id ) )
                    {
                        $selected = ' selected="selected"';
                    }
                
                    $jump_string .= "<option value="{$item_data[$this->_sqlPrimaryID]}"".$selected.">".$item_data[$this->_sqlTitle]."</option>n";
                
                    $depth_guide = '--';
                
                    if ( is_array( $this->_itemCache[ $item_data[$this->_sqlPrimaryID] ] ) )
                    {
                        foreach( $this->_itemCache[ $item_data[$this->_sqlPrimaryID] ] as $id => $item_data )
                        {
                            if ( in_array( $item_data[$this->_sqlPrimaryID], $skip_id ) )
                            {
                                continue;
                            }
            
                            if ( (IN_DEV AND $item_data[$this->_sqlFolderFlag] ) OR $item_data[$this->_sqlFolderFlag] == 1 )
                            {
                                $selected = "";
                            
                                if ( in_array( $item_data[ $this->_sqlPrimaryID ], $selected_id ) )
                                {
                                    $selected = ' selected="selected"';
                                }
                            
                                $jump_string .= "<option value="{$item_data[$this->_sqlPrimaryID]}"".$selected.">  |".$depth_guide." ".$item_data[$this->_sqlTitle]."</option>n";
                            }
                        
                            $jump_string = $this->_fetchDirectoriesDropDown( $item_data[$this->_sqlPrimaryID], $jump_string, $depth_guide . '--', $selected_id, $skip_id );
                        }
                    }
                }
            }
        }
        
        return $jump_string;
    }
    
    /**
     * Return a HTML option list of directories: Internal version
     *
     * @access    protected
     * @param    int            Primary ID of entry to drill down from
     * @param    string        Currently built option list
     * @param    string         Current depth guage
     * @param    int         Primary ID selected
     * @param    array         Array of IDs to skip
     * @return    array
     */
    protected function _fetchDirectoriesDropDown($root_id, $jump_string="", $depth_guide="", $selected_id, $skip_id=array())
    {
        //-----------------------------------------
        // Got an array?
        //-----------------------------------------
        
        if ( ! is_array( $selected_id ) )
        {
            $_selected_id = $selected_id;
            $selected_id  = array( $_selected_id => $_selected_id );
        }
        
        if ( is_array( $this->_itemCache[ $root_id ] ) )
        {
            foreach( $this->_itemCache[ $root_id ] as $id => $item_data )
            {
                if ( in_array( $item_data[$this->_sqlPrimaryID], $skip_id ) )
                {
                    continue;
                }
                        
                if ( (IN_DEV AND $item_data[$this->_sqlFolderFlag] ) OR $item_data[$this->_sqlFolderFlag] == 1 )
                {
                    $selected = "";
                    
                    if ( in_array( $item_data[ $this->_sqlPrimaryID ], $selected_id ) )
                    {
                        $selected = ' selected="selected"';
                    }
                    
                    $jump_string .= "<option value="{$item_data[$this->_sqlPrimaryID]}"".$selected.">  '".$depth_guide." ".$item_data[$this->_sqlTitle]."</option>n";
                }
                    
                $jump_string = $this->_fetchDirectoriesDropDown( $item_data[$this->_sqlPrimaryID], $jump_string, $depth_guide . '--', $selected_id, $skip_id );
            }
        }
        
        return $jump_string;
    }
    
    /**
     * Return a HTML option list of all items: Internal version
     *
     * @access    public
     * @param    array        Array of selected IDs
     * @param    array         Array of IDs to skip
     * @param    array         [Optional: Default row array (value, name). Eg: array( '0', 'None' )
     * @return    string
     */
    public function fetchAllsItemDropDown($selected_id=array(), $skip_id=array(), $defaultRow=array())
    {
        //-----------------------------------------
        // Multi selections?
        //-----------------------------------------
        
        if ( ! is_array( $selected_id ) )
        {
            $selected_id = array( $selected_id );
        }
        
        //-----------------------------------------
        // Default row?
        //-----------------------------------------
        
        if ( count( $defaultRow ) )
        {
            if ( in_array( $defaultRow[0], $selected_id ) )
            {
                $selected = ' selected="selected"';
            }
            
            $jump_string .= "<option value="{$defaultRow[0]}"".$selected.">".$defaultRow[1]."</option>n";
        }
        
        //-----------------------------------------
        // Here we go...
        //-----------------------------------------
        
        foreach( $this->_itemCache['root'] as $id => $item_data )
        {
            if ( in_array( $item_data[$this->_sqlPrimaryID], $skip_id ) )
            {
                continue;
            }
            
            $selected = '';
            
            if ( in_array( $item_data[$this->_sqlPrimaryID], $selected_id ) )
            {
                $selected = ' selected="selected"';
            }
            
            $jump_string .= "<option value="{$item_data[$this->_sqlPrimaryID]}"".$selected.">".$item_data[$this->_sqlTitle]."</option>n";
            
            $depth_guide = '--';
            
            if ( is_array( $this->_itemCache[ $item_data[$this->_sqlPrimaryID] ] ) )
            {
                foreach( $this->_itemCache[ $item_data[$this->_sqlPrimaryID] ] as $id => $item_data )
                {
                    if ( in_array( $item_data[$this->_sqlPrimaryID], $skip_id ) )
                    {
                        continue;
                    }
        
                    $selected = "";
                    
                    if ( is_array( $selected_id ) AND in_array( $item_data[$this->_sqlPrimaryID], $selected_id ) )
                    {
                        $selected = ' selected="selected"';
                    }
                    
                    //-----------------------------------------
                    // Skip system folder
                    //-----------------------------------------
                    
                    if ( ! IN_DEV AND $item_data[$this->_sqlFolderFlag] == 2 )
                    {
                        continue;
                    }
                    
                    $jump_string .= "<option value="{$item_data[$this->_sqlPrimaryID]}"".$selected.">  '".$depth_guide." ".$item_data[$this->_sqlTitle]."</option>n";
                
                    $jump_string = $this->_fetchAllsItemDropDown( $item_data[$this->_sqlPrimaryID], $jump_string, $depth_guide . '--', $selected_id, $skip_id );
                }
            }
        }
        
        return $jump_string;
    }
    
    /**
     * Return a HTML option list of all items: Internal version
     *
     * @access    protected
     * @param    int            Primary ID of entry to drill down from
     * @param    string        Currently built option list
     * @param    string         Current depth guage
     * @param    int         Primary ID selected
     * @param    array         Array of IDs to skip
     * @return    string
     */
    protected function _fetchAllsItemDropDown($root_id, $jump_string="", $depth_guide="", $selected_id, $skip_id=array())
    {
        if ( is_array( $this->_itemCache[ $root_id ] ) )
        {
            foreach( $this->_itemCache[ $root_id ] as $id => $item_data )
            {
                if ( in_array( $item_data[$this->_sqlPrimaryID], $skip_id ) )
                {
                    continue;
                }
                
                $selected = "";
                
                if ( is_array( $selected_id ) AND in_array( $item_data[ $this->_sqlPrimaryID ], $selected_id ) )
                {
                    $selected = ' selected="selected"';
                }
                
                //-----------------------------------------
                // Skip system folder
                //-----------------------------------------
                
                if ( ! IN_DEV AND $item_data[$this->_sqlFolderFlag] == 2 )
                {
                    continue;
                }
                
                $jump_string .= "<option value="{$item_data[$this->_sqlPrimaryID]}"".$selected.">  |".$depth_guide." ".$item_data[$this->_sqlTitle]."</option>n";
                    
                $jump_string = $this->_fetchAllsItemDropDown( $item_data[$this->_sqlPrimaryID], $jump_string, $depth_guide . '--', $selected_id, $skip_id );
            }
        }
        
        return $jump_string;
    }
}