Text_Diff

General API for generating and formatting diffs - the differences between two sequences of strings.

Defined (1)

The class is defined in the following location(s).

/wp-includes/Text/Diff.php  
  1. class Text_Diff { 
  2.  
  3. /** 
  4. * Array of changes. 
  5. * @var array 
  6. */ 
  7. var $_edits; 
  8.  
  9. /** 
  10. * Computes diffs between sequences of strings. 
  11. * @param string $engine Name of the diffing engine to use. 'auto' 
  12. * will automatically select the best. 
  13. * @param array $params Parameters to pass to the diffing engine. 
  14. * Normally an array of two arrays, each 
  15. * containing the lines from a file. 
  16. */ 
  17. function __construct( $engine, $params ) 
  18. // Backward compatibility workaround. 
  19. if (!is_string($engine)) { 
  20. $params = array($engine, $params); 
  21. $engine = 'auto'; 
  22.  
  23. if ($engine == 'auto') { 
  24. $engine = extension_loaded('xdiff') ? 'xdiff' : 'native'; 
  25. } else { 
  26. $engine = basename($engine); 
  27.  
  28. // WP #7391 
  29. require_once dirname(__FILE__).'/Diff/Engine/' . $engine . '.php'; 
  30. $class = 'Text_Diff_Engine_' . $engine; 
  31. $diff_engine = new $class(); 
  32.  
  33. $this->_edits = call_user_func_array(array($diff_engine, 'diff'), $params); 
  34.  
  35. /** 
  36. * PHP4 constructor. 
  37. */ 
  38. public function Text_Diff( $engine, $params ) { 
  39. self::__construct( $engine, $params ); 
  40.  
  41. /** 
  42. * Returns the array of differences. 
  43. */ 
  44. function getDiff() 
  45. return $this->_edits; 
  46.  
  47. /** 
  48. * returns the number of new (added) lines in a given diff. 
  49. * @since Text_Diff 1.1.0 
  50. * @return integer The number of new lines 
  51. */ 
  52. function countAddedLines() 
  53. $count = 0; 
  54. foreach ($this->_edits as $edit) { 
  55. if (is_a($edit, 'Text_Diff_Op_add') || 
  56. is_a($edit, 'Text_Diff_Op_change')) { 
  57. $count += $edit->nfinal(); 
  58. return $count; 
  59.  
  60. /** 
  61. * Returns the number of deleted (removed) lines in a given diff. 
  62. * @since Text_Diff 1.1.0 
  63. * @return integer The number of deleted lines 
  64. */ 
  65. function countDeletedLines() 
  66. $count = 0; 
  67. foreach ($this->_edits as $edit) { 
  68. if (is_a($edit, 'Text_Diff_Op_delete') || 
  69. is_a($edit, 'Text_Diff_Op_change')) { 
  70. $count += $edit->norig(); 
  71. return $count; 
  72.  
  73. /** 
  74. * Computes a reversed diff. 
  75. * Example: 
  76. * <code> 
  77. * $diff = new Text_Diff($lines1, $lines2); 
  78. * $rev = $diff->reverse(); 
  79. * </code> 
  80. * @return Text_Diff A Diff object representing the inverse of the 
  81. * original diff. Note that we purposely don't return a 
  82. * reference here, since this essentially is a clone() 
  83. * method. 
  84. */ 
  85. function reverse() 
  86. if (version_compare(zend_version(), '2', '>')) { 
  87. $rev = clone($this); 
  88. } else { 
  89. $rev = $this; 
  90. $rev->_edits = array(); 
  91. foreach ($this->_edits as $edit) { 
  92. $rev->_edits[] = $edit->reverse(); 
  93. return $rev; 
  94.  
  95. /** 
  96. * Checks for an empty diff. 
  97. * @return boolean True if two sequences were identical. 
  98. */ 
  99. function isEmpty() 
  100. foreach ($this->_edits as $edit) { 
  101. if (!is_a($edit, 'Text_Diff_Op_copy')) { 
  102. return false; 
  103. return true; 
  104.  
  105. /** 
  106. * Computes the length of the Longest Common Subsequence (LCS). 
  107. * This is mostly for diagnostic purposes. 
  108. * @return integer The length of the LCS. 
  109. */ 
  110. function lcs() 
  111. $lcs = 0; 
  112. foreach ($this->_edits as $edit) { 
  113. if (is_a($edit, 'Text_Diff_Op_copy')) { 
  114. $lcs += count($edit->orig); 
  115. return $lcs; 
  116.  
  117. /** 
  118. * Gets the original set of lines. 
  119. * This reconstructs the $from_lines parameter passed to the constructor. 
  120. * @return array The original sequence of strings. 
  121. */ 
  122. function getOriginal() 
  123. $lines = array(); 
  124. foreach ($this->_edits as $edit) { 
  125. if ($edit->orig) { 
  126. array_splice($lines, count($lines), 0, $edit->orig); 
  127. return $lines; 
  128.  
  129. /** 
  130. * Gets the final set of lines. 
  131. * This reconstructs the $to_lines parameter passed to the constructor. 
  132. * @return array The sequence of strings. 
  133. */ 
  134. function getFinal() 
  135. $lines = array(); 
  136. foreach ($this->_edits as $edit) { 
  137. if ($edit->final) { 
  138. array_splice($lines, count($lines), 0, $edit->final); 
  139. return $lines; 
  140.  
  141. /** 
  142. * Removes trailing newlines from a line of text. This is meant to be used 
  143. * with array_walk(). 
  144. * @param string $line The line to trim. 
  145. * @param integer $key The index of the line in the array. Not used. 
  146. */ 
  147. static function trimNewlines(&$line, $key) 
  148. $line = str_replace(array("\n", "\r"), '', $line); 
  149.  
  150. /** 
  151. * Determines the location of the system temporary directory. 
  152. * @static 
  153. * @access protected 
  154. * @return string A directory name which can be used for temp files. 
  155. * Returns false if one could not be found. 
  156. */ 
  157. function _getTempDir() 
  158. $tmp_locations = array('/tmp', '/var/tmp', 'c:\WUTemp', 'c:\temp',  
  159. 'c:\windows\temp', 'c:\winnt\temp'); 
  160.  
  161. /** Try PHP's upload_tmp_dir directive. */ 
  162. $tmp = ini_get('upload_tmp_dir'); 
  163.  
  164. /** Otherwise, try to determine the TMPDIR environment variable. */ 
  165. if (!strlen($tmp)) { 
  166. $tmp = getenv('TMPDIR'); 
  167.  
  168. /** If we still cannot determine a value, then cycle through a list of 
  169. * preset possibilities. */ 
  170. while (!strlen($tmp) && count($tmp_locations)) { 
  171. $tmp_check = array_shift($tmp_locations); 
  172. if (@is_dir($tmp_check)) { 
  173. $tmp = $tmp_check; 
  174.  
  175. /** If it is still empty, we have failed, so return false; otherwise 
  176. * return the directory determined. */ 
  177. return strlen($tmp) ? $tmp : false; 
  178.  
  179. /** 
  180. * Checks a diff for validity. 
  181. * This is here only for debugging purposes. 
  182. */ 
  183. function _check($from_lines, $to_lines) 
  184. if (serialize($from_lines) != serialize($this->getOriginal())) { 
  185. trigger_error("Reconstructed original doesn't match", E_USER_ERROR); 
  186. if (serialize($to_lines) != serialize($this->getFinal())) { 
  187. trigger_error("Reconstructed final doesn't match", E_USER_ERROR); 
  188.  
  189. $rev = $this->reverse(); 
  190. if (serialize($to_lines) != serialize($rev->getOriginal())) { 
  191. trigger_error("Reversed original doesn't match", E_USER_ERROR); 
  192. if (serialize($from_lines) != serialize($rev->getFinal())) { 
  193. trigger_error("Reversed final doesn't match", E_USER_ERROR); 
  194.  
  195. $prevtype = null; 
  196. foreach ($this->_edits as $edit) { 
  197. if ($prevtype == get_class($edit)) { 
  198. trigger_error("Edit sequence is non-optimal", E_USER_ERROR); 
  199. $prevtype = get_class($edit); 
  200.  
  201. return true; 
  202.