[ Index ] |
PHP Cross Reference of MyBB |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Class used internally by Diff to actually compute the diffs. 4 * 5 * This class uses the Unix `diff` program via shell_exec to compute the 6 * differences between the two input arrays. 7 * 8 * Copyright 2007-2011 Horde LLC (http://www.horde.org/) 9 * 10 * See the enclosed file COPYING for license information (LGPL). If you did 11 * not receive this file, see http://www.horde.org/licenses/lgpl21. 12 * 13 * @author Milian Wolff <mail@milianw.de> 14 * @package Text_Diff 15 */ 16 17 // Disallow direct access to this file for security reasons 18 if(!defined("IN_MYBB")) 19 { 20 die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined."); 21 } 22 23 class Horde_Text_Diff_Engine_Shell 24 { 25 /** 26 * Path to the diff executable 27 * 28 * @var string 29 */ 30 protected $_diffCommand = 'diff'; 31 32 /** 33 * Returns the array of differences. 34 * 35 * @param array $from_lines lines of text from old file 36 * @param array $to_lines lines of text from new file 37 * 38 * @return array all changes made (array with Horde_Text_Diff_Op_* objects) 39 */ 40 public function diff($from_lines, $to_lines) 41 { 42 array_walk($from_lines, array('Horde_Text_Diff', 'trimNewlines')); 43 array_walk($to_lines, array('Horde_Text_Diff', 'trimNewlines')); 44 45 // Execute gnu diff or similar to get a standard diff file. 46 $from_file = Horde_Util::getTempFile('Horde_Text_Diff'); 47 $to_file = Horde_Util::getTempFile('Horde_Text_Diff'); 48 $fp = fopen($from_file, 'w'); 49 fwrite($fp, implode("\n", $from_lines)); 50 fclose($fp); 51 $fp = fopen($to_file, 'w'); 52 fwrite($fp, implode("\n", $to_lines)); 53 fclose($fp); 54 $diff = shell_exec($this->_diffCommand . ' ' . $from_file . ' ' . $to_file); 55 unlink($from_file); 56 unlink($to_file); 57 58 if (is_null($diff)) { 59 // No changes were made 60 return array(new Horde_Text_Diff_Op_Copy($from_lines)); 61 } 62 63 $from_line_no = 1; 64 $to_line_no = 1; 65 $edits = array(); 66 67 // Get changed lines by parsing something like: 68 // 0a1,2 69 // 1,2c4,6 70 // 1,5d6 71 preg_match_all('#^(\d+)(?:,(\d+))?([adc])(\d+)(?:,(\d+))?$#m', $diff, 72 $matches, PREG_SET_ORDER); 73 74 foreach ($matches as $match) { 75 if (!isset($match[5])) { 76 // This paren is not set every time (see regex). 77 $match[5] = false; 78 } 79 80 if ($match[3] == 'a') { 81 $from_line_no--; 82 } 83 84 if ($match[3] == 'd') { 85 $to_line_no--; 86 } 87 88 if ($from_line_no < $match[1] || $to_line_no < $match[4]) { 89 // copied lines 90 assert('$match[1] - $from_line_no == $match[4] - $to_line_no'); 91 array_push($edits, 92 new Horde_Text_Diff_Op_Copy( 93 $this->_getLines($from_lines, $from_line_no, $match[1] - 1), 94 $this->_getLines($to_lines, $to_line_no, $match[4] - 1))); 95 } 96 97 switch ($match[3]) { 98 case 'd': 99 // deleted lines 100 array_push($edits, 101 new Horde_Text_Diff_Op_Delete( 102 $this->_getLines($from_lines, $from_line_no, $match[2]))); 103 $to_line_no++; 104 break; 105 106 case 'c': 107 // changed lines 108 array_push($edits, 109 new Horde_Text_Diff_Op_Change( 110 $this->_getLines($from_lines, $from_line_no, $match[2]), 111 $this->_getLines($to_lines, $to_line_no, $match[5]))); 112 break; 113 114 case 'a': 115 // added lines 116 array_push($edits, 117 new Horde_Text_Diff_Op_Add( 118 $this->_getLines($to_lines, $to_line_no, $match[5]))); 119 $from_line_no++; 120 break; 121 } 122 } 123 124 if (!empty($from_lines)) { 125 // Some lines might still be pending. Add them as copied 126 array_push($edits, 127 new Horde_Text_Diff_Op_Copy( 128 $this->_getLines($from_lines, $from_line_no, 129 $from_line_no + count($from_lines) - 1), 130 $this->_getLines($to_lines, $to_line_no, 131 $to_line_no + count($to_lines) - 1))); 132 } 133 134 return $edits; 135 } 136 137 /** 138 * Get lines from either the old or new text 139 * 140 * @access private 141 * 142 * @param array &$text_lines Either $from_lines or $to_lines 143 * @param int &$line_no Current line number 144 * @param int $end Optional end line, when we want to chop more 145 * than one line. 146 * 147 * @return array The chopped lines 148 */ 149 protected function _getLines(&$text_lines, &$line_no, $end = false) 150 { 151 if (!empty($end)) { 152 $lines = array(); 153 // We can shift even more 154 while ($line_no <= $end) { 155 array_push($lines, array_shift($text_lines)); 156 $line_no++; 157 } 158 } else { 159 $lines = array(array_shift($text_lines)); 160 $line_no++; 161 } 162 163 return $lines; 164 } 165 }
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 |