1<?php 2 3namespace Drupal\Component\Diff; 4 5use Drupal\Component\Diff\Engine\HWLDFWordAccumulator; 6 7/** 8 * @todo document 9 * @private 10 * @subpackage DifferenceEngine 11 */ 12class WordLevelDiff extends MappedDiff { 13 14 const MAX_LINE_LENGTH = 10000; 15 16 public function __construct($orig_lines, $closing_lines) { 17 list($orig_words, $orig_stripped) = $this->_split($orig_lines); 18 list($closing_words, $closing_stripped) = $this->_split($closing_lines); 19 20 parent::__construct($orig_words, $closing_words, $orig_stripped, $closing_stripped); 21 } 22 23 protected function _split($lines) { 24 $words = []; 25 $stripped = []; 26 $first = TRUE; 27 foreach ($lines as $line) { 28 // If the line is too long, just pretend the entire line is one big word 29 // This prevents resource exhaustion problems 30 if ( $first ) { 31 $first = FALSE; 32 } 33 else { 34 $words[] = "\n"; 35 $stripped[] = "\n"; 36 } 37 if (mb_strlen($line) > $this::MAX_LINE_LENGTH) { 38 $words[] = $line; 39 $stripped[] = $line; 40 } 41 else { 42 if (preg_match_all('/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs', $line, $m)) { 43 $words = array_merge($words, $m[0]); 44 $stripped = array_merge($stripped, $m[1]); 45 } 46 } 47 } 48 return [$words, $stripped]; 49 } 50 51 public function orig() { 52 $orig = new HWLDFWordAccumulator(); 53 54 foreach ($this->edits as $edit) { 55 if ($edit->type == 'copy') { 56 $orig->addWords($edit->orig); 57 } 58 elseif ($edit->orig) { 59 $orig->addWords($edit->orig, 'mark'); 60 } 61 } 62 $lines = $orig->getLines(); 63 return $lines; 64 } 65 66 public function closing() { 67 $closing = new HWLDFWordAccumulator(); 68 69 foreach ($this->edits as $edit) { 70 if ($edit->type == 'copy') { 71 $closing->addWords($edit->closing); 72 } 73 elseif ($edit->closing) { 74 $closing->addWords($edit->closing, 'mark'); 75 } 76 } 77 $lines = $closing->getLines(); 78 return $lines; 79 } 80 81} 82