/**
 * Computes the two textes and returns an array with the changes needed
 * to trade back to the old text.
 *
 * @author Johannes Klose <*****@*****.**>
 * @param  string $text1 The old text
 * @param  string $text2 The new text
 * @return array         Differences between $text1 and $text2
 **/
function getDiff($text1, $text2)
{
    $lines1 = explode("\n", $text1);
    $lines2 = explode("\n", $text2);
    $obj = new Text_Diff($lines2, $lines1);
    $diff = $obj->getDiff();
    $ndiff = array();
    $lines = 0;
    /**
     * Take the array with the differences and strip
     * informations (unchanged lines, old values on changed lines)
     * we do not need to store in the database to get from the
     * new page version to the old one.
     **/
    foreach ($diff as $op) {
        if (strtolower(get_class($op)) == 'text_diff_op_copy') {
            $lines += count($op->orig);
            continue;
        } elseif (strtolower(get_class($op)) == 'text_diff_op_change') {
            if (count($op->orig) == count($op->final)) {
                foreach ($op->final as $key => $val) {
                    if (isset($op->orig[$key])) {
                        $ndiff[$lines + $key] = array('~', $val);
                    } else {
                        $ndiff[$lines + $key] = array('+', $val);
                    }
                }
            } elseif (count($op->orig) > count($op->final)) {
                foreach ($op->orig as $key => $val) {
                    if (isset($op->final[$key])) {
                        $ndiff[$lines + $key] = array('~', $op->final[$key]);
                    } else {
                        $ndiff[$lines + $key] = array('-');
                    }
                }
            } else {
                foreach ($op->final as $key => $val) {
                    if (isset($op->orig[$key])) {
                        $ndiff[$lines + $key] = array('~', $op->final[$key]);
                    } else {
                        $ndiff[$lines + $key] = array('+', $op->final[$key]);
                    }
                }
            }
        } elseif (strtolower(get_class($op)) == 'text_diff_op_add') {
            foreach ($op->final as $key => $val) {
                $ndiff[$lines + $key] = array('+', $val);
            }
        } elseif (strtolower(get_class($op)) == 'text_diff_op_delete') {
            foreach ($op->orig as $key => $val) {
                $ndiff[$lines + $key] = array('-');
            }
        }
        $lines += count($op->orig) > count($op->final) ? count($op->orig) : count($op->final);
    }
    return $ndiff;
}
Beispiel #2
0
 /**
  * Renders a diff.
  *
  * @param Text_Diff $diff  A Text_Diff object.
  *
  * @return string  The formatted output.
  */
 function render($diff)
 {
     $xi = $yi = 1;
     $block = false;
     $context = array();
     $nlead = $this->_leading_context_lines;
     $ntrail = $this->_trailing_context_lines;
     $output = $this->_startDiff();
     $diffs = $diff->getDiff();
     foreach ($diffs as $i => $edit) {
         if (is_a($edit, 'Text_Diff_Op_copy')) {
             if (is_array($block)) {
                 $keep = $i == count($diffs) - 1 ? $ntrail : $nlead + $ntrail;
                 if (count($edit->orig) <= $keep) {
                     $block[] = $edit;
                 } else {
                     if ($ntrail) {
                         $context = array_slice($edit->orig, 0, $ntrail);
                         $block[] =& new Text_Diff_Op_copy($context);
                     }
                     $output .= $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
                     $block = false;
                 }
             }
             $context = $edit->orig;
         } else {
             if (!is_array($block)) {
                 $context = array_slice($context, count($context) - $nlead);
                 $x0 = $xi - count($context);
                 $y0 = $yi - count($context);
                 $block = array();
                 if ($context) {
                     $block[] =& new Text_Diff_Op_copy($context);
                 }
             }
             $block[] = $edit;
         }
         if ($edit->orig) {
             $xi += count($edit->orig);
         }
         if ($edit->final) {
             $yi += count($edit->final);
         }
     }
     if (is_array($block)) {
         $output .= $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
     }
     return $output . $this->_endDiff();
 }
Beispiel #3
0
 /**
  * Renders a diff.
  *
  * @param Text_Diff $diff  A Text_Diff object.
  *
  * @return string  The formatted output.
  */
 function render($diff)
 {
     $xi = $yi = 1;
     $block = false;
     $context = array();
     $nlead = $this->_leading_context_lines;
     $ntrail = $this->_trailing_context_lines;
     $output = $this->_startDiff();
     $diffs = $diff->getDiff();
     foreach ($diffs as $i => $edit) {
         /* If these are unchanged (copied) lines, and we want to keep
          * leading or trailing context lines, extract them from the copy
          * block. */
         if (is_a($edit, 'Text_Diff_Op_copy')) {
             /* Do we have any diff blocks yet? */
             if (is_array($block)) {
                 /* How many lines to keep as context from the copy
                  * block. */
                 $keep = $i == count($diffs) - 1 ? $ntrail : $nlead + $ntrail;
                 if (count($edit->orig) <= $keep) {
                     /* We have less lines in the block than we want for
                      * context => keep the whole block. */
                     $block[] = $edit;
                 } else {
                     if ($ntrail) {
                         /* Create a new block with as many lines as we need
                          * for the trailing context. */
                         $context = array_slice($edit->orig, 0, $ntrail);
                         $block[] = new Text_Diff_Op_copy($context);
                     }
                     /* @todo */
                     $output .= $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
                     $block = false;
                 }
             }
             /* Keep the copy block as the context for the next block. */
             $context = $edit->orig;
         } else {
             /* Don't we have any diff blocks yet? */
             if (!is_array($block)) {
                 /* Extract context lines from the preceding copy block. */
                 $context = array_slice($context, count($context) - $nlead);
                 $x0 = $xi - count($context);
                 $y0 = $yi - count($context);
                 $block = array();
                 if ($context) {
                     $block[] = new Text_Diff_Op_copy($context);
                 }
             }
             $block[] = $edit;
         }
         if ($edit->orig) {
             $xi += count($edit->orig);
         }
         if ($edit->final) {
             $yi += count($edit->final);
         }
     }
     if (is_array($block)) {
         $output .= $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
     }
     return $output . $this->_endDiff();
 }
Beispiel #4
0
	/**
	 * 
	 * merges a newer version of a page into the current document
	 * @param string	$newpage	a string with a later version of the page
	 * @param string	$newauthor	name of the author of the new version
	 */
	function mergeDiff($newpage, $newauthor)
	{
		global $tikilib;
		$this->_history=false;
		$author=$newauthor;
		$deleted=false;
		$deleted_by='';
		$newdoc=array();
		$page=preg_replace(array('/\{AUTHOR\(.+?\)\}/','/{AUTHOR\}/','/\{INCLUDE\(.+?\)\}\{INCLUDE\}/'), ' ~np~$0~/np~', $newpage);
		if ($this->_parsed) {
			$page=$tikilib->parse_data($page, array('suppress_icons'=>true));
			$page=preg_replace(array('/\{AUTHOR\(.+?\)\}/','/{AUTHOR\}/','/\{INCLUDE\(.+?\)\}\{INCLUDE\}/'), ' ~np~$0~/np~', $page);
		}
		if ($this->_nohtml) {
			$page=strip_tags($page);
		}
		preg_match_all($this->_search, $page, $out, PREG_PATTERN_ORDER);
		$new=$out[0];
		$z = new Text_Diff($this->getDiffArray(), $new);
		$pos=0;
		foreach ($z->getDiff() as $element) {
			if (is_a($element, 'Text_Diff_Op_copy')) {
				$this->moveWords($newdoc, $pos, $element->orig, $deleted, $deleted_by);
			} else {
				if (is_a($element, 'Text_Diff_Op_add')) {
					$newdoc=$this->addWords($newdoc, $element->final, $author, $deleted, $deleted_by);
				} else {
					if (is_a($element, 'Text_Diff_Op_delete')) {
						$this->moveWords($newdoc, $pos, $element->orig, $deleted, $author);
					} else { //change
						$newdoc=$this->addWords($newdoc, $element->final, $author, $deleted, $deleted_by);
						$this->moveWords($newdoc, $pos, $element->orig, true, $author);
					} //delete
				} // add
			} // copy
		} // foreach diff
		$this->_document=$newdoc;
	}
Beispiel #5
0
         $end += strspn($text, $delimiter, $end);
         if ($end === $start) {
             break;
         }
         $fragments[] = substr($text, $start, $end - $start);
         $start = $end;
     }
     return $fragments;
 }
 $from_fragments = extractFragments($from, $delimiters[$granularity]);
 $to_fragments = extractFragments($to, $delimiters[$granularity]);
 $diff = new Text_Diff('native', array($from_fragments, $to_fragments));
 $exec_time = sprintf('%.3f sec', gettimeofday(true) - $start_time);
 $edits = array();
 ob_start();
 foreach ($diff->getDiff() as $edit) {
     if ($edit instanceof Text_Diff_Op_copy) {
         $orig = str_replace(array("", ""), array("\n", "\r"), implode('', $edit->orig));
         $edits[] = new fineDiffCopyOp(strlen($orig));
         echo htmlentities($orig);
     } else {
         if ($edit instanceof Text_Diff_Op_delete) {
             $orig = str_replace(array("", ""), array("\n", "\r"), implode('', $edit->orig));
             $edits[] = new fineDiffDeleteOp(strlen($orig));
             echo '<del>', htmlentities($orig), '</del>';
         } else {
             if ($edit instanceof Text_Diff_Op_add) {
                 $final = str_replace(array("", ""), array("\n", "\r"), implode('', $edit->final));
                 $edits[] = new fineDiffInsertOp($final);
                 echo '<ins>', htmlentities($final), '</ins>';
             } else {
Beispiel #6
0
 function diffLatestWithArchive($archive = 0)
 {
     include_once "lib/diff/Diff.php";
     $textDiff = new Text_Diff(FileGallery_File::id($this->getParam('fileId'))->archive($archive)->data(), $this->data());
     return $textDiff->getDiff();
 }
Beispiel #7
0
 function diff_sheets_as_html($id, $dates = null)
 {
     global $prefs, $sheetlib;
     function count_longest($array1, $array2)
     {
         return count($array1) > count($array2) ? count($array1) : count($array2);
     }
     function join_with_sub_grids($id, $date)
     {
         global $prefs, $sheetlib;
         $result1 = "";
         $result2 = "";
         $handler = new TikiSheetDatabaseHandler($id, $date);
         $handler->setReadDate($date);
         $grid = new TikiSheet();
         $grid->import($handler);
         $childSheetIds = $sheetlib->get_related_sheet_ids($grid->id);
         $i = 0;
         $grids = array($grid);
         foreach ($childSheetIds as $childSheetId) {
             $handler = new TikiSheetDatabaseHandler($childSheetId, $date);
             $handler->setReadDate($date);
             $childSheet = new TikiSheet();
             $childSheet->import($handler);
             array_push($grids, $childSheet);
             $i++;
         }
         return $grids;
     }
     function sanitize_for_diff($val)
     {
         $val = str_replace("<br/>", "<br>", $val);
         $val = str_replace("<br />", "<br>", $val);
         $val = str_replace("<br  />", "<br>", $val);
         $val = str_replace("<BR/>", "<br>", $val);
         $val = str_replace("<BR />", "<br>", $val);
         $val = str_replace("<BR  />", "<br>", $val);
         return explode("<br>", $val);
     }
     function diff_to_html($changes)
     {
         $result = array("", "");
         for ($i = 0; $i < count_longest($changes->orig, $changes->final); $i++) {
             $class = array("", "");
             $char = array("", "");
             $vals = array(trim($changes->orig[$i]), trim($changes->final[$i]));
             if ($vals[0] && $vals[1]) {
                 if ($vals[0] != $vals[1]) {
                     $class[1] .= "diffadded";
                 }
             } else {
                 if ($vals[0]) {
                     $class[0] .= "diffadded";
                     $class[1] .= "diffdeleted";
                     $vals[1] = $vals[0];
                     $char[1] = "-";
                 } else {
                     if ($vals[1]) {
                         $class[0] .= "diffdeleted";
                         $class[1] .= "diffadded";
                         $char[1] = "+";
                     }
                 }
             }
             if ($vals[0]) {
                 $result[0] .= "<td class='{$class['0']}'>" . $char[0] . $vals[0] . "</td>";
             }
             if ($vals[1]) {
                 $result[1] .= "<td class='{$class['1']}'>" . $char[1] . $vals[1] . "</td>";
             }
         }
         return $result;
     }
     $grids1 = join_with_sub_grids($id, $dates[0]);
     $grids2 = join_with_sub_grids($id, $dates[1]);
     for ($i = 0; $i < count_longest($grids1, $grids2); $i++) {
         //cycle through the sheets within a spreadsheet
         $result1 .= "<table title='" . $grids1[$i]->name() . "'>";
         $result2 .= "<table title='" . $grids2[$i]->name() . "'>";
         for ($row = 0; $row < count_longest($grids1[$i]->dataGrid, $grids2[$i]->dataGrid); $row++) {
             //cycle through rows
             $result1 .= "<tr>";
             $result2 .= "<tr>";
             for ($col = 0; $col < count_longest($grids1[$i]->dataGrid[$row], $grids2[$i]->dataGrid[$row]); $col++) {
                 //cycle through columns
                 $diff = new Text_Diff(sanitize_for_diff($grids1[$i]->dataGrid[$row][$col]), sanitize_for_diff($grids2[$i]->dataGrid[$row][$col]));
                 $changes = $diff->getDiff();
                 //print_r($changes);
                 $class = array('', '');
                 $values = array('', '');
                 //I left this diff switch, but it really isn't being used as of now, in the future we may though.
                 switch (get_class($changes[0])) {
                     case 'Text_Diff_Op_copy':
                         $values = diff_to_html($changes[0]);
                         break;
                     case 'Text_Diff_Op_change':
                         $values = diff_to_html($changes[0]);
                         break;
                     case 'Text_Diff_Op_delete':
                         $values = diff_to_html($changes[0]);
                         break;
                     case 'Text_Diff_Op_add':
                         $values = diff_to_html($changes[0]);
                         break;
                     default:
                         $values = diff_to_html($changes[0]);
                 }
                 $result1 .= empty($values[0]) ? '<td></td>' : $values[0];
                 $result2 .= empty($values[1]) ? '<td></td>' : $values[1];
             }
             $result1 .= "</tr>";
             $result2 .= "</tr>";
         }
         $result1 .= "</table>";
         $result2 .= "</table>";
     }
     return array($result1, $result2);
 }