[ Index ] |
PHP Cross Reference of MyBB 1.8.38 |
[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-2017 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 * @return integer The number of new lines 86 */ 87 public function countAddedLines() 88 { 89 $count = 0; 90 foreach ($this->_edits as $edit) { 91 if ($edit instanceof Horde_Text_Diff_Op_Add || 92 $edit instanceof Horde_Text_Diff_Op_Change) { 93 $count += $edit->nfinal(); 94 } 95 } 96 return $count; 97 } 98 99 /** 100 * Returns the number of deleted (removed) lines in a given diff. 101 * 102 * @return integer The number of deleted lines 103 */ 104 public function countDeletedLines() 105 { 106 $count = 0; 107 foreach ($this->_edits as $edit) { 108 if ($edit instanceof Horde_Text_Diff_Op_Delete || 109 $edit instanceof Horde_Text_Diff_Op_Change) { 110 $count += $edit->norig(); 111 } 112 } 113 return $count; 114 } 115 116 /** 117 * Computes a reversed diff. 118 * 119 * Example: 120 * <code> 121 * $diff = new Horde_Text_Diff($lines1, $lines2); 122 * $rev = $diff->reverse(); 123 * </code> 124 * 125 * @return Horde_Text_Diff A Diff object representing the inverse of the 126 * original diff. Note that we purposely don't return a 127 * reference here, since this essentially is a clone() 128 * method. 129 */ 130 public function reverse() 131 { 132 if (version_compare(zend_version(), '2', '>')) { 133 $rev = clone($this); 134 } else { 135 $rev = $this; 136 } 137 $rev->_edits = array(); 138 foreach ($this->_edits as $edit) { 139 $rev->_edits[] = $edit->reverse(); 140 } 141 return $rev; 142 } 143 144 /** 145 * Checks for an empty diff. 146 * 147 * @return boolean True if two sequences were identical. 148 */ 149 public function isEmpty() 150 { 151 foreach ($this->_edits as $edit) { 152 if (!($edit instanceof Horde_Text_Diff_Op_Copy)) { 153 return false; 154 } 155 } 156 return true; 157 } 158 159 /** 160 * Computes the length of the Longest Common Subsequence (LCS). 161 * 162 * This is mostly for diagnostic purposes. 163 * 164 * @return integer The length of the LCS. 165 */ 166 public function lcs() 167 { 168 $lcs = 0; 169 foreach ($this->_edits as $edit) { 170 if ($edit instanceof Horde_Text_Diff_Op_Copy) { 171 $lcs += count($edit->orig); 172 } 173 } 174 return $lcs; 175 } 176 177 /** 178 * Gets the original set of lines. 179 * 180 * This reconstructs the $from_lines parameter passed to the constructor. 181 * 182 * @return array The original sequence of strings. 183 */ 184 public function getOriginal() 185 { 186 $lines = array(); 187 foreach ($this->_edits as $edit) { 188 if ($edit->orig) { 189 array_splice($lines, count($lines), 0, $edit->orig); 190 } 191 } 192 return $lines; 193 } 194 195 /** 196 * Gets the final set of lines. 197 * 198 * This reconstructs the $to_lines parameter passed to the constructor. 199 * 200 * @return array The sequence of strings. 201 */ 202 public function getFinal() 203 { 204 $lines = array(); 205 foreach ($this->_edits as $edit) { 206 if ($edit->final) { 207 array_splice($lines, count($lines), 0, $edit->final); 208 } 209 } 210 return $lines; 211 } 212 213 /** 214 * Removes trailing newlines from a line of text. This is meant to be used 215 * with array_walk(). 216 * 217 * @param string $line The line to trim. 218 * @param integer $key The index of the line in the array. Not used. 219 */ 220 public static function trimNewlines(&$line, $key) 221 { 222 $line = str_replace(array("\n", "\r"), '', $line); 223 } 224 225 /** 226 * Checks a diff for validity. 227 * 228 * This is here only for debugging purposes. 229 */ 230 protected function _check($from_lines, $to_lines) 231 { 232 if (serialize($from_lines) != serialize($this->getOriginal())) { 233 trigger_error("Reconstructed original doesn't match", E_USER_ERROR); 234 } 235 if (serialize($to_lines) != serialize($this->getFinal())) { 236 trigger_error("Reconstructed final doesn't match", E_USER_ERROR); 237 } 238 239 $rev = $this->reverse(); 240 if (serialize($to_lines) != serialize($rev->getOriginal())) { 241 trigger_error("Reversed original doesn't match", E_USER_ERROR); 242 } 243 if (serialize($from_lines) != serialize($rev->getFinal())) { 244 trigger_error("Reversed final doesn't match", E_USER_ERROR); 245 } 246 247 $prevtype = null; 248 foreach ($this->_edits as $edit) { 249 if ($prevtype == get_class($edit)) { 250 trigger_error("Edit sequence is non-optimal", E_USER_ERROR); 251 } 252 $prevtype = get_class($edit); 253 } 254 255 return true; 256 } 257 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup | Cross-referenced by PHPXref |