/** * displays a diff for two texts * * @return void * @author The Young Shepherd **/ public static function diff($old, $new) { $dmp = new diff_match_patch(); $d = $dmp->diff_main($old, $new); $dmp->diff_cleanupSemantic($d); return $dmp->diff_prettyHtml($d); }
/** * Calculate the DiffMatchPatch patch between two Phabricator files. * * @phutil-external-symbol class diff_match_patch */ public static function calculatePatch(PhabricatorFile $old = null, PhabricatorFile $new = null) { $root = dirname(phutil_get_library_root('phabricator')); require_once $root . '/externals/diff_match_patch/diff_match_patch.php'; $old_hash = self::EMPTY_HASH; $new_hash = self::EMPTY_HASH; if ($old !== null) { $old_hash = $old->getContentHash(); } if ($new !== null) { $new_hash = $new->getContentHash(); } $old_content = ''; $new_content = ''; if ($old_hash === $new_hash) { return null; } if ($old_hash !== self::EMPTY_HASH) { $old_content = $old->loadFileData(); } else { $old_content = ''; } if ($new_hash !== self::EMPTY_HASH) { $new_content = $new->loadFileData(); } else { $new_content = ''; } $dmp = new diff_match_patch(); $dmp_patches = $dmp->patch_make($old_content, $new_content); return $dmp->patch_toText($dmp_patches); }
public function modify() { // Change name if ($this->new_name) { $explode = explode('/', $this->path); array_pop($explode); $new_path = implode("/", $explode) . "/" . $this->new_name; if (!file_exists($new_path)) { if (rename($this->path, $new_path)) { //unlink($this->path); $this->status = "success"; } else { $this->status = "error"; $this->message = "Could Not Rename"; } } else { $this->status = "error"; $this->message = "Path Already Exists"; } } else { // Change content if ($this->content || $this->patch) { if ($this->content == ' ') { $this->content = ''; // Blank out file } if ($this->patch && !$this->mtime) { $this->status = "error"; $this->message = "mtime parameter not found"; $this->respond(); return; } if (is_file($this->path)) { $serverMTime = filemtime($this->path); $fileContents = file_get_contents($this->path); if ($this->patch && $this->mtime != $serverMTime) { $this->status = "error"; $this->message = "Client is out of sync"; //DEBUG : file_put_contents($this->path.".conflict", "SERVER MTIME :".$serverMTime.", CLIENT MTIME :".$this->mtime); $this->respond(); return; } else { if (strlen(trim($this->patch)) == 0 && !$this->content) { // Do nothing if the patch is empty and there is no content $this->status = "success"; $this->data = '"mtime":' . $serverMTime; $this->respond(); return; } } if ($file = fopen($this->path, 'w')) { if ($this->patch) { $dmp = new diff_match_patch(); $p = $dmp->patch_apply($dmp->patch_fromText($this->patch), $fileContents); $this->content = $p[0]; //DEBUG : file_put_contents($this->path.".orig",$fileContents ); //DEBUG : file_put_contents($this->path.".patch", $this->patch); } if (fwrite($file, $this->content) === false) { $this->status = "error"; $this->message = "could not write to file"; } else { // Unless stat cache is cleared the pre-cached mtime will be // returned instead of new modification time after editing // the file. clearstatcache(); $this->data = '"mtime":' . filemtime($this->path); $this->status = "success"; } fclose($file); } else { $this->status = "error"; $this->message = "Cannot Write to File"; } } else { $this->status = "error"; $this->message = "Not A File"; } } else { $file = fopen($this->path, 'w'); fclose($file); $this->data = '"mtime":' . filemtime($this->path); $this->status = "success"; } } $this->respond(); }
exit(formatJSEND('error', 'Inconsistent sever text filename in synchronizeText: ' . $serverTextEntry)); } $query = array('user' => $_SESSION['user'], 'filename' => $_POST['filename']); $shadowTextEntry = getDB()->select($query, 'shadow'); if ($shadowTextEntry == null) { exit(formatJSEND('error', 'Inconsistent sever text filename in synchronizeText: ' . $shadowTextEntry)); } /* First acquire a lock or wait until a lock can be acquired for server * text and shadow. */ $serverTextEntry->lock(); $shadowTextEntry->lock(); $serverText = $serverTextEntry->get_value(); $shadowText = $shadowTextEntry->get_value(); $patchFromClient = $_POST['patch']; /* Patch the shadow and server texts with the edits from the client. */ $dmp = new diff_match_patch(); $patchedServerText = $dmp->patch_apply($dmp->patch_fromText($patchFromClient), $serverText); $serverTextEntry->put_value($patchedServerText[0]); $patchedShadowText = $dmp->patch_apply($dmp->patch_fromText($patchFromClient), $shadowText); /* Make a diff between server text and shadow to get the edits to send * back to the client. */ $patchFromServer = $dmp->patch_toText($dmp->patch_make($patchedShadowText[0], $patchedServerText[0])); /* Apply it to the shadow. */ $patchedShadowText = $dmp->patch_apply($dmp->patch_fromText($patchFromServer), $patchedShadowText[0]); $shadowTextEntry->put_value($patchedShadowText[0]); /* Release locks. */ $serverTextEntry->unlock(); $shadowTextEntry->unlock(); echo formatJSEND('success', $patchFromServer); break; case 'sendHeartbeat':