Source for file patcher.php
Documentation is available at patcher.php
* @package Joomla.Platform
* @copyright Copyright (C) 2005 - 2013 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
* A Unified Diff Format Patcher class
* @package Joomla.Platform
* @link http://sourceforge.net/projects/phppatcher/ This has been derived from the PhpPatcher version 0.1.1 written by Giuseppe Mazzotta
* Regular expression for searching source files
const SRC_FILE =
'/^---\\s+(\\S+)\s+\\d{1,4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}(\\.\\d+)?\\s+(\+|-)\\d{4}/A';
* Regular expression for searching destination files
const DST_FILE =
'/^\\+\\+\\+\\s+(\\S+)\s+\\d{1,4}-\\d{1,2}-\\d{1,2}\\s+\\d{1,2}:\\d{1,2}:\\d{1,2}(\\.\\d+)?\\s+(\+|-)\\d{4}/A';
* Regular expression for searching hunks of differences
const HUNK =
'/@@ -(\\d+)(,(\\d+))?\\s+\\+(\\d+)(,(\\d+))?\\s+@@($)/A';
* Regular expression for splitting lines
const SPLIT =
'/(\r\n)|(\r)|(\n)/';
* @var array sources files
* @var array destination files
* @var array removal files
* @var array instance of this class
protected static $instance;
* The constructor is protected to force the use of JFilesystemPatcher::getInstance()
* Method to get a patcher
* @return JFilesystemPatcher an instance of the patcher
if (!isset
(static::$instance))
static::$instance =
new static;
return static::$instance;
* @return JFilesystemPatcher This object for chaining
* @return integer The number of files patched
* @throws RuntimeException
// Separate the input into lines
$lines =
self::splitLines($patch['udiff']);
while (self::findHeader($lines, $src, $dst))
if ($patch['strip'] ===
null)
$src =
$patch['root'] .
preg_replace('#^([^/]*/)*#', '', $src);
$dst =
$patch['root'] .
preg_replace('#^([^/]*/)*#', '', $dst);
$src =
$patch['root'] .
preg_replace('#^([^/]*/){' . (int)
$patch['strip'] .
'}#', '', $src);
$dst =
$patch['root'] .
preg_replace('#^([^/]*/){' . (int)
$patch['strip'] .
'}#', '', $dst);
// Loop for each hunk of differences
while (self::findHunk($lines, $src_line, $src_size, $dst_line, $dst_size))
// Apply the hunk of differences
$this->applyHunk($lines, $src, $dst, $src_line, $src_size, $dst_line, $dst_size);
// If no modifications were found, throw an exception
throw
new RuntimeException('Invalid Diff');
// Initialize the counter
// Patch each destination file
// Remove each removed file
// Clear the destinations cache
* Add a unified diff file to the patcher
* @param string $filename Path to the unified diff file
* @param string $root The files root path
* @param string $strip The number of '/' to strip
* @return JFilesystemPatch $this for chaining
public function addFile($filename, $root =
JPATH_BASE, $strip =
0)
* Add a unified diff string to the patcher
* @param string $udiff Unified diff input string
* @param string $root The files root path
* @param string $strip The number of '/' to strip
* @return JFilesystemPatch $this for chaining
public function add($udiff, $root =
JPATH_BASE, $strip =
0)
'root' => isset
($root) ?
rtrim($root, DIRECTORY_SEPARATOR) .
DIRECTORY_SEPARATOR :
'',
* Separate CR or CRLF lines
* @param string $data Input string
* @return array The lines of the inputdestination file
* The internal array pointer of $lines is on the next line after the finding
* @param array &$lines The udiff array of lines
* @param string &$src The source file
* @param string &$dst The destination file
* @return boolean TRUE in case of success, FALSE in case of failure
* @throws RuntimeException
protected static function findHeader(&$lines, &$src, &$dst)
while ($line !==
false &&
!preg_match(self::SRC_FILE, $line, $m))
// No header found, return false
// Advance to the next line
throw
new RuntimeException('Unexpected EOF');
// Search the destination file
throw
new RuntimeException('Invalid Diff file');
// Set the destination file
// Advance to the next line
if (next($lines) ===
false)
throw
new RuntimeException('Unexpected EOF');
* Find the next hunk of difference
* The internal array pointer of $lines is on the next line after the finding
* @param array &$lines The udiff array of lines
* @param string &$src_line The beginning of the patch for the source file
* @param string &$src_size The size of the patch for the source file
* @param string &$dst_line The beginning of the patch for the destination file
* @param string &$dst_size The size of the patch for the destination file
* @return boolean TRUE in case of success, false in case of failure
* @throws RuntimeException
protected static function findHunk(&$lines, &$src_line, &$src_size, &$dst_line, &$dst_size)
if (next($lines) ===
false)
throw
new RuntimeException('Unexpected EOF');
* @param array &$lines The udiff array of lines
* @param string $src The source file
* @param string $dst The destination file
* @param string $src_line The beginning of the patch for the source file
* @param string $src_size The size of the patch for the source file
* @param string $dst_line The beginning of the patch for the destination file
* @param string $dst_size The size of the patch for the destination file
* @throws RuntimeException
protected function applyHunk(&$lines, $src, $dst, $src_line, $src_size, $dst_line, $dst_size)
// Source lines (old file)
throw
new RuntimeException(JText::sprintf('JLIB_FILESYSTEM_PATCHER_REMOVE_LINE', key($lines)));
throw
new RuntimeException(JText::sprintf('JLIB_FILESYSTEM_PATCHER_ADD_LINE', key($lines)));
elseif ($line !=
'\\ No newline at end of file')
if ($src_left ==
0 &&
$dst_left ==
0)
// Now apply the patch, finally!
throw
new RuntimeException(JText::sprintf('JLIB_FILESYSTEM_PATCHER_UNEXISING_SOURCE', $src));
$src_bottom =
$src_line +
count($source);
for ($l =
$src_line;$l <
$src_bottom;$l++
)
if ($src_lines[$l] !=
$source[$l -
$src_line])
throw
new RuntimeException(JText::sprintf('JLIB_FILESYSTEM_PATCHER_FAILED_VERIFY', $src, $l));
throw
new RuntimeException('Unexpected EOF');
* Get the lines of a source file
* @param string $src The path of a file
* @return array The lines of the source file
* Get the lines of a destination file
* @param string $dst The path of a destination file
* @param string $src The path of a source file
* @return array The lines of the destination file
Documentation generated on Tue, 19 Nov 2013 15:10:22 +0100 by phpDocumentor 1.4.3