class.t3lib_diff.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************
00003 *  Copyright notice
00004 *
00005 *  (c) 1999-2008 Kasper Skaarhoj (kasperYYYY@typo3.com)
00006 *  All rights reserved
00007 *
00008 *  This script is part of the TYPO3 project. The TYPO3 project is
00009 *  free software; you can redistribute it and/or modify
00010 *  it under the terms of the GNU General Public License as published by
00011 *  the Free Software Foundation; either version 2 of the License, or
00012 *  (at your option) any later version.
00013 *
00014 *  The GNU General Public License can be found at
00015 *  http://www.gnu.org/copyleft/gpl.html.
00016 *  A copy is found in the textfile GPL.txt and important notices to the license
00017 *  from the author is found in LICENSE.txt distributed with these scripts.
00018 *
00019 *
00020 *  This script is distributed in the hope that it will be useful,
00021 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023 *  GNU General Public License for more details.
00024 *
00025 *  This copyright notice MUST APPEAR in all copies of the script!
00026 ***************************************************************/
00027 /**
00028  * Contains class which has functions that generates a difference output of a content string
00029  *
00030  * $Id: class.t3lib_diff.php 3439 2008-03-16 19:16:51Z flyguide $
00031  * Revised for TYPO3 3.6 November/2003 by Kasper Skaarhoj
00032  * XHTML Compliant
00033  *
00034  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00035  */
00036 /**
00037  * [CLASS/FUNCTION INDEX of SCRIPT]
00038  *
00039  *
00040  *
00041  *   66: class t3lib_diff
00042  *   86:     function makeDiffDisplay($str1,$str2,$wrapTag='span')
00043  *  163:     function getDiff($str1,$str2)
00044  *  189:     function addClearBuffer($clearBuffer,$last=0)
00045  *  205:     function explodeStringIntoWords($str)
00046  *  226:     function tagSpace($str,$rev=0)
00047  *
00048  * TOTAL FUNCTIONS: 5
00049  * (This index is automatically created/updated by the extension "extdeveval")
00050  *
00051  */
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 /**
00060  * This class has functions which generates a difference output of a content string
00061  *
00062  * @author  Kasper Skaarhoj <kasperYYYY@typo3.com>
00063  * @package TYPO3
00064  * @subpackage t3lib
00065  */
00066 class t3lib_diff {
00067 
00068         // External, static:
00069     var $stripTags = 0;         // If set, the HTML tags are stripped from the input strings first.
00070     var $diffOptions = '';      // Diff options. eg "--unified=3"
00071 
00072         // Internal, dynamic:
00073     var $clearBufferIdx=0;      // This indicates the number of times the function addClearBuffer has been called - and used to detect the very first call...
00074     var $differenceLgd=0;
00075 
00076 
00077 
00078     /**
00079      * This will produce a color-marked-up diff output in HTML from the input strings.
00080      *
00081      * @param   string      String 1
00082      * @param   string      String 2
00083      * @param   string      Setting the wrapping tag name
00084      * @return  string      Formatted output.
00085      */
00086     function makeDiffDisplay($str1,$str2,$wrapTag='span')   {
00087         if ($this->stripTags)   {
00088             $str1 = strip_tags($str1);
00089             $str2 = strip_tags($str2);
00090         } else {
00091             $str1 = $this->tagSpace($str1);
00092             $str2 = $this->tagSpace($str2);
00093         }
00094         $str1Lines = $this->explodeStringIntoWords($str1);
00095         $str2Lines = $this->explodeStringIntoWords($str2);
00096 
00097         $diffRes = $this->getDiff(implode(chr(10),$str1Lines).chr(10),implode(chr(10),$str2Lines).chr(10));
00098 
00099         if (is_array($diffRes)) {
00100             reset($diffRes);
00101             $c=0;
00102             $diffResArray=array();
00103             $differenceStr = '';
00104             while(list(,$lValue)=each($diffRes))    {
00105                 if (intval($lValue))    {
00106                     $c=intval($lValue);
00107                     $diffResArray[$c]['changeInfo']=$lValue;
00108                 }
00109                 if (substr($lValue,0,1)=='<')   {
00110                     $differenceStr.= $diffResArray[$c]['old'][] = substr($lValue,2);
00111                 }
00112                 if (substr($lValue,0,1)=='>')   {
00113                     $differenceStr.= $diffResArray[$c]['new'][] = substr($lValue,2);
00114                 }
00115             }
00116 
00117             $this->differenceLgd = strlen($differenceStr);
00118 
00119             $outString='';
00120             $clearBuffer='';
00121             for ($a=-1;$a<count($str1Lines);$a++)   {
00122                 if (is_array($diffResArray[$a+1]))  {
00123                     if (strstr($diffResArray[$a+1]['changeInfo'],'a'))  {   // a=Add, c=change, d=delete: If a, then the content is Added after the entry and we must insert the line content as well.
00124                         $clearBuffer.=htmlspecialchars($str1Lines[$a]).' ';
00125                     }
00126 
00127                     $outString.=$this->addClearBuffer($clearBuffer);
00128                     $clearBuffer='';
00129                     if (is_array($diffResArray[$a+1]['old']))   {
00130                         $outString.='<'.$wrapTag.' class="diff-r">'.htmlspecialchars(implode(' ',$diffResArray[$a+1]['old'])).'</'.$wrapTag.'> ';
00131                     }
00132                     if (is_array($diffResArray[$a+1]['new']))   {
00133                         $outString.='<'.$wrapTag.' class="diff-g">'.htmlspecialchars(implode(' ',$diffResArray[$a+1]['new'])).'</'.$wrapTag.'> ';
00134                     }
00135                     $chInfParts = explode(',',$diffResArray[$a+1]['changeInfo']);
00136                     if (!strcmp($chInfParts[0],$a+1))   {
00137                         $newLine = intval($chInfParts[1])-1;
00138                         if ($newLine>$a)    $a=$newLine;    // Security that $a is not set lower than current for some reason...
00139                     }
00140                 } else {
00141                     $clearBuffer.=htmlspecialchars($str1Lines[$a]).' ';
00142                 }
00143             }
00144             $outString.=$this->addClearBuffer($clearBuffer,1);
00145 
00146             $outString = str_replace('  ',chr(10),$outString);
00147             if (!$this->stripTags)  {
00148                 $outString = $this->tagSpace($outString,1);
00149             }
00150             return $outString;
00151         }
00152     }
00153 
00154     /**
00155      * Produce a diff (using the "diff" application) between two strings
00156      * The function will write the two input strings to temporary files, then execute the diff program, delete the temp files and return the result.
00157      *
00158      * @param   string      String 1
00159      * @param   string      String 2
00160      * @return  array       The result from the exec() function call.
00161      * @access private
00162      */
00163     function getDiff($str1,$str2)   {
00164             // Create file 1 and write string
00165         $file1 = t3lib_div::tempnam('diff1_');
00166         t3lib_div::writeFile($file1,$str1);
00167             // Create file 2 and write string
00168         $file2 = t3lib_div::tempnam('diff2_');
00169         t3lib_div::writeFile($file2,$str2);
00170             // Perform diff.
00171         $cmd = $GLOBALS['TYPO3_CONF_VARS']['BE']['diff_path'].' '.$this->diffOptions.' '.$file1.' '.$file2;
00172         $res = array();
00173         exec($cmd,$res);
00174 
00175         unlink($file1);
00176         unlink($file2);
00177 
00178         return $res;
00179     }
00180 
00181     /**
00182      * Will bring down the length of strings to < 150 chars if they were longer than 200 chars. This done by preserving the 70 first and last chars and concatenate those strings with "..." and a number indicating the string length
00183      *
00184      * @param   string      The input string.
00185      * @param   boolean     If set, it indicates that the string should just end with ... (thus no "complete" ending)
00186      * @return  string      Processed string.
00187      * @access private
00188      */
00189     function addClearBuffer($clearBuffer,$last=0)   {
00190         if (strlen($clearBuffer)>200)   {
00191             $clearBuffer=($this->clearBufferIdx?t3lib_div::fixed_lgd_cs($clearBuffer,70):'').'['.strlen($clearBuffer).']'.(!$last?t3lib_div::fixed_lgd_cs($clearBuffer,-70):'');
00192         }
00193         $this->clearBufferIdx++;
00194         return $clearBuffer;
00195     }
00196 
00197     /**
00198      * Explodes the input string into words.
00199      * This is done by splitting first by lines, then by space char. Each word will be in stored as a value in an array. Lines will be indicated by two subsequent empty values.
00200      *
00201      * @param   string      The string input
00202      * @return  array       Array with words.
00203      * @access private
00204      */
00205     function explodeStringIntoWords($str)   {
00206         $strArr = t3lib_div::trimExplode(chr(10),$str);
00207         $outArray=array();
00208         reset($strArr);
00209         while(list(,$lineOfWords)=each($strArr))    {
00210             $allWords = t3lib_div::trimExplode(' ',$lineOfWords,1);
00211             $outArray = array_merge($outArray,$allWords);
00212             $outArray[]='';
00213             $outArray[]='';
00214         }
00215         return $outArray;
00216     }
00217 
00218     /**
00219      * Adds a space character before and after HTML tags (more precisely any found < or >)
00220      *
00221      * @param   string      String to process
00222      * @param   boolean     If set, the < > searched for will be &lt; and &gt;
00223      * @return  string      Processed string
00224      * @access private
00225      */
00226     function tagSpace($str,$rev=0)  {
00227         if ($rev)   {
00228             return str_replace(' &lt;','&lt;',str_replace('&gt; ','&gt;',$str));
00229         } else {
00230             return str_replace('<',' <',str_replace('>','> ',$str));
00231         }
00232     }
00233 }
00234 
00235 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_diff.php'])  {
00236     include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_diff.php']);
00237 }
00238 ?>

Generated on Sat Jan 3 04:23:26 2009 for TYPO3 API by  doxygen 1.4.7