Вход Регистрация
Файл: admin/sources/classes/skins/skinDifferences.php
Строк: 810
<?php

/**
 * <pre>
 * Invision Power Services
 * IP.Board v3.3.3
 * Skin Functions
 * Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $
 * </pre>
 *
 * Owner: Matt
 * @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 $
 *
 */

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 
skinDifferences extends skinCaching
{
    
/**#@+
     * Registry objects
     *
     * @access    protected
     * @var        object
     */    
    
protected $registry;
    protected 
$DB;
    protected 
$settings;
    protected 
$request;
    protected 
$lang;
    protected 
$member;
    protected 
$memberData;
    protected 
$cache;
    protected 
$caches;
    
/**#@-*/
    
    /**
     * Diff class object
     * @var    object
     */
    
protected $classDifference;
    
/**
     * Constructor
     *
     * @access    public
     * @param    object        Registry object
     * @return    @e void
     */
    
public function __construct( ipsRegistry $registry )
    {
        
/* Make diff class object */
        
require_once( IPS_KERNEL_PATH . 'classDifference.php' );/*noLibHook*/
        
$this->classDifference         = new classDifference();
        
$this->classDifference->method = 'PHP';
        
        
/* Make object */
        
parent::__construct( $registry );
    }
    
    
/**
     * Revert changes
     *
     * @access    public
     * @param    array        Array of item (change_id) ids
     * @return    int            Number of items reverted
     */
    
public function revert( $items )
    {
        
/* INIT */
        
$reverted = 0;
        
$setIds    = array();
        
$has       = array( 'css' => 0, 'template' => 0 );
        
        
/* Basic check */
        
if ( ! count( $items ) )
        {
            return 
false;
        }
        
        
/* Fetch Data */
        
$this->DB->build( array( 'select' => '*',
                                 
'from'   => 'skin_merge_changes',
                                 
'where'  => 'change_id IN(' . implode( ',', IPSLib::cleanIntArray( $items ) ) . ')' ) );
        
$o = $this->DB->execute();
        
        
/* GO freakiNG LoOPy */
        
while( $row = $this->DB->fetch( $o ) )
        {
            
$_oldContent = false;
            
            
/* KNock out the bad boyz who ain't not worth it eva girlfriend */
            
if ( ! $row['change_changes_applied'] OR ! $row['change_original_content'] )
            {
                
/* slowly starting to lose the plot */
                
continue;
                
/* don't mind if I do! */
            
}
            
            
/* Which text? */
            
$text    = $row['change_original_content'];
            
            
/* Fetch session */
            
$session = $this->fetchSession( $row['change_session_id'] );
            
            
/* Store set id */
            
$setIds[ $session['merge_set_id'] ] = $session['merge_set_id'];
            
            
/* Fetch customized template details */
            
if ( $row['change_data_type'] == 'template' )
            {
                
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                          
'from'   => 'skin_templates',
                                                          
'where'  => 'template_set_id=' . intval( $session['merge_set_id'] ) . ' AND template_group='' . $this->DB->addSlashes( $row['change_data_group'] ) . '' AND template_name='' . $this->DB->addSlashes( $row['change_data_title'] ) . ''' ) );
            }
            else
            {
                
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                          
'from'   => 'skin_css',
                                                          
'where'  => 'css_set_id=' . intval( $session['merge_set_id'] ) . ' AND css_app='' . $this->DB->addSlashes( $row['change_data_group'] ) . '' AND css_group='' . $this->DB->addSlashes( $row['change_data_title'] ) . ''' ) );
            }
        
            if ( 
$row['change_data_type'] == 'template' )
            {
                if ( 
$_data['template_id'] )
                {
                    
$has['template']++;
                    
$reverted++;
                    
/* Should in theory only ever get here, but you NEVER KNOW */
                    
$this->DB->update( 'skin_templates', array( 'template_content'     => $text,
                                                                
'template_user_edited' => 1,
                                                                
'template_updated'     => time() ), 'template_id=' . $_data['template_id'] );
                }
            }
            else
            {
                if ( 
$_data['css_id'] )
                {
                    
$has['css']++;
                    
$reverted++;
                    
$this->DB->update( 'skin_css', array( 'css_content'      => $text,
                                                          
'css_updated'      => time() ), 'css_id=' . $_data['css_id'] );
                }
            }
            
            
/* Did we successfully commit? */
            
if ( is_array( $_data ) AND count( $_data ) )
            {
                
/* Update row */
                
$this->DB->update( 'skin_merge_changes', array( 'change_original_content' => '', 'change_changes_applied' => 0 ), 'change_id=' . $row['change_id'] );
            }
        }
        
        
/* Do we need to recache? */
        
if ( count( $setIds ) )
        {
            foreach( 
array_keys( $setIds ) as $id )
            {
                if ( 
$has['template'] )
                {
                    
$this->rebuildPHPTemplates( $id );
                }
                
                if ( 
$has['css'] )
                {
                    
$this->rebuildCSS( $id );
                }
            }
        }
        
        return 
$reverted;
    }
    
    
/**
     * Commit changes
     *
     * @access    public
     * @param    array        Array of item (change_id) ids
     * @return    int            Number of items committed
     */
    
public function commit( $items )
    {
        
/* INIT */
        
$committed = 0;
        
$setIds    = array();
        
$has       = array( 'css' => 0, 'template' => 0 );
        
        
/* Basic check */
        
if ( ! count( $items ) )
        {
            return 
false;
        }
        
        
/* Fetch Data */
        
$this->DB->build( array( 'select' => '*',
                                 
'from'   => 'skin_merge_changes',
                                 
'where'  => 'change_id IN(' . implode( ',', IPSLib::cleanIntArray( $items ) ) . ')' ) );
        
$o = $this->DB->execute();
        
        
/* GO freakiNG LoOPy */
        
while( $row = $this->DB->fetch( $o ) )
        {
            
$_oldContent = false;
            
            
/* KNock out the bad boyz who ain't not worth it eva girlfriend */
            
if ( ! $row['change_can_merge'] OR ( $row['change_is_conflict'] AND ! $row['change_final_content'] ) )
            {
                
/* slowly starting to lose the plot */
                
continue;
                
/* don't mind if I do! */
            
}
            
            
/* Which text? */
            
$text    = ( $row['change_final_content'] ) ? $row['change_final_content'] : $row['change_merge_content'];
            
            
/* Fetch session */
            
$session = $this->fetchSession( $row['change_session_id'] );
            
            
/* Store set id */
            
$setIds[ $session['merge_set_id'] ] = $session['merge_set_id'];
            
            
/* Fetch customized template details */
            
if ( $row['change_data_type'] == 'template' )
            {
                
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                          
'from'   => 'skin_templates',
                                                          
'where'  => '(template_set_id=' . intval( $session['merge_set_id'] ) . ' OR ( template_set_id=0 AND template_master_key='' . $this->DB->addSlashes( $session['merge_master_key'] ) . '' ) ) AND template_group='' . $this->DB->addSlashes( $row['change_data_group'] ) . '' AND template_name='' . $this->DB->addSlashes( $row['change_data_title'] ) . ''',
                                                          
'order'  => 'template_set_id DESC',
                                                          
'limit'  => array(0,1) ) );
            }
            else
            {
                
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                          
'from'   => 'skin_css',
                                                          
'where'  => '(css_set_id=' . intval( $session['merge_set_id'] ) . ' OR ( css_set_id=0 AND css_master_key='' . $this->DB->addSlashes( $session['merge_master_key'] ) . '' ) ) AND css_app='' . $this->DB->addSlashes( $row['change_data_group'] ) . '' AND css_group='' . $this->DB->addSlashes( $row['change_data_title'] ) . ''',
                                                          
'order'  => 'css_set_id DESC',
                                                          
'limit'  => array(0,1) ) );
            }
        
            if ( 
$row['change_data_type'] == 'template' )
            {
                if ( 
$_data['template_id'] )
                {
                    if ( 
$this->testTemplateBitSyntax( $_data['template_name'], $_data['template_data'], $text ) !== TRUE )
                    {
                        
/* Could log or throw an error here */
                        
continue;
                    }
        
                    
$_oldContent = $_data['template_content'];
                    
$committed++;
                    
$has['template']++;
                    
                    
/* Should in theory only ever get here, but you NEVER KNOW */
                    
$this->DB->update( 'skin_templates', array( 'template_content'     => $text,
                                                                
'template_user_edited' => 1,
                                                                
'template_updated'     => time() ), 'template_id=' . $_data['template_id'] );
                }
            }
            else
            {
                if ( 
$_data['css_id'] )
                { 
                    
$_oldContent = $_data['css_content'];
                    
$committed++;
                    
$has['css']++;
                    
                    
$this->DB->update( 'skin_css', array( 'css_content'      => $text,
                                                          
'css_updated'      => time() ), 'css_id=' . $_data['css_id'] );
                }
            }
            
            
/* Did we successfully commit? */
            
if ( $_oldContent !== false )
            {
                
/* Update row */
                
$this->DB->update( 'skin_merge_changes', array( 'change_original_content' => $_oldContent, 'change_changes_applied' => 1 ), 'change_id=' . $row['change_id'] );
            }
        }
        
        
/* Do we need to recache? */
        
if ( count( $setIds ) )
        {
            foreach( 
array_keys( $setIds ) as $id )
            {
                if ( 
$has['template'] )
                {
                    
$this->rebuildPHPTemplates( $id );
                }
                
                if ( 
$has['css'] )
                {
                    
$this->rebuildCSS( $id );
                }
            }
        }
        
        return 
$committed;
    }

    
/**
     * Resolve Conflict Automatically
     *
     * @access    public
     * @param    array        Array of item (change_id) ids
     * @param    type        Which wins? YOU DECIDE (custom/new)
     * @return    nufink
     */
    
public function resolveConflict( $items, $type='new' )
    {
        
/* Basic check */
        
if ( ! count( $items ) )
        {
            return 
false;
        }
        
        
/* Fetch Data */
        
$this->DB->build( array( 'select' => '*',
                                 
'from'   => 'skin_merge_changes',
                                 
'where'  => 'change_id IN(' . implode( ',', IPSLib::cleanIntArray( $items ) ) . ')' ) );
        
$o = $this->DB->execute();
        
        
/* GO freakiNG LoOPy */
        
while( $row = $this->DB->fetch( $o ) )
        {
            
$text = $row['change_merge_content'];
            
            
/* Re-format  */
            
preg_match_all( "#<ips:conflict id="([0-9]+?)">((?<!(</ips:conflict>)).+?)</ips:conflict>#s", $text, $matches );
            
            if ( 
is_array($matches) AND count($matches) )
            {
                foreach( 
$matches[1] as $index => $m )
                {    
                    
/* Yeah, I like readable code and copying and pasting evidently */
                    
$_all      = $matches[0][$index];
                    
$_id      = $matches[1][$index];
                    
$_content = $matches[2][$index];
                    
                    if ( 
$_id != null AND $_content )
                    {
                        
/* Save which block? */
                        
if ( $type == 'new' )
                        {
                            
$_content = preg_replace( "#(?:n)?<ips:cblock type="original">(?:n)?(.+?)(?:n)?</ips:cblock>#s", "", $_content );
                            
$_content = preg_replace( "#(?:n)?<ips:cblock type="new">(?:n)?(.+?)(?:n)?</ips:cblock>#s", "n\1", $_content );
                        }
                        else
                        {
                            
$_content = preg_replace( "#(?:n)?<ips:cblock type="original">(?:n)?(.+?)(?:n)?</ips:cblock>#s", "n\1", $_content );
                            
$_content = preg_replace( "#(?:n)?<ips:cblock type="new">(?:n)?(.+?)(?:n)?</ips:cblock>#s", "", $_content );
                        }
                        
                        
$text = str_replace( $_all,  $_content, $text );
                    }
                }
                
                
/* Save to db */
                
$this->DB->update( 'skin_merge_changes', array( 'change_final_content' => $text ), 'change_id=' . intval( $row['change_id'] ) );
            }
        }
        
        return 
true;
    }
    
    
/**
     * Format Merge: Edit
     *
     * @access    public
     * @param    string        Content from DB
     * @return    string        Content suitable for editing in a text area
     */
    
public function formatMergeForEdit( $text )
    {
        
/* Re-format mark-up for preview */
        
preg_match_all( "#<ips:conflict id="([0-9]+?)">(.+?)</ips:conflict>#s", $text, $matches );
        
        if ( 
is_array($matches[1]) AND count($matches[1]) )
        {
            foreach( 
$matches[1] as $index => $m )
            {        
                
/* Yeah, I like readable code */
                
$_all      = $matches[0][$index];
                
$_id      = $matches[1][$index];
                
$_content = $matches[2][$index];
                
                if ( 
$_id != null AND $_content )
                {
                    
/* Format old default block */
                    
$_content = preg_replace( "#(?:n)?<ips:cblock type="original">(?:n)?(.+?)(?:n)?</ips:cblock>#s", "~~~~~~~~~~ CUSTOM CONTENTn\1", $_content );
                    
                    
/* Format custom block */
                    
$_content = preg_replace( "#(?:n)?<ips:cblock type="new">(?:n)?(.+?)(?:n)?</ips:cblock>#s", "n===================n\1n^^^^^^^^^^ NEW DEFAULTn", $_content );
                    
                    
$text = str_replace( $_all,  $_content, $text );
                }
            }
        }
        
        
/* Encode */
        
$text = IPSText::textToForm( $text );
        
        
/* Convert special place holders */
        
$text = str_replace( '~~~~~~~~~~', '<<<<<<<<<<', $text );
        
$text = str_replace( '^^^^^^^^^^', '>>>>>>>>>>', $text );
        
        return 
$text;
    }
    
    
/**
     * Format Merge: Preview
     *
     * @access    public
     * @param    string        Content from DB
     * @return    string        Content suitable for viewing in a web page
     */
    
public function formatMergeForPreview( $text )
    {
        
/* Encode and format white space */
        
$text = htmlspecialchars( $text );
        
$text = str_replace( "n", "<br />", $text );
        
$text = str_replace( "t", "&nbsp; &nbsp; ", $text );
        
        
/* Un-encode special mark-up */
        
$text = preg_replace( "#&lt;ips:conflict id=&quot;([0-9]+?)&quot;&gt;#", "<ips:conflict id="\1">", $text );
        
$text = preg_replace( "#&lt;ips:cblock type=&quot;(w+?)&quot;&gt;#", "<ips:cblock type="\1">", $text );
        
$text = preg_replace( "#&lt;/ips:(cblock|conflict)&gt;#", "</ips:\1>", $text );
        
        
/* Re-format mark-up for preview */
        
preg_match_all( "#<ips:conflict id="([0-9]+?)">(.+?)</ips:conflict>#s", $text, $matches );
        
        if ( 
is_array($matches[1]) AND count($matches[1]) )
        {
            foreach( 
$matches[1] as $index => $m )
            {        
                
/* Yeah, I like readable code */
                
$_all      = $matches[0][$index];
                
$_id      = $matches[1][$index];
                
$_content = $matches[2][$index];
                
                if ( 
$_id != null AND $_content )
                {
                    
/* Format old default block */
                    
$_content = preg_replace( "#(?:<br />)?<ips:cblock type="original">(?:<br />)?(.+?)(?:<br />)?</ips:cblock>#s", "<div class="ips_merge_custom __c{$_id}" id="ips_merge_custom_id_{$_id}"><h3>Custom Value</h3><p>\1</p></div>", $_content );
                    
                    
/* Format custom block */
                    
$_content = preg_replace( "#(?:<br />)?<ips:cblock type="new">(?:<br />)?(.+?)(?:<br />)?</ips:cblock>#s", "<div class="ips_merge_new __n{$_id}" id="ips_merge_new_id_{$_id}"><h3>New Value</h3><p>\1</p></div>", $_content );
                    
                    
$text = str_replace( $_all,  "<div class="ips_merge_wrap __w{$_id}"id="ips_merge_wrap_id_{$_id}">" . $_content . "</div>", $text );
                }
            }
        }
        
//IPSDebug::addLogMessage( str_replace( '<br />', "<br />n", $text), 'mdmdmd', false, true, false );
        
return $text;
    }
    
    
/**
     * Fetch differences between items
     * Can be CSS or template
     *
     * @access    public
     * @param    string        Original text
     * @param    string        New text
     * @return    mixed        Returns compiled diff text or false if no diffs
     */
    
public function fetchDifferences( $original, $new, $method='inline' )
    {
        
$this->classDifference->diff_found = false;
        
        
$diff = $this->classDifference->getDifferences( $original, $new, $method='inline' );
        
        if ( 
$this->classDifference->diff_found )
        {
            return 
$diff;
        }
        else
        {
            return 
false;
        }
    }
    
    
/**
     * Fetch original item (from _previous table)
     * Can be CSS or template
     *
     * @access    public
     * @param    array        Array of data
     * @return    string        Item content or false
     */
    
public function fetchOriginalItem( $data )
    {
        
/* INIT */
        
$original = false;
        
$_data    = array();
        
        
/* Template? */
        
if ( $data['data_type'] == 'template' )
        {
            
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                      
'from'   => 'skin_templates_previous',
                                                      
'where'  => 'p_template_group='' . $this->DB->addSlashes( $data['data_group'] ) . '' AND p_template_name='' . $this->DB->addSlashes( $data['data_title'] ) . '' AND p_template_master_key='' . $this->DB->addSlashes( $data['data_master_key'] ) . ''' ) );
        }
        else
        {
            
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                      
'from'   => 'skin_css_previous',
                                                      
'where'  => 'p_css_app='' . $this->DB->addSlashes( $data['data_group'] ) . '' AND p_css_group='' . $this->DB->addSlashes( $data['data_title'] ) . '' AND p_css_master_key='' . $this->DB->addSlashes( $data['data_master_key'] ) . ''' ) );
        }
        
        if ( 
is_array( $_data ) AND count( $_data ) )
        {
            if ( 
$data['data_type'] == 'template' )
            {
                
$original = $_data['p_template_content'];
            }
            else
            {
                
$original = $_data['p_css_content'];
            }
            
        }
        
        return 
$original;
    }
    
    
/**
     * Fetch new item (from current table)
     * Can be CSS or template
     *
     * @access    public
     * @param    array        Array of data
     * @return    string        Item content or false
     */
    
public function fetchNewItem( $data )
    {
        
/* INIT */
        
$original = false;
        
$_data    = array();
        
        
/* Template? */
        
if ( $data['data_type'] == 'template' )
        {
            
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                      
'from'   => 'skin_templates',
                                                      
'where'  => 'template_group='' . $this->DB->addSlashes( $data['data_group'] ) . '' AND template_name='' . $this->DB->addSlashes( $data['data_title'] ) . '' AND template_master_key='' . $this->DB->addSlashes( $data['data_master_key'] ) . ''' ) );
        }
        else
        {
            
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                      
'from'   => 'skin_css',
                                                      
'where'  => 'css_app='' . $this->DB->addSlashes( $data['data_group'] ) . '' AND css_group='' . $this->DB->addSlashes( $data['data_title'] ) . '' AND css_master_key='' . $this->DB->addSlashes( $data['data_master_key'] ) . ''' ) );
        }
        
        if ( 
is_array( $_data ) AND count( $_data ) )
        {
            if ( 
$data['data_type'] == 'template' )
            {
                
$original = $_data['template_content'];
            }
            else
            {
                
$original = $_data['css_content'];
            }
            
        }
        
        return 
$original;
    }

    
    
/**
     * Fetch custom item (user edited item)
     * Can be CSS or template
     *
     * @access    public
     * @param    array        Array of data
     * @return    array        Item content or false
     */
    
public function fetchCustomItem( $data )
    {
        
/* INIT */
        
$custom   = false;
        
$_data    = array();
        
        
/* Template? */
        
if ( $data['data_type'] == 'template' )
        {
            
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                      
'from'   => 'skin_templates',
                                                      
'where'  => 'template_set_id=' . intval( $data['data_set_id'] ) . ' AND template_group='' . $this->DB->addSlashes( $data['data_group'] ) . '' AND template_name='' . $this->DB->addSlashes( $data['data_title'] ) . ''' ) );
        }
        else
        {
            
$_data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                      
'from'   => 'skin_css',
                                                      
'where'  => 'css_set_id=' . intval( $data['data_set_id'] ) . ' AND css_app='' . $this->DB->addSlashes( $data['data_group'] ) . '' AND css_group='' . $this->DB->addSlashes( $data['data_title'] ) . ''' ) );
        }
        
        if ( 
is_array( $_data ) AND count( $_data ) )
        {
            if ( 
$data['data_type'] == 'template' )
            {
                
$custom = $_data['template_content'];
            }
            else
            {
                
$custom = $_data['css_content'];
            }
        }
        
        return 
$custom;
    }

    
    
/**
     * Fetch all skin difference sessions
     *
     * @access    public
     * @return    array        Array of skin difference sessions
     */
    
public function fetchSessions()
    {
        
/* INIT */
        
$sessions = array();
        
        
/* Fetch set up class */
        
require_once( IPS_ROOT_PATH . "setup/sources/base/setup.php" );/*noLibHook*/
        
        /* Fetch version numbers */
        
$versions = IPSSetUp::fetchXmlAppVersions('core');
        
        
/* Load data */
        
$this->DB->build( array( 'select' => '*',
                                 
'from'   => 'skin_merge_session',
                                 
'order'  => 'merge_date DESC' ) );
        
        
$this->DB->execute();
        
        while( 
$row = $this->DB->fetch() )
        {
            
/* Prep dates */
            
$row['_date'] = ipsRegistry::getClass( 'class_localization')->getDate( $row['merge_date'], 'TINY' );
            
            
/* Prep version numbers */
            
$row['_oldHumanVersion'] = $versions[ $row['merge_old_version'] ];
            
$row['_newHumanVersion'] = $versions[ $row['merge_new_version'] ];
            
            
/* Skin data */
            
$row['_skinData'] = $this->fetchSkinData( $row['merge_set_id'] );
            
            
/* Title */
            
$row['_title']    = $this->fetchReportTitle( $row );
            
            
$sessions[ $row['merge_id'] ] = $row;
        }
        
        return 
$sessions;
    }
    
    
/**
     * Fetch a title
     *
     * @access    public
     * @return    string        Report title string
     */
    
public function fetchReportTitle( $session )
    {
        if ( ! isset( 
$session['_skinData'] ) )
        {
            
$session = $this->fetchSession( $session['merge_id'], true );
        }
        
        return 
$session['_skinData']['set_name'] . ' (' . $session['_oldHumanVersion'] . ' &gt; ' . $session['_newHumanVersion'] .')';
    }
    
    
/**
     * Remove a session
     *
     * @access    public
     * @param    int            Session ID
     * @return    bool        True
     */
    
public function removeSession( $sessionID )
    {
        
/* Delete 'em */
        
$this->DB->delete('skin_merge_session', 'merge_id='.$sessionID );
        
        
$this->DB->delete('skin_merge_changes', 'change_session_id='.$sessionID );
    
        return 
TRUE;
    }
    
    
/**
     * Create new session
     *
     * @access    public
     * @param    int            Template set ID to run merge on
     * @return    int            New session ID
     *
     * Exception Codes
     * NO_SET                No such skin set
     * NO_PREVIOUS            No previous data found
     */
    
public function createSession( $setId )
    {
        
/* INIT */
        
$templates      = array();
        
$css          = array();
        
$skinData     = $this->fetchSkinData( $setId );
        
        
/* Quick test */
        
if ( ! $skinData['set_id'] )
        {
            throw new 
Exception('NO_SET');
        }
        
        
/* Got a master key? */
        
$skinData['set_master_key'] = ( $skinData['set_master_key'] ) ? $skinData['set_master_key'] : 'root';
        
        
/* Fetch version ID of previous elements */
        
$previous  = $this->DB->buildAndFetch( array( 'select' => 'p_template_long_version',
                                                      
'from'   => 'skin_templates_previous',
                                                      
'order'  => 'p_template_long_version DESC',
                                                      
'limit'  => array(0,1) ) );
        
        
        
/* Got any previous data? */
        
if ( ! $previous['p_template_long_version'] )
        {
            throw new 
Exception('NO_PREVIOUS');
        }
        
        
/* Delete all previous with this set ID */
        
$this->DB->build( array( 'select' => 'merge_id',
                                 
'from'   => 'skin_merge_session',
                                 
'where'  => 'merge_set_id=' . $setId ) );
                                 
        
$o = $this->DB->execute();
        
        while( 
$row = $this->DB->fetch( $o ) )
        {
            
$this->removeSession( $row['merge_id'] );
        }
        
        
/* Now grab master elements based on root key data */
        
$tCount    = 0;
        
$templates = $this->fetchTemplates( $skinData['set_master_key'], 'allNoContent' );
        
$css       = $this->fetchCSS( $skinData['set_master_key'], false );
        
        
/* Get correct count of templates */
        
foreach( $templates as $group => $data )
        {
            
$tCount += count( $templates[ $group ] );
        }
        
        
/* Grab current version numbers */
        
$cVersion  = IPSLib::fetchVersionNumber();
        
        
/* Create session */
        
$this->DB->insert( 'skin_merge_session', array( 'merge_date'             => time(),
                                                         
'merge_set_id'             => $setId,
                                                         
'merge_master_key'         => $skinData['set_master_key'],
                                                         
'merge_old_version'         => $previous['p_template_long_version'],
                                                         
'merge_new_version'         => $cVersion['long'],
                                                         
'merge_templates_togo'   => $tCount,
                                                         
'merge_css_togo'         => intval( count( $css ) ),
                                                         
'merge_templates_done'   => 0,
                                                         
'merge_css_done'         => 0 ) );
                                                         
                                                                        
        
$diffSesssionID = $this->DB->getInsertId();
        
        return 
$diffSesssionID;
    }
    
    
/**
     * Fetch a report
     *
     * @access    public
     * @param    int            Session ID
     * @return    array
     */
    
public function fetchReport( $diffSessionID )
    {
        
//-----------------------------------------
        // INIT
        //-----------------------------------------
        
        
$return = array( 'counts' => array( 'missing' => 0, 'changed' => 0 ), 'data' => array() );
    
        
//-----------------------------------------
        // Get data
        //-----------------------------------------
        
        
$this->DB->build( array( 'select' => '*',
                                 
'from'   => 'skin_merge_changes',
                                 
'where'  => 'change_session_id='.$diffSessionID,
                                 
'order'  => 'change_data_group ASC, change_data_title ASC' ) );
        
        
        
$this->DB->execute();
        
        while( 
$row = $this->DB->fetch() )
        {
            
//-----------------------------------------
            // Gen data
            //-----------------------------------------
            
            
$row['_key']  = $row['change_key'];
            
$row['_size'] = IPSLib::sizeFormat( IPSLib::strlenToBytes( IPSText::mbstrlen( $row['change_data_content'] ) ) );
            
            
//-----------------------------------------
            // Diff type
            //-----------------------------------------
            
            
if ( $row['change_is_new'] )
            {
                
$row['_is'] = 'new';
                
$return['counts']['missing']++;
            }
            else
            {
                
$row['_is'] = 'changed';
                
$return['counts']['changed']++;
            }
            
            
/* Is it CSS? */
            
if ( $row['change_data_type'] == 'css' )
            {
                
$row['change_data_group'] = 'css';
                
$row['change_data_title'] .= '.css';
            }
            
            
/* Fetch basic stats */
            
if ( $row['change_data_content'] )
            {
                
$row['_diffs'] = substr_count( $row['change_data_content'], '-ips-match:1' );
            }
            
            if ( 
$row['change_merge_content'] AND stristr( $row['change_merge_content'], '<ips:conflict' ) )
            {
                
$row['_conflicts'] = substr_count( $row['change_merge_content'], '<ips:conflict' );
            }
            
            
//-----------------------------------------
            // Add data...
            //-----------------------------------------
            
            
$return['data'][ $row['change_data_group'] ][ $row['_key'] ] = $row;
        }
        
        return 
$return;
    }
    
    
/**
     * Fetch a session
     *
     * @access    public
     * @param    int            Session ID
     * @param    bool        Parse data
     * @return    mixed         Array of data, or false
     */
    
public function fetchSession( $diffSessionID, $parse=false )
    {
        
$session = $this->DB->buildAndFetch( array( 'select' => '*', 'from' => 'skin_merge_session', 'where' => 'merge_id='.$diffSessionID ) );
        
        if ( 
$session['merge_id']  AND $parse === true )
        {
            
/* Fetch set up class */
            
require_once( IPS_ROOT_PATH . "setup/sources/base/setup.php" );/*noLibHook*/
            
            /* Fetch version numbers */
            
$versions = IPSSetUp::fetchXmlAppVersions('core');
            
            
/* Prep dates */
            
$session['_date'] = ipsRegistry::getClass('class_localization')->getDate( $session['merge_date'], 'TINY' );
            
            
/* Prep version numbers */
            
$session['_oldHumanVersion'] = $versions[ $session['merge_old_version'] ];
            
$session['_newHumanVersion'] = $versions[ $session['merge_new_version'] ];
            
            
/* Skin data */
            
$session['_skinData'] = $this->fetchSkinData( $session['merge_set_id'] );
            
            
/* Title */
            
$session['_title']    = $this->fetchReportTitle( $session );
        }
        
        return ( 
$session['merge_id'] ) ? $session : FALSE;
    }
    
    
/**
     * Return the total number of bits to process
     *
     * @access    public
     * @param    int            Session ID
     * @param    string        Type: template or css
     * @return    int            Number of bits
     */
    
public function fetchNumberSessionTemplateBits( $diffSesssionID, $type='' )
    {
        
$return = 0;
        
        
/* Fetch data */
        
$data = $this->DB->buildAndFetch( array( 'select' => '*',
                                                 
'from'   => 'skin_merge_session',
                                                 
'where'  => 'merge_id=' . intval( $diffSesssionID ) ) );
                                                 
        if ( 
$type )
        {
            
$return = ( $type == 'template' ) ? $data['merge_templates_togo'] : $data['merge_css_togo'];
        }
        else
        {
            
$return = $data['merge_templates_togo'] + $data['merge_css_togo'];
        }
                                                
        return 
intval( $return );
    }

    
/**
     * Return the total number of master template bits
     *
     * @access    public
     * @return    int            Number of bits
     */
    
public function fetchNumberTemplateBits()
    {
        
$count = $this->DB->buildAndFetch( array( 'select' => 'count(*) as count',
                                                  
'from'   => 'skin_templates',
                                                  
'where'  => 'template_set_id=0' ) );
                                                
        return 
intval( $count['count'] );
    }
}
Онлайн: 2
Реклама