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

Commit

Permalink
Merge pull request #84 from aldas/fix-various-problems
Browse files Browse the repository at this point in the history
 fixed problem with path when extracting files - strpos'sing path to find directory part is not that clever as directory separator is different on windows vs linux
  • Loading branch information
Chumper authored Dec 27, 2016
2 parents dd05b4b + 16d3cec commit c7c32e7
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 c7c32e7

Please sign in to comment.