Skip to content
This repository has been archived by the owner on Feb 25, 2020. It is now read-only.

Commit

Permalink
fixed problem with path when extracting files - strpos'sing path to f…
Browse files Browse the repository at this point in the history
…ind directory part is not that clever as directory separator is different on windows vs linux

extractTo now honors folder set with folder()
fixed some of the warnings that Idea/phpstorm inspectors gave
  • Loading branch information
aldas committed Dec 27, 2016
1 parent dd05b4b commit 16d3cec
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 23 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,9 @@ This will go into the folder `test` in the zip file and extract the content of t

This command is really nice to get just a part of the zip file, you can also pass a 2nd & 3rd param to specify a single or an array of files that will be

> NB: Php ZipArchive uses internally '/' as directory separator for files/folders in zip. So Windows users should not set
> whitelist/blacklist patterns with '\' as it will not match anything
white listed

>**Zipper::WHITELIST**
Expand Down Expand Up @@ -170,7 +173,7 @@ Which will extract the `test.zip` into the `public` folder but **only** files/fo
test.zip
|- test.bat
|- test.bat.~
|- test.bat/
|- test.bat.dir/
|- fileInSubFolder.log
```

Expand Down
9 changes: 9 additions & 0 deletions src/Chumper/Zipper/Repositories/RepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ function __construct($filePath, $new = false, $archiveImplementation = null);
*/
public function addFile($pathToFile, $pathInArchive);

/**
* Add a file to the opened Archive using its contents
*
* @param $name
* @param $content
* @return void
*/
public function addFromString($name, $content);

/**
* Add an empty directory
*
Expand Down
57 changes: 40 additions & 17 deletions src/Chumper/Zipper/Zipper.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class Zipper
*
* @param Filesystem $fs
*/
function __construct(Filesystem $fs = null)
public function __construct(Filesystem $fs = null)
{
$this->file = $fs ? $fs : new Filesystem();
}
Expand All @@ -67,6 +67,7 @@ function __construct(Filesystem $fs = null)
* @param RepositoryInterface|string $type The type of the archive, defaults to zip, possible are zip, phar
*
* @return $this Zipper instance
* @throws \RuntimeException
* @throws \Exception
* @throws \InvalidArgumentException
*/
Expand All @@ -84,10 +85,9 @@ public function make($pathToFile, $type = 'zip')
throw new \InvalidArgumentException("Class for '{$objectOrName}' must implement RepositoryInterface interface");
}

$this->repository = $type;
if (is_string($objectOrName)) {
$this->repository = new $objectOrName($pathToFile, $new);
} else {
$this->repository = $type;
}

return $this;
Expand All @@ -98,6 +98,7 @@ public function make($pathToFile, $type = 'zip')
*
* @param $pathToFile
* @return $this
* @throws \Exception
*/
public function zip($pathToFile)
{
Expand All @@ -110,6 +111,7 @@ public function zip($pathToFile)
*
* @param $pathToFile
* @return $this
* @throws \Exception
*/
public function phar($pathToFile)
{
Expand All @@ -122,6 +124,7 @@ public function phar($pathToFile)
*
* @param $pathToFile
* @return $this
* @throws \Exception
*/
public function rar($pathToFile)
{
Expand Down Expand Up @@ -150,7 +153,7 @@ public function extractTo($path, array $files = array(), $methodFlags = Zipper::
return in_array($haystack, $files, true);
};
} else {
$matchingMethod = function ($haystack) use ($files) {
$matchingMethod = function ($haystack) use ($files) {
return starts_with($haystack, $files);
};
}
Expand All @@ -170,8 +173,11 @@ public function extractTo($path, array $files = array(), $methodFlags = Zipper::
*
* @param string $extractToPath The path to extract to
* @param string $regex regular expression used to match files. See @link http://php.net/manual/en/reference.pcre.pattern.syntax.php
* @throws \InvalidArgumentException
* @throws \RuntimeException
*/
public function extractMatchingRegex($extractToPath, $regex) {
public function extractMatchingRegex($extractToPath, $regex)
{
if (empty($regex)) {
throw new \InvalidArgumentException('Missing pass valid regex parameter');
}
Expand Down Expand Up @@ -233,7 +239,7 @@ public function add($pathToAdd, $fileName = null)
* Add an empty directory
*
* @param $dirName
* @return void
* @return Zipper
*/
public function addEmptyDir($dirName)
{
Expand Down Expand Up @@ -313,9 +319,10 @@ public function usePassword($password)
*/
public function close()
{
if (!is_null($this->repository))
if (null !== $this->repository) {
$this->repository->close();
$this->filePath = "";
}
$this->filePath = '';
}

/**
Expand Down Expand Up @@ -346,11 +353,12 @@ public function home()
*/
public function delete()
{
if (!is_null($this->repository))
if (null !== $this->repository) {
$this->repository->close();
}

$this->file->delete($this->filePath);
$this->filePath = "";
$this->filePath = '';
}

/**
Expand All @@ -368,8 +376,9 @@ public function getArchiveType()
*/
public function __destruct()
{
if (!is_null($this->repository))
if (null !== $this->repository) {
$this->repository->close();
}
}

/**
Expand All @@ -382,6 +391,19 @@ public function getCurrentFolderPath()
return $this->currentFolder;
}

private function getCurrentFolderWithTrailingSlash()
{
if (empty($this->currentFolder)) {
return '';
}

$lastChar = mb_substr($this->currentFolder, -1);
if ($lastChar !== '/' || $lastChar !== '\\') {
return $this->currentFolder . '/';
}
return $this->currentFolder;
}

/**
* Checks if a file is present in the archive
*
Expand Down Expand Up @@ -430,9 +452,10 @@ private function createArchiveFile($pathToZip)
{

if (!$this->file->exists($pathToZip)) {
if (!$this->file->exists(dirname($pathToZip)) && !$this->file->makeDirectory(dirname($pathToZip), 0755, true)) {
$dirname = dirname($pathToZip);
if (!$this->file->exists($dirname) && !$this->file->makeDirectory($dirname, 0755, true)) {
throw new \RuntimeException('Failed to create folder');
} else if (!$this->file->isWritable(dirname($pathToZip))) {
} else if (!$this->file->isWritable($dirname)) {
throw new Exception(sprintf('The path "%s" is not writeable', $pathToZip));
}

Expand Down Expand Up @@ -493,7 +516,7 @@ private function extractFilesInternal($path, callable $matchingMethod)
{
$self = $this;
$this->repository->each(function ($fileName) use ($path, $matchingMethod, $self) {
$currentPath = $self->getCurrentFolderPath();
$currentPath = $self->getCurrentFolderWithTrailingSlash();
if (!empty($currentPath) && !starts_with($fileName, $currentPath)) {
return;
}
Expand All @@ -508,15 +531,15 @@ private function extractFilesInternal($path, callable $matchingMethod)
/**
* @param $fileName
* @param $path
* @throws \RuntimeException
*/
private function extractOneFileInternal($fileName, $path)
{
$tmpPath = str_replace($this->getInternalPath(), '', $fileName);

// We need to create the directory first in case it doesn't exist
$full_path = $path . DIRECTORY_SEPARATOR . $tmpPath;
$dir = substr($full_path, 0, strrpos($full_path, DIRECTORY_SEPARATOR));
if (!is_dir($dir) && !$this->getFileHandler()->makeDirectory($dir, 0777, true, true)) {
$dir = pathinfo($path . DIRECTORY_SEPARATOR . $tmpPath, PATHINFO_DIRNAME);
if (!$this->file->exists($dir) && !$this->file->makeDirectory($dir, 0755, true, true)) {
throw new \RuntimeException('Failed to create folders');
}

Expand Down
16 changes: 14 additions & 2 deletions tests/ArrayArchive.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ public function addFile($pathToFile, $pathInArchive)
$this->entries[$pathInArchive] = $pathInArchive;
}

/**
* Add a file to the opened Archive using its contents
*
* @param $name
* @param $content
* @return void
*/
public function addFromString($name, $content)
{
$this->entries[$name] = $name;
}

/**
* Remove a file permanently from the Archive
*
Expand Down Expand Up @@ -115,7 +127,7 @@ public function close()
* @return void
*/
public function addEmptyDir($dirName){
# CODE...
# CODE...
}

/**
Expand All @@ -126,6 +138,6 @@ public function addEmptyDir($dirName){
*/
public function usePassword($password)
{
# CODE...
# CODE...
}
}
10 changes: 7 additions & 3 deletions tests/ZipperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ public function testExtractWhiteListWithExactMatching()
public function testExtractWhiteListWithExactMatchingFromSubDirectory()
{
$this->file->shouldReceive('isFile')->andReturn(true);
$this->file->shouldReceive('exists')->andReturn(false);
$this->file->shouldReceive('makeDirectory')->andReturn(true);

$this->archive->folder('foo/bar/subDirectory')
Expand All @@ -264,12 +265,15 @@ public function testExtractWhiteListWithExactMatchingFromSubDirectory()
->add('baz')
->add('baz.log');

$this->file
->shouldReceive('put')
->with(realpath(NULL) . DIRECTORY_SEPARATOR . 'subDirectory/bazInSubDirectory', 'foo/bar/subDirectory/bazInSubDirectory');
$subDirectoryPath = realpath(NULL) . DIRECTORY_SEPARATOR . 'subDirectory';
$subDirectoryFilePath = $subDirectoryPath . '/bazInSubDirectory';
$this->file->shouldReceive('put')
->with($subDirectoryFilePath, 'foo/bar/subDirectory/bazInSubDirectory');

$this->archive
->extractTo(getcwd(), array('subDirectory/bazInSubDirectory'), Zipper::WHITELIST | Zipper::EXACT_MATCH);

$this->file->shouldHaveReceived('makeDirectory')->with($subDirectoryPath, 0755, true, true);
}

public function testExtractToIgnoresBlackListFile()
Expand Down

0 comments on commit 16d3cec

Please sign in to comment.