Вход Регистрация
Файл: IPBMafia.ru_IPB_3.4.6_Final_Rus _Nulled/board/upload/ips_kernel/classMerge.php
Строк: 424
<?php
/**
 * <pre>
 * Invision Power Services
 * IP.Board v3.4.6
 * Three Way Merge Class
 * Last Updated: $Date: 2012-05-10 16:10:13 -0400 (Thu, 10 May 2012) $ BY $author$
 * </pre>
 *
 * @author         Matt Mecham
 * @copyright    (c) 2001 - 2010 Invision Power Services, Inc.
 * @license        http://www.invisionpower.com/company/standards.php#license
 * @package        IP.Board
 * @link        http://www.invisionpower.com
 * @version        $Rev: 10721 $
 *
 */

class ThreeWayMerge
{
    
/**
     * Original text
     * For example, template bit from 3.0.5
     *
     * @var        array
     */
    
protected $_ORIG = array();
    
    
/**
     * New text
     * For example, template bit from 3.1.0
     *
     * @var        array
     */
    
protected $_NEW = array();
    
    
/**
     * Custom text
     * For example, user customized template bit
     *
     * @var        array
     */
    
protected $_CUSTOM = array();
    
    
/**
     * Debug messages
     *
     * @var        array
     */
    
public $DEBUG = array();
    
    
/**
     * Diff type
     *
     * @var        string
     */
    
public $diffType 'lite';
    
    
/**
     * Construct
     *
     * @param    string        Original Text
     * @param    string        New Text
     * @param    string        Custom Text
     * @param    string        Method ('lite' or 'ipb')
     * @return    @e void
     */
    
public function __construct$ORIG$NEW$CUSTOM$mType='lite' )
    {
        
$this->_ORIG   = ( ! is_array$ORIG ) )   ? explode"n"str_replace"rn""n"trim$ORIG ) ) ) : $ORIG;
        
$this->_NEW    = ( ! is_array$NEW ) )    ? explode"n"str_replace"rn""n" trim$NEW ) ) ) : $NEW;
        
$this->_CUSTOM = ( ! is_array$CUSTOM ) ) ? explode"n"str_replace"rn""n" trim$CUSTOM ) ) ) : $CUSTOM;
        
        if ( 
$mType != 'lite' )
        {
            
$this->diffType $mType;
        }
        
        
/* Set include path.. */
        
@set_include_pathIPS_KERNEL_PATH 'PEAR/' );/*noLibHook*/
        
        /* OMG.. too many PHP 5 errors under strict standards */
        
if ( IN_DEV )
        {
            
$oldReportLevel error_reporting);
            
error_reporting$oldReportLevel E_STRICT );
        }
        else
        {
            
error_reporting);
        }
        
        
/* ugh */
        
if ( $this->diffType == 'lite' )
        {
            require_once 
'Text/Diff3.php';/*noLibHook*/
            
require_once 'Text/Diff/Renderer.php';/*noLibHook*/
            
require_once 'Text/Diff/Renderer/inline.php';/*noLibHook*/
        
}
        else
        {
            require_once 
'Text/Diff.php';/*noLibHook*/
            
require_once 'Text/Diff/Renderer.php';/*noLibHook*/
            
require_once 'Text/Diff/Renderer/ips3waymerge.php';/*noLibHook*/
        
}
    }
    
    
/**
     * Perform the merge and return the result
     *
     * On conflict, will throw an exception with a message of CONFLICT
     *
     * @return    @e string
     * @throws    Exception
     */
     
    
public function merge()
    {
        
$this->_addDebugMsg'---- START--o---'$this->_ORIG );
        
$this->_addDebugMsg'---- START--n---'$this->_NEW );
        
$this->_addDebugMsg'---- START--c---'$this->_CUSTOM );
        
        if ( 
$this->diffType == 'lite' )
        {
            
/* Create the Diff object. */
            
$diff = new Text_Diff3$this->_ORIG$this->_NEW$this->_CUSTOM );
            
            
/* Output the diff in unified format. */
            
return $this->_postProcessQuickimplode"n"$diff->mergedOutput'XXXNEWXXX''XXXCUSTOMXXX' ) ) );
        }
        else
        {
            
/* ORIG - NEW */
            
$diff = new Text_Diff'auto', array( $this->_ORIG$this->_NEW ) );
            
$renderer = new Text_Diff_Renderer_ips3waymerge();
            
$orig_new explode"n"trim$renderer->render($diff) ) );
            
            
            
/* ORIG - CUSTOM */
            
$diff = new Text_Diff'auto', array( $this->_ORIG$this->_CUSTOM ) );
            
$renderer = new Text_Diff_Renderer_ips3waymerge();
            
$orig_custom explode"n"trim$renderer->render($diff) ) );
        
            
            
/* Process the arrays */
            
$orig_new_map     $this->_fetchProcessed$orig_new);
            
$orig_custom_map  $this->_fetchProcessed$orig_custom );
            
            
/* Add to debug */
            
$this->_addDebugMsg'---- OLD DEFAULT------'$this->_ORIG );
            
$this->_addDebugMsg'---- NEW DEFAULT------'$this->_NEW );
            
$this->_addDebugMsg'---- USER DEFAULT------'$this->_CUSTOM );
            
$this->_addDebugMsg'---- OLD DEFAULT > NEW DEFAULT DIFF------'$orig_new_map );
            
$this->_addDebugMsg'---- OLD DEFAULT > USER CUSTOM DIFF------'$orig_custom_map );
            
            
/* Process the thing */
            
try
            {
                
$return $this->_processMerge$orig_new_map$orig_custom_map );
                
                return 
$return;
            }
            catch( 
Exception $e )
            {
                throw new 
Exception$e->getMessage() );
            }
        }
    }
    
    
/**
     * Post process merge (quick)
     *
     * @param    string        Merge text
     * @return    @e string
     */
    
protected function _postProcessQuick$text )
    {
        
/* INIT */
        
$count 0;
        
//print $text; exit();
        /* MATCH */
        
preg_match_all"#<<<<<<< XXXNEWXXX(.+?)=======(.+?)>>>>>>> XXXCUSTOMXXX#si"$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];
                
$_new    trim$matches[1][$index], "n" );
                
$_custom trim$matches[2][$index], "n" );
                
                
$_new    "<ips:conflict id="{$count}">n<ips:cblock type="original">n" $_custom "n</ips:cblock>n<ips:cblock type="new">n" $_new "n</ips:cblock>n</ips:conflict>";
                    
                
$text str_replace$_all,  $_new$text );
                
                
$count++;
            }
        }
        
        return 
$text;
    }
    
    
/**
     * Process merge
     * Takes the two maps (old-new, old-custom) and merges.
     * Will throw an error on conflict.
     *
     * @param    array        old-new map
     * @param    array        old-custom map
     * @return    @e string
     */
    
protected function _processMerge$orig_new_map$orig_custom_map )
    {
        
$len      count$this->_ORIG );
        
$c        0;
        
$conflict 0;
        
$final    = array();
        
        while( 
$c <= $len )
        {
            
$left  $this->_sliceFromLineNumber$orig_new_map$c );
            
$right $this->_sliceFromLineNumber$orig_custom_map$c );
            
            if ( 
$left['type'] == 'ok' AND $right['type'] == 'ok' )
            {
                
$test1    $this->_textToAddAtLine$orig_new_map$c );
                
$test2    $this->_textToAddAtLine$orig_custom_map$c );
                
                
/* Potential conflict, are both modifications to this line the same? */
                
if ( count$test1 ) AND count$test2 ) AND implode"n"$test1 ) != implode"n"$test2 ) )
                {
                    
$conflict++;
                    
                    
$final[] = "<ips:conflict id="{$conflict}">";
                    
$final[] = "<ips:cblock type="original">";
                    
                    if ( 
count$test2 ) )
                    {
                        foreach( 
$test2 as $t )
                        {
                            
$final[] = $t;
                        }
                    }
                    
                    
$final[] = "</ips:cblock>";
                    
$final[] = "<ips:cblock type="new">";
                    
                    if ( 
count$test1 ) )
                    {
                        foreach( 
$test1 as $t )
                        {
                            
$final[] = $t;
                        }
                    }
                    
                    
$final[] = "</ips:cblock>";
                    
$final[] = "</ips:conflict>";
                }
                else
                {
                    if ( 
count$test1 ) )
                    {
                        foreach( 
$test1 as $t )
                        {
                            
$final[] =  $t;
                        }
                    }
                    
                    if ( 
count$test2 ) )
                    {
                        foreach( 
$test2 as $t )
                        {
                            
//$final[] =  $t;
                        
}
                    }
                    
                    
$final[] = $left['data'];
                }
            }
            else if ( 
$left['type'] == 'del' AND $right['type'] == 'ok' )
            {
                
/* Add in anything from left */
                
$final $this->_textToAddAtLine$orig_new_map$c$final'lnxx' );
                
                
/* One line or more exists in both? */
                
$final $this->_textToAddAtLine$orig_custom_map$c$final'lc--' );
            }
            else if ( 
$left['type'] == 'ok' AND $right['type'] == 'del' )
            {
                
/* Add in right */
                
$final $this->_textToAddAtLine$orig_custom_map$c$final'rcxx' );
                
                
/* Anything to add from the new side? */
                
$final $this->_textToAddAtLine$orig_new_map$c$final'rn--' );
            }
            else if ( 
$left['type'] == 'del' AND $right['type'] == 'del' )
            {
                
$test1 $this->_textToAddAtLine$orig_new_map$c );
                
$test2 $this->_textToAddAtLine$orig_custom_map$c );
                
                
/* Potential conflict, are both modifications to this line the same? */
                
if ( count$test1 ) AND count$test2 ) AND  implode"n"$test1 ) != implode"n"$test2 ) )
                {
                    
$conflict++;
                    
                    
$final[] = "<ips:conflict id="{$conflict}">";
                    
$final[] = "<ips:cblock type="original">";
                    
                    if ( 
count$test2 ) )
                    {
                        foreach( 
$test2 as $t )
                        {
                            
$final[] = $t;
                        }
                    }
                    
                    
$final[] = "</ips:cblock>";
                    
$final[] = "<ips:cblock type="new">";
                    
                    if ( 
count$test1 ) )
                    {
                        foreach( 
$test1 as $t )
                        {
                            
$final[] = $t;
                        }
                    }
                    
                    
$final[] = "</ips:cblock>";
                    
$final[] = "</ips:conflict>";
                }
                else
                {
                    if ( 
count$test1 ) )
                    {
                        foreach( 
$test1 as $t )
                        {
                            
/* We're removing, dumbass */
                            //$final[] = $c . ' dexx1' . $t;
                        
}
                    }
                        
                    if ( 
count$test2 ) )
                    {
                        foreach( 
$test2 as $t )
                        {
                            
/* We're removing, dumbass */
                            //$final[] = $c . ' dexx2 ' . $t;
                        
}
                    }
                }
            }
            
            
$c++;
        }
        
        return 
implode"n"$final );
    }
    
    
/**
     * Returns an array slice for the ORIG line number X
     *
     * @param    array        Re-processed Diff Array
     * @param    int            ORIG line number
     * @return    @e mixed
     */
    
protected function _sliceFromLineNumber$data$n )
    {
        foreach ( 
$data as $i )
        {
            if ( 
$i['line'] == $n AND $i['type'] != 'ins' )
            {
                return 
$i;
            }
        }
        
        return 
false;
    }
    
    
/**
     * Returns an array of lines to add at the current ORIG line number X
     *
     * @param    array        Re-processed Diff Array
     * @param    int            ORIG line number
     * @param    array         Array to add to
     * @param    string        Newline data (not used)
     * @return    @e array
     */
    
protected function _textToAddAtLine$data$n$return=array(), $p='' )
    {
        
$return = ( is_array$return ) AND count$return ) ) ? $return : array();
        
        foreach ( 
$data as $i )
        {
            if ( 
$i['line'] == $n AND $i['type'] == 'ins' )
            { 
                
$return[] = $i['data'];
            }
        }
        
        return 
$return;
    }
    
    
/**
     * Re-process DIFF.
     * Figures out mappings to original line numbers, etc
     *
     * @param    array         Array of DIFF data
     * @param    boolean        Log or not (unused)
     * @return    @e array
     */
    
protected function _fetchProcessed$data$log=)
    {
        
/* Counter to ensure unique entry in $return */
        
$c 0;
        
        
/* Counter to keep a corrilation with the original line numbering */
        
$n 0;
        
        
/* Variable to retain value of $n when processing insertion rows */
        
$old_n 0;
        
        
/* Flag to note if the previous row was a delete and therefore treat a proceeding insert as a replacement */
        
$delete_was_last 0;
        
        
/* Freeze the line number when we first see a delete line (assume that more may follow if removing a block */
        
$freeze 0;
        
        foreach( 
$data as $l )
        {        
            if ( 
substr$l0) == '+' )
            {
                
/* AAA: If the last line was a delete, this is treated as a replacement */
                
if ( $delete_was_last )
                {
                    
/* We want to ensure that the insert retains the same ORIGINAL line number as the FIRST line of the recent delete(s)
                      So we effectively 'freeze' N for the inserts and store what would be the next number in $old_n */
                    
$old_n = ( $old_n ) ? $old_n $n;
                    
$n     $freeze;
                }
                else if ( 
$freeze )
                {
                    
/* Ok, the previous was an insert after a delete line, so use the line number that would have been the first delete line number */
                    
$n $old_n;
                }
                
                
$return$c ] = array( 'data' => substr$l),
                                       
'type' => 'ins',
                                       
'line' => $n );
                
                
/* Delete was not last. Reset freeze flag */  
                
$delete_was_last 0;
                
$freeze          0;
            }
            else if ( 
substr$l0) == '-' )
            {
                
$return$c ] = array( 'data' => substr$l),
                                       
'type' => 'del',
                                       
'line' => $n );
                
                
/* We want to 'freeze' the line number if this is the first delete line */ 
                
$freeze = ( $delete_was_last ) ? $freeze $n;
                
                
/* AAA: We've just deleted a line, so flag this up because if an insert is next, then it's a replacement */
                
$delete_was_last 1;
                
                
/* BBB: We deleted a line from the original, so increment the original line number */
                
$n++;
            }
            else
            {
                
/* If this is a line after an insert or delete, use the old_n line number */
                
if ( $old_n )
                {
                    
$n $old_n;
                }
                
                
$return$c ] = array( 'data' => $l,
                                       
'type' => 'ok',
                                       
'line' => $n );
                                       
                
$n++;
                
$delete_was_last 0;
                
$freeze          0;
                
$old_n             0;
            }
            
            
$c++;
        }
        
        
//print_r( $return );
        
return $return;
    }
    
    
/**
     * Add debug messages
     *
     * @param    string        TITLE
     * @param    mixed        Data
     * @return    @e void
     */
    
protected function _addDebugMsg$title$data )
    {
        
$this->_DEBUG[] = $title "n" var_export$dataTRUE );
    }

}
Онлайн: 1
Реклама