[ Index ] |
PHP Cross Reference of MyBB |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * General API for generating and formatting diffs - the differences between 4 * two sequences of strings. 5 * 6 * The original PHP version of this code was written by Geoffrey T. Dairiki 7 * <dairiki@dairiki.org>, and is used/adapted with his permission. 8 * 9 * Copyright 2004 Geoffrey T. Dairiki <dairiki@dairiki.org> 10 * Copyright 2004-2011 Horde LLC (http://www.horde.org/) 11 * 12 * See the enclosed file COPYING for license information (LGPL). If you did 13 * not receive this file, see http://www.horde.org/licenses/lgpl21. 14 * 15 * @package Text_Diff 16 * @author Geoffrey T. Dairiki <dairiki@dairiki.org> 17 */ 18 19 // Disallow direct access to this file for security reasons 20 if(!defined("IN_MYBB")) 21 { 22 die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined."); 23 } 24 25 class Horde_Text_Diff 26 { 27 /** 28 * Array of changes. 29 * 30 * @var array 31 */ 32 protected $_edits; 33 34 /** 35 * Computes diffs between sequences of strings. 36 * 37 * @param string $engine Name of the diffing engine to use. 'auto' 38 * will automatically select the best. 39 * @param array $params Parameters to pass to the diffing engine. 40 * Normally an array of two arrays, each 41 * containing the lines from a file. 42 */ 43 public function __construct($engine, $params) 44 { 45 if ($engine == 'auto') { 46 $engine = extension_loaded('xdiff') ? 'Xdiff' : 'Native'; 47 } else { 48 $engine = Horde_String::ucfirst(basename($engine)); 49 } 50 51 // Fugly; Include operational classes required for Text_Diff 52 $classes = array( 53 'String.php', 54 "Engine/{$engine}.php", 55 'Renderer/Inline.php', 56 'Op/Base.php', 57 'Op/Copy.php', 58 'Op/Change.php', 59 'Op/Add.php', 60 'Op/Delete.php' 61 ); 62 63 foreach($classes as $class) 64 { 65 require_once MYBB_ROOT."inc/3rdparty/diff/Diff/{$class}"; 66 } 67 68 $class = 'Horde_Text_Diff_Engine_' . $engine; 69 $diff_engine = new $class(); 70 71 $this->_edits = call_user_func_array(array($diff_engine, 'diff'), $params); 72 } 73 74 /** 75 * Returns the array of differences. 76 */ 77 public function getDiff() 78 { 79 return $this->_edits; 80 } 81 82 /** 83 * returns the number of new (added) lines in a given diff. 84 * 85 * @since Text_Diff 1.1.0 86 * 87 * @return integer The number of new lines 88 */ 89 public function countAddedLines() 90 { 91 $count = 0; 92 foreach ($this->_edits as $edit) { 93 if ($edit instanceof Horde_Text_Diff_Op_Add || 94 $edit instanceof Horde_Text_Diff_Op_Change) { 95 $count += $edit->nfinal(); 96 } 97 } 98 return $count; 99 } 100 101 /** 102 * Returns the number of deleted (removed) lines in a given diff. 103 * 104 * @since Text_Diff 1.1.0 105 * 106 * @return integer The number of deleted lines 107 */ 108 public function countDeletedLines() 109 { 110 $count = 0; 111 foreach ($this->_edits as $edit) { 112 if ($edit instanceof Horde_Text_Diff_Op_Delete || 113 $edit instanceof Horde_Text_Diff_Op_Change) { 114 $count += $edit->norig(); 115 } 116 } 117 return $count; 118 } 119 120 /** 121 * Computes a reversed diff. 122 * 123 * Example: 124 * <code> 125 * $diff = new Horde_Text_Diff($lines1, $lines2); 126 * $rev = $diff->reverse(); 127 * </code> 128 * 129 * @return Horde_Text_Diff A Diff object representing the inverse of the 130 * original diff. Note that we purposely don't return a 131 * reference here, since this essentially is a clone() 132 * method. 133 */ 134 public function reverse() 135 { 136 if (version_compare(zend_version(), '2', '>')) { 137 $rev = clone($this); 138 } else { 139 $rev = $this; 140 } 141 $rev->_edits = array(); 142 foreach ($this->_edits as $edit) { 143 $rev->_edits[] = $edit->reverse(); 144 } 145 return $rev; 146 } 147 148 /** 149 * Checks for an empty diff. 150 * 151 * @return boolean True if two sequences were identical. 152 */ 153 public function isEmpty() 154 { 155 foreach ($this->_edits as $edit) { 156 if (!($edit instanceof Horde_Text_Diff_Op_Copy)) { 157 return false; 158 } 159 } 160 return true; 161 } 162 163 /** 164 * Computes the length of the Longest Common Subsequence (LCS). 165 * 166 * This is mostly for diagnostic purposes. 167 * 168 * @return integer The length of the LCS. 169 */ 170 public function lcs() 171 { 172 $lcs = 0; 173 foreach ($this->_edits as $edit) { 174 if ($edit instanceof Horde_Text_Diff_Op_Copy) { 175 $lcs += count($edit->orig); 176 } 177 } 178 return $lcs; 179 } 180 181 /** 182 * Gets the original set of lines. 183 * 184 * This reconstructs the $from_lines parameter passed to the constructor. 185 * 186 * @return array The original sequence of strings. 187 */ 188 public function getOriginal() 189 { 190 $lines = array(); 191 foreach ($this->_edits as $edit) { 192 if ($edit->orig) { 193 array_splice($lines, count($lines), 0, $edit->orig); 194 } 195 } 196 return $lines; 197 } 198 199 /** 200 * Gets the final set of lines. 201 * 202 * This reconstructs the $to_lines parameter passed to the constructor. 203 * 204 * @return array The sequence of strings. 205 */ 206 public function getFinal() 207 { 208 $lines = array(); 209 foreach ($this->_edits as $edit) { 210 if ($edit->final) { 211 array_splice($lines, count($lines), 0, $edit->final); 212 } 213 } 214 return $lines; 215 } 216 217 /** 218 * Removes trailing newlines from a line of text. This is meant to be used 219 * with array_walk(). 220 * 221 * @param string $line The line to trim. 222 * @param integer $key The index of the line in the array. Not used. 223 */ 224 static public function trimNewlines(&$line, $key) 225 { 226 $line = str_replace(array("\n", "\r"), '', $line); 227 } 228 229 /** 230 * Checks a diff for validity. 231 * 232 * This is here only for debugging purposes. 233 */ 234 protected function _check($from_lines, $to_lines) 235 { 236 if (serialize($from_lines) != serialize($this->getOriginal())) { 237 trigger_error("Reconstructed original doesn't match", E_USER_ERROR); 238 } 239 if (serialize($to_lines) != serialize($this->getFinal())) { 240 trigger_error("Reconstructed final doesn't match", E_USER_ERROR); 241 } 242 243 $rev = $this->reverse(); 244 if (serialize($to_lines) != serialize($rev->getOriginal())) { 245 trigger_error("Reversed original doesn't match", E_USER_ERROR); 246 } 247 if (serialize($from_lines) != serialize($rev->getFinal())) { 248 trigger_error("Reversed final doesn't match", E_USER_ERROR); 249 } 250 251 $prevtype = null; 252 foreach ($this->_edits as $edit) { 253 if ($prevtype == get_class($edit)) { 254 trigger_error("Edit sequence is non-optimal", E_USER_ERROR); 255 } 256 $prevtype = get_class($edit); 257 } 258 259 return true; 260 } 261 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Oct 8 19:19:50 2013 | Cross-referenced by PHPXref 0.7.1 |