[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/inc/3rdparty/diff/ -> Diff.php (source)

   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  }


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1