/src/system/application/libraries/Htmldiff.php
PHP | 307 lines | 210 code | 31 blank | 66 comment | 60 complexity | 2dca030b4b0b9737a823d70433dc60af MD5 | raw file
Possible License(s): GPL-2.0
- <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
- /**
- * Replacement of htmldiff.py
- *
- * Requirement:
- * PEAR::Text_Diff
- * OS diff command
- * shell_exec()
- *
- * @author Kenji Suzuki <kenji@club.h14m.org> Thanks!
- * @copyright Copyright (c) 2009 Kenji Suzuki
- * @modified at 2010/10/29 Yoshiaki Sugimoto <neo.yoshiaki.sugimoto@gmail.com>
- *
- */
- class Htmldiff
- {
- protected $past_version;
- protected $latest_version;
-
- public function __construct() {
- require_once APPPATH . 'libraries/HtmlDiff/Diff.php';
- require_once APPPATH . 'libraries/HtmlDiff/Diff/Renderer.php';
- require_once APPPATH . 'libraries/HtmlDiff/Diff/Renderer/unified.php';
- }
-
- /**
- * additional method getDiffFromFile
- * get diff from two files
- * @param unknown_type $file1
- * @param unknown_type $file2
- */
- public function getDiffFromFile($file1, $file2)
- {
- /* Make sure both files exist. */
- if (!is_readable($file1)) {
- return "$file1 not found or not readable.";
- }
- if (!is_readable($file2)) {
- return "$file2 not found or not readable.";
- }
- /* Load the lines of each file. */
- $lines1 = file($file1);
- $lines2 = file($file2);
-
- return $this->_getDiff($lines1, $lines2);
- }
-
- /**
- * additionalmethod getDiffFromString
- * get diff from outputed string daa
- * @param unknown_type $text1
- * @param unknown_type $text2
- */
- public function getDiffFromString($str1, $str2)
- {
- $str1 = explode("\n", $str1);
- $str2 = explode("\n", $str2);
- return $this->_getDiff($str1, $str2);
- }
-
- /**
- * alias to getDiff public method
- * @param unknown_type $text1
- * @param unknown_type $text2
- */
- public function getDiff($file1, $file2)
- {
- return $this->getDiffFromFile($file1, $file2);
- }
-
- /**
- * getDiff from URI parameter files
- * Enter description here ...
- * @param unknown_type $text1
- * @param unknown_type $text2
- */
- function getDiffFromURIs($uri1, $uri2)
- {
- /* Make sure both uris strict format. */
- if ( ! preg_match('/^http/', $uri1) )
- {
- return "$uri1 is illegal URI format.";
- }
- if ( ! preg_match('/^http/', $uri2) )
- {
- return "$uri2 is illegal URI format.";
- }
-
- $lines1 = @file($uri1);
- $lines2 = @file($uri2);
-
- if ( ! $lines1 )
- {
- return "$uri1 is not found.";
- }
- if ( ! $lines2 )
- {
- return "$uri2 is not found.";
- }
-
- return $this->_getDiff($lines1, $lines2);
- }
- protected function _getDiff($text1, $text2) {
- // this process move to "getDiffFromFile" method.
- ///* Make sure both files exist. */
- //if (!is_readable($file1)) {
- // return "$file1 not found or not readable.";
- //}
- //if (!is_readable($file2)) {
- // return "$file2 not found or not readable.";
- //}
- //
- ///* Load the lines of each file. */
- //$lines1 = file($file1);
- //$lines2 = file($file2);
-
- $lines1 = $this->normailze($text1);
- $lines2 = $this->normailze($text2);
- /* Create the Diff object. */
- // 'shell' means to use diff command, we select it because it's smarter than 'native' PHP diff engine.
- $diff = new Text_Diff('auto', array($lines1, $lines2));
- /* Get the Diff result */
- $diffResult = $diff->getDiff();
-
- $version_txt = 'バージョン' . $this->past_version . ' → ' . $this->latest_version . ' ';
- $out = '';
- foreach ($diffResult as $index => $op) {
- if ($op instanceof Text_Diff_Op_copy) {
- // equal
- // orig is equl to final
- foreach ($op->orig as $line) {
- $out .= $line . PHP_EOL;
- }
- } else if ($op instanceof Text_Diff_Op_add) {
- // insert
- // orig is empty, final has content
- $out .= '<div class="diff" style="background-color:#87e7a2">';
- $out .= '<p style="text-align:left;font-size:12px">' . $version_txt . 'で追加</p>';
- foreach ($op->final as $line) {
- $out .= $line . PHP_EOL;
- }
- $out .= '</div>';
- } else if ($op instanceof Text_Diff_Op_delete) {
- // delete
- // orig has content, final is empty
- $out .= '<div class="diff" style="background-color:#ed9492">';
- $out .= '<p style="text-align:left;font-size:12px">' . $version_txt . 'で削除</p>';
- foreach ($op->orig as $line) {
- $out .= $line . PHP_EOL;
- }
- $out .= '</div>';
- } else if ($op instanceof Text_Diff_Op_change) {
- // replace
- $orig = array();
- foreach ($op->orig as $line) {
- $len = mb_strlen($line);
- if ($len > 0 && $line[0] == '<') {
- $orig[] = $line;
- } else {
- for ($i = 0; $i < $len; $i++) {
- $orig[] = mb_substr($line, $i, 1);
- }
- $orig[] = PHP_EOL;
- }
- }
- $final = array();
- foreach ($op->final as $line) {
- $len = mb_strlen($line);
- if ($len > 0 && $line[0] == '<') {
- $orig[] = $line;
- } else {
- for ($i = 0; $i < $len; $i++) {
- $final[] = mb_substr($line, $i, 1);
- }
- $final[] = PHP_EOL;
- }
- }
- $diffInChange = new Text_Diff('auto', array($orig, $final));
- $diffInChangeResult = $diffInChange->getDiff();
- foreach ($diffInChangeResult as $indexInChange => $opInChange) {
- if ($opInChange instanceof Text_Diff_Op_copy) {
- // equal
- foreach ($opInChange->orig as $line) {
- if ($line == '') {
- $line = PHP_EOL;
- }
- $out .= $line;
- }
- } else if ($opInChange instanceof Text_Diff_Op_add) {
- // insert
- $out .= '<div class="diff" style="background-color:#87e7a2">';
- $out .= '<p style="text-align:left;font-size:12px">' . $version_txt . 'で追加</p>';
- foreach ($opInChange->final as $line) {
- if ($line == '') {
- $line = PHP_EOL;
- }
- $out .= $line;
- }
- $out .= '</div>';
- } else if ($opInChange instanceof Text_Diff_Op_delete) {
- // delete
- $out .= '<div class="diff" style="backgorund-color:#ed9492">';
- $out .= '<p style="text-align:left;font-size:12px">' . $version_txt . 'で削除</p>';
- foreach ($opInChange->orig as $line) {
- if ($line == '') {
- $line = PHP_EOL;
- }
- $out .= $line;
- }
- $out .= '</del>';
- } else if ($op instanceof Text_Diff_Op_change) {
- // replace
- $out .= '<div class="diff modified" style="background-color:#ccc">';
- $out .= '<p style="text-align:left;font-size:12px">' . $version_txt . 'で削除</p>';
- foreach ($opInChange->orig as $line) {
- if ($line == '') {
- $line = PHP_EOL;
- }
- $out .= $line;
- }
- $out .= '</div><div class="diff modified" style="background-color:#00084c4"><p style="text-align:left;font-size:12px">' . $version_txt . 'で追加</p>';;
- foreach ($opInChange->final as $line) {
- if ($line == '') {
- $line = PHP_EOL;
- }
- $out .= $line;
- }
- $out .= '</div>';
- } else {
- printf("WARNING: unknown operation\n");
- }
- }
- } else {
- printf("WARNING: unknown operation\n");
- }
- }
- return $out;
- }
- private function normailze($lines) {
- $mode = 'char';
- $out = array();
- foreach ($lines as $line) {
- $len = strlen($line);
- for ($i = 0; $i < $len; $i++) {
- $c = $line[$i];
- if ($mode == 'tag') {
- if ($c == '>') {
- $tmp = array_pop($out);
- $out[] = $tmp . $c;
- $out[] = '';
- $mode = 'char';
- } else {
- $tmp = array_pop($out);
- $out[] = $tmp . $c;
- }
- }
- else if ($mode == 'char') {
- if ($c == '<') {
- $out[] = $c;
- $mode = 'tag';
- } else {
- if ($c != PHP_EOL) {
- $tmp = array_pop($out);
- } else {
- $tmp = '';
- }
- $out[] = $tmp . $c;
- }
- }
- }
- }
- $html = array();
- foreach ($out as $line) {
- $line = trim($line);
- if ($line != '') {
- $html[] = $line . PHP_EOL;
- }
- }
- return $html;
- }
-
- // version ID setter
- public function set_versions($past = 0, $latest = 0)
- {
- $this->past_version = $past;
- $this->latest_version = $latest;
- }
-
- }