Laravel version update

Laravel version update
This commit is contained in:
Manish Verma
2018-08-06 18:48:58 +05:30
parent d143048413
commit 126fbb0255
13678 changed files with 1031482 additions and 778530 deletions

View File

@@ -38,7 +38,7 @@ class DatatableServiceProvider extends ServiceProvider {
$this->mergeConfigFrom(__DIR__.'/../../config/config.php', 'chumper.datatable');
$this->app['datatable'] = $this->app->share(function($app)
$this->app->singleton('datatable', function($app)
{
return new Datatable;
});

34
vendor/chumper/zipper/.php_cs vendored Normal file
View File

@@ -0,0 +1,34 @@
<?php
return PhpCsFixer\Config::create()
->setRiskyAllowed(true)
->setRules(array(
'@Symfony' => true,
'@Symfony:risky' => true,
'@PHP56Migration' => true,
'array_syntax' => array('syntax' => 'short'),
'combine_consecutive_unsets' => true,
// one should use PHPUnit methods to set up expected exception instead of annotations
'general_phpdoc_annotation_remove' => array('expectedException', 'expectedExceptionMessage', 'expectedExceptionMessageRegExp'),
'heredoc_to_nowdoc' => false,
'no_extra_consecutive_blank_lines' => array('break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block'),
'no_unreachable_default_argument_value' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_class_elements' => true,
'ordered_imports' => true,
'php_unit_strict' => true,
'phpdoc_add_missing_param_annotation' => true,
'phpdoc_order' => true,
'psr4' => true,
'strict_comparison' => true,
'strict_param' => true,
'no_php4_constructor' => true,
'no_short_echo_tag' => true,
'phpdoc_summary' => false,
))
->setFinder(
PhpCsFixer\Finder::create()
->in(__DIR__)
)
;

1
vendor/chumper/zipper/.php_cs.cache vendored Normal file
View File

@@ -0,0 +1 @@
{"php":"7.0.15","version":"2.0.0:v2.0.0#f3baf72eb2f58bf275b372540f5b47d25aed910f","rules":{"encoding":true,"full_opening_tag":true,"blank_line_after_namespace":true,"braces":true,"class_definition":{"singleLine":true},"elseif":true,"function_declaration":true,"indentation_type":true,"line_ending":true,"lowercase_constants":true,"lowercase_keywords":true,"method_argument_space":true,"no_closing_tag":true,"no_spaces_after_function_name":true,"no_spaces_inside_parenthesis":true,"no_trailing_whitespace":true,"no_trailing_whitespace_in_comment":true,"single_blank_line_at_eof":true,"single_class_element_per_statement":true,"single_import_per_statement":true,"single_line_after_imports":true,"switch_case_semicolon_to_colon":true,"switch_case_space":true,"visibility_required":true,"binary_operator_spaces":{"align_double_arrow":false,"align_equals":false},"blank_line_after_opening_tag":true,"blank_line_before_return":true,"cast_spaces":true,"concat_space":{"spacing":"none"},"declare_equal_normalize":true,"function_typehint_space":true,"hash_to_slash_comment":true,"include":true,"lowercase_cast":true,"method_separation":true,"native_function_casing":true,"new_with_braces":true,"no_alias_functions":true,"no_blank_lines_after_class_opening":true,"no_blank_lines_after_phpdoc":true,"no_empty_comment":true,"no_empty_phpdoc":true,"no_empty_statement":true,"no_extra_consecutive_blank_lines":["break","continue","extra","return","throw","use","parenthesis_brace_block","square_brace_block","curly_brace_block"],"no_leading_import_slash":true,"no_leading_namespace_whitespace":true,"no_mixed_echo_print":{"use":"echo"},"no_multiline_whitespace_around_double_arrow":true,"no_short_bool_cast":true,"no_singleline_whitespace_before_semicolons":true,"no_spaces_around_offset":true,"no_trailing_comma_in_list_call":true,"no_trailing_comma_in_singleline_array":true,"no_unneeded_control_parentheses":true,"no_unreachable_default_argument_value":true,"no_unused_imports":true,"no_whitespace_before_comma_in_array":true,"no_whitespace_in_blank_line":true,"normalize_index_brace":true,"object_operator_without_whitespace":true,"php_unit_fqcn_annotation":true,"phpdoc_align":true,"phpdoc_annotation_without_dot":true,"phpdoc_indent":true,"phpdoc_inline_tag":true,"phpdoc_no_access":true,"phpdoc_no_alias_tag":true,"phpdoc_no_empty_return":true,"phpdoc_no_package":true,"phpdoc_scalar":true,"phpdoc_separation":true,"phpdoc_single_line_var_spacing":true,"phpdoc_to_comment":true,"phpdoc_trim":true,"phpdoc_types":true,"phpdoc_var_without_name":true,"pre_increment":true,"return_type_declaration":true,"self_accessor":true,"short_scalar_cast":true,"single_blank_line_before_namespace":true,"single_quote":true,"space_after_semicolon":true,"standardize_not_equals":true,"ternary_operator_spaces":true,"trailing_comma_in_multiline_array":true,"trim_array_spaces":true,"unary_operator_spaces":true,"whitespace_after_comma_in_array":true,"php_unit_construct":true,"php_unit_dedicate_assert":true,"silenced_deprecation_error":true,"pow_to_exponentiation":true,"array_syntax":{"syntax":"short"},"combine_consecutive_unsets":true,"general_phpdoc_annotation_remove":["expectedException","expectedExceptionMessage","expectedExceptionMessageRegExp"],"no_useless_else":true,"no_useless_return":true,"ordered_class_elements":true,"ordered_imports":true,"php_unit_strict":true,"phpdoc_add_missing_param_annotation":true,"phpdoc_order":true,"psr4":true,"strict_comparison":true,"strict_param":true,"no_php4_constructor":true,"no_short_echo_tag":true},"hashes":{"src\/Chumper\/Zipper\/Facades\/Zipper.php":3336360490,"src\/Chumper\/Zipper\/Repositories\/RepositoryInterface.php":146020446,"src\/Chumper\/Zipper\/Repositories\/ZipRepository.php":1787403374,"src\/Chumper\/Zipper\/Zipper.php":3154847016,"src\/Chumper\/Zipper\/ZipperServiceProvider.php":3002562041,"tests\/ArrayArchive.php":1688992765,"tests\/Repositories\/ZipRepositoryTest.php":973823218,"tests\/ZipperTest.php":2774399588}}

View File

@@ -1,11 +1,32 @@
language: php
sudo: false
php:
- 5.4
- 5.5
- 5.6
- 7.0
- 7.1
before_script:
- curl -s http://getcomposer.org/installer | php
- php composer.phar install --dev
env:
global:
- setup=basic
script: phpunit
matrix:
fast_finish: true
include:
- php: 5.6
env: setup=lowest
- php: 5.6
env: setup=stable
before_install:
- composer self-update
- composer clear-cache
install:
- if [[ $setup = 'basic' ]]; then travis_retry composer update --no-interaction --prefer-dist --no-suggest; fi
- if [[ $setup = 'stable' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-stable --no-suggest; fi
- if [[ $setup = 'lowest' ]]; then travis_retry composer update --prefer-dist --no-interaction --prefer-lowest --prefer-stable --no-suggest; fi
script: vendor/bin/phpunit

View File

@@ -1,39 +1,31 @@
#Zipper
# Zipper
[![Build Status](https://travis-ci.org/Chumper/Zipper.png)](https://travis-ci.org/Chumper/Zipper)
This is a simple Wrapper around the ZipArchive methods with some handy functions.
##Installation
## Installation
1a- To install this package for laravel 5 just require it in your
1. Add this package to the list of required packages, inside `composer.json`
* for Laravel 5: `"chumper/zipper": "1.0.x"`
* ~~for Laravel 4: `"chumper/zipper": "0.5.x"`~~
2. Run `composer update`
`composer.json` with `"Chumper/Zipper": "0.6.0"`
3. Go to `app/config/app.php`
1b- To install this package for laravel 4 just require it in your
`composer.json` with `"Chumper/Zipper": "0.5.1"`
2- goto `app/config/app.php`
.add to providers
'Chumper\Zipper\ZipperServiceProvider'
.add to aliases
'Zipper' => 'Chumper\Zipper\Zipper'
* add to providers `'Chumper\Zipper\ZipperServiceProvider'`
* add to aliases `'Zipper' => 'Chumper\Zipper\Zipper'`
You can now access Zipper with the `Zipper` alias.
##Simple example
## Simple example
```php
$files = glob('public/files/*');
Zipper::make('public/test.zip')->add($files);
Zipper::make('public/test.zip')->add($files)->close();
```
- by default the package will create the `test.zip` in the project route folder but in the example above we changed it to `project_route/public/`.
####Another example
## Another example
```php
$zipper = new \Chumper\Zipper\Zipper;
@@ -52,38 +44,41 @@ $zipper->folder('mySuperPackage')->add(
$zipper->getFileContent('mySuperPackage/composer.json');
$zipper->make('test.zip')->extractTo('',array('mySuperPackage/composer.json'),Zipper::WHITELIST);
$zipper->close();
```
- You can easily chain most functions, except `getFileContent`, `getStatus`, `close` and `extractTo` which must come at the end of the chaine.
Note: Please be aware that you need to call `->close()` at the end to write the zip file to disk.
The main reason i wrote this little package is the `extractTo` method since it allows you to be very flexible when extracting zips.
So you can for example implement an update method which will just override the changed files.
You can easily chain most functions, except `getFileContent`, `getStatus`, `close` and `extractTo` which must come at the end of the chain.
The main reason I wrote this little package is the `extractTo` method since it allows you to be very flexible when extracting zips. So you can for example implement an update method which will just override the changed files.
##Functions
# Functions
**make($pathToFile)**
## make($pathToFile)
`Create` or `Open` a zip archive; if the file does not exists it will create a new one.
It will return the Zipper instance so you can chain easily.
**add($files/folder)**
## add($files/folder)
You can add and array of Files, or a Folder which all the files in that folder will then be added, so from the first example we could instead do something like `$files = 'public/files/';`.
**addString($filename, $content)**
## addString($filename, $content)
add a single file to the zip by specifying a name and content as strings.
**remove($file/s)**
## remove($file/s)
removes a single file or an array of files from the zip.
**folder($folder)**
## folder($folder)
Specify a folder to 'add files to' or 'remove files from' from the zip, example
@@ -91,32 +86,46 @@ Specify a folder to 'add files to' or 'remove files from' from the zip, example
Zipper::make('test.zip')->folder('test')->remove('composer.json');
**home()**
## listFiles($regexFilter = null)
Lists all files within archive (if no filter pattern is provided). Use `$regexFilter` parameter to filter files. See [Pattern Syntax](http://php.net/manual/en/reference.pcre.pattern.syntax.php) for regular expression syntax
> NB: `listFiles` ignores folder set with `folder` function
Example: Return all files/folders ending/not ending with '.log' pattern (case insensitive). This will return matches in sub folders and their sub folders also
```php
$logFiles = Zipper::make('test.zip')->listFiles('/\.log$/i');
$notLogFiles = Zipper::make('test.zip')->listFiles('/^(?!.*\.log).*$/i');
```
## home()
Resets the folder pointer.
**zip($fileName)**
## zip($fileName)
Uses the ZipRepository for file handling.
**getFileContent($filePath)**
## getFileContent($filePath)
get the content of a file in the zip. This will return the content or false.
**getStatus()**
## getStatus()
get the opening status of the zip as integer.
**close()**
## close()
closes the zip and writes all changes.
**extractTo($path)**
## extractTo($path)
Extracts the content of the zip archive to the specified location, for example
@@ -126,25 +135,69 @@ 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**
>
Zipper::make('test.zip')->extractTo('public', array('vendor'), Zipper::WHITELIST);
Which will extract the `test.zip` into the `public` folder but **only** the folder `vendor` inside the zip will be extracted.
```php
Zipper::make('test.zip')->extractTo('public', array('vendor'), Zipper::WHITELIST);
```
Which will extract the `test.zip` into the `public` folder but **only** files/folders starting with `vendor` prefix inside the zip will be extracted.
or black listed
>**Zipper::BLACKLIST**
>
Zipper::make('test.zip')->extractTo('public', array('vendor'), Zipper::BLACKLIST);
Which will extract the `test.zip` into the `public` folder except the folder `vendor` inside the zip will not be extracted.
Which will extract the `test.zip` into the `public` folder except files/folders starting with `vendor` prefix inside the zip will not be extracted.
```php
Zipper::make('test.zip')->extractTo('public', array('vendor'), Zipper::BLACKLIST);
```
##Development
>**Zipper::EXACT_MATCH**
May it is a goot idea to add other compress functions like rar, phar or bzip2 etc...
```php
Zipper::make('test.zip')
->folder('vendor')
->extractTo('public', array('composer', 'bin/phpunit'), Zipper::WHITELIST | Zipper::EXACT_MATCH);
```
Which will extract the `test.zip` into the `public` folder but **only** files/folders **exact matching names**. So this will:
* extract file or folder named `composer` in folder named `vendor` inside zip to `public` resulting `public/composer`
* extract file or folder named `bin/phpunit` in `vendor/bin/phpunit` folder inside zip to `public` resulting `public/bin/phpunit`
> **NB:** extracting files/folder from zip without setting Zipper::EXACT_MATCH
> When zip has similar structure as below and only `test.bat` is given as whitelist/blacklist argument then `extractTo` would extract all those files and folders as they all start with given string
```
test.zip
|- test.bat
|- test.bat.~
|- test.bat.dir/
|- fileInSubFolder.log
```
## extractMatchingRegex($path, $regex)
Extracts the content of the zip archive matching regular expression to the specified location. See [Pattern Syntax](http://php.net/manual/en/reference.pcre.pattern.syntax.php) for regular expression syntax.
Example: extract all files ending with `.php` from `src` folder and its sub folders.
```php
Zipper::make('test.zip')->folder->('src')->extractMatchingRegex($path, '/\.php$/i');
```
Example: extract all files **except** those ending with `test.php` from `src` folder and its sub folders.
```php
Zipper::make('test.zip')->folder->('src')->extractMatchingRegex($path, '/^(?!.*test\.php).*$/i');
```
# Development
Maybe it is a good idea to add other compression functions like rar, phar or bzip2 etc...
Everything is setup for that, if you want just fork and develop further.
If you need other functions or got errors, please leave an issue on github.

View File

@@ -14,18 +14,37 @@
}
],
"require": {
"php": ">=5.3.0",
"illuminate/support": "5.x",
"illuminate/filesystem": "5.x"
"php": ">=5.6.0",
"illuminate/support": "^5.0",
"illuminate/filesystem": "^5.0"
},
"require-dev": {
"phpunit/phpunit": "3.7.*",
"mockery/mockery": "dev-master"
"phpunit/phpunit": "^5.7",
"mockery/mockery": "^0.9.4"
},
"autoload": {
"psr-0": {
"Chumper\\Zipper": "src/"
"psr-4": {
"Chumper\\Zipper\\": "src/Chumper/Zipper"
}
},
"minimum-stability": "dev"
"autoload-dev": {
"psr-4": {
"Chumper\\Zipper\\": "tests/"
}
},
"config": {
"sort-packages": true
},
"extra": {
"laravel": {
"providers": [
"Chumper\\Zipper\\ZipperServiceProvider"
],
"aliases": {
"Zipper": "Chumper\\Zipper\\Zipper"
}
}
},
"minimum-stability": "dev",
"prefer-stable": true
}

View File

@@ -1,13 +1,13 @@
<?php namespace Chumper\Zipper\Facades;
<?php
namespace Chumper\Zipper\Facades;
use Illuminate\Support\Facades\Facade;
class Zipper extends Facade{
class Zipper extends Facade
{
protected static function getFacadeAccessor()
{
return 'zipper';
}
}
}

View File

@@ -1,19 +1,14 @@
<?php namespace Chumper\Zipper\Repositories;
<?php
namespace Chumper\Zipper\Repositories;
/**
* RepositoryInterface that needs to be implemented by every Repository
*
* Class RepositoryInterface
* @package Chumper\Zipper\Repositories
*/
/**
* Class RepositoryInterface
* @package Chumper\Zipper\Repositories
*/
interface RepositoryInterface
{
/**
* Construct with a given path
*
@@ -21,22 +16,35 @@ interface RepositoryInterface
* @param bool $new
* @param $archiveImplementation
*/
function __construct($filePath, $new = false, $archiveImplementation = null);
public function __construct($filePath, $new = false, $archiveImplementation = null);
/**
* Add a file to the opened Archive
*
* @param $pathToFile
* @param $pathInArchive
* @return void
*/
public function addFile($pathToFile, $pathInArchive);
/**
* Add a file to the opened Archive using its contents
*
* @param $name
* @param $content
*/
public function addFromString($name, $content);
/**
* Add an empty directory
*
* @param $dirName
*/
public function addEmptyDir($dirName);
/**
* Remove a file permanently from the Archive
*
* @param $pathInArchive
* @return void
*/
public function removeFile($pathInArchive);
@@ -44,6 +52,7 @@ interface RepositoryInterface
* Get the content of a file
*
* @param $pathInArchive
*
* @return string
*/
public function getFileContent($pathInArchive);
@@ -52,6 +61,7 @@ interface RepositoryInterface
* Get the stream of a file
*
* @param $pathInArchive
*
* @return mixed
*/
public function getFileStream($pathInArchive);
@@ -61,7 +71,6 @@ interface RepositoryInterface
* Will provide the filename for every item
*
* @param $callback
* @return void
*/
public function each($callback);
@@ -69,10 +78,20 @@ interface RepositoryInterface
* Checks whether the file is in the archive
*
* @param $fileInArchive
* @return boolean
*
* @return bool
*/
public function fileExists($fileInArchive);
/**
* Sets the password to be used for decompressing
*
* @param $password
*
* @return bool
*/
public function usePassword($password);
/**
* Returns the status of the archive as a string
*
@@ -82,7 +101,6 @@ interface RepositoryInterface
/**
* Closes the archive and saves it
* @return void
*/
public function close();
}
}

View File

@@ -1,4 +1,6 @@
<?php namespace Chumper\Zipper\Repositories;
<?php
namespace Chumper\Zipper\Repositories;
use Exception;
use ZipArchive;
@@ -13,21 +15,23 @@ class ZipRepository implements RepositoryInterface
* @param $filePath
* @param bool $create
* @param $archive
*
* @throws \Exception
*
* @return ZipRepository
*/
function __construct($filePath, $create = false, $archive = null)
public function __construct($filePath, $create = false, $archive = null)
{
//Check if ZipArchive is available
if (!class_exists('ZipArchive'))
if (!class_exists('ZipArchive')) {
throw new Exception('Error: Your PHP version is not compiled with zip support');
}
$this->archive = $archive ? $archive : new ZipArchive();
$this->archive = $archive ? $archive : new ZipArchive;
if ($create)
$this->archive->open($filePath, ZipArchive::CREATE);
else
$this->archive->open($filePath);
$res = $this->archive->open($filePath, ($create ? ZipArchive::CREATE : null));
if ($res !== true) {
throw new Exception("Error: Failed to open $filePath! Error: ".$this->getErrorMessage($res));
}
}
/**
@@ -35,19 +39,27 @@ class ZipRepository implements RepositoryInterface
*
* @param $pathToFile
* @param $pathInArchive
* @return void
*/
public function addFile($pathToFile, $pathInArchive)
{
$this->archive->addFile($pathToFile, $pathInArchive);
}
/**
* Add a file to the opened Archive using its contents
/**
* Add an empty directory
*
* @param $dirName
*/
public function addEmptyDir($dirName)
{
$this->archive->addEmptyDir($dirName);
}
/**
* Add a file to the opened Archive using its contents
*
* @param $name
* @param $content
* @return void
*/
public function addFromString($name, $content)
{
@@ -58,7 +70,6 @@ class ZipRepository implements RepositoryInterface
* Remove a file permanently from the Archive
*
* @param $pathInArchive
* @return void
*/
public function removeFile($pathInArchive)
{
@@ -69,6 +80,7 @@ class ZipRepository implements RepositoryInterface
* Get the content of a file
*
* @param $pathInArchive
*
* @return string
*/
public function getFileContent($pathInArchive)
@@ -80,6 +92,7 @@ class ZipRepository implements RepositoryInterface
* Get the stream of a file
*
* @param $pathInArchive
*
* @return mixed
*/
public function getFileStream($pathInArchive)
@@ -92,20 +105,18 @@ class ZipRepository implements RepositoryInterface
* Will provide the filename for every item
*
* @param $callback
* @return void
*/
public function each($callback)
{
for ($i = 0; $i < $this->archive->numFiles; $i++) {
for ($i = 0; $i < $this->archive->numFiles; ++$i) {
//skip if folder
$stats = $this->archive->statIndex($i);
if ($stats['size'] == 0 && $stats['crc'] == 0)
if ($stats['size'] === 0 && $stats['crc'] === 0) {
continue;
call_user_func_array($callback, array(
}
call_user_func_array($callback, [
'file' => $this->archive->getNameIndex($i),
));
]);
}
}
@@ -113,13 +124,27 @@ class ZipRepository implements RepositoryInterface
* Checks whether the file is in the archive
*
* @param $fileInArchive
* @return boolean
*
* @return bool
*/
public function fileExists($fileInArchive)
{
return $this->archive->locateName($fileInArchive) !== false;
}
/**
* Sets the password to be used for decompressing
* function named usePassword for clarity
*
* @param $password
*
* @return bool
*/
public function usePassword($password)
{
return $this->archive->setPassword($password);
}
/**
* Returns the status of the archive as a string
*
@@ -132,10 +157,33 @@ class ZipRepository implements RepositoryInterface
/**
* Closes the archive and saves it
* @return void
*/
public function close()
{
@$this->archive->close();
}
}
private function getErrorMessage($resultCode)
{
switch ($resultCode) {
case ZipArchive::ER_EXISTS:
return 'ZipArchive::ER_EXISTS - File already exists.';
case ZipArchive::ER_INCONS:
return 'ZipArchive::ER_INCONS - Zip archive inconsistent.';
case ZipArchive::ER_MEMORY:
return 'ZipArchive::ER_MEMORY - Malloc failure.';
case ZipArchive::ER_NOENT:
return 'ZipArchive::ER_NOENT - No such file.';
case ZipArchive::ER_NOZIP:
return 'ZipArchive::ER_NOZIP - Not a zip archive.';
case ZipArchive::ER_OPEN:
return 'ZipArchive::ER_OPEN - Can\'t open file.';
case ZipArchive::ER_READ:
return 'ZipArchive::ER_READ - Read error.';
case ZipArchive::ER_SEEK:
return 'ZipArchive::ER_SEEK - Seek error.';
default:
return "An unknown error [$resultCode] has occurred.";
}
}
}

View File

@@ -1,5 +1,6 @@
<?php namespace Chumper\Zipper;
<?php
namespace Chumper\Zipper;
use Chumper\Zipper\Repositories\RepositoryInterface;
use Exception;
@@ -9,11 +10,9 @@ use Illuminate\Filesystem\Filesystem;
* This Zipper class is a wrapper around the ZipArchive methods with some handy functions
*
* Class Zipper
* @package Chumper\Zipper
*/
class Zipper
{
/**
* Constant for extracting
*/
@@ -24,6 +23,11 @@ class Zipper
*/
const BLACKLIST = 2;
/**
* Constant for matching only strictly equal file names
*/
const EXACT_MATCH = 4;
/**
* @var string Represents the current location in the archive
*/
@@ -49,11 +53,21 @@ class Zipper
*
* @param Filesystem $fs
*/
function __construct(Filesystem $fs = null)
public function __construct(Filesystem $fs = null)
{
$this->file = $fs ? $fs : new Filesystem();
}
/**
* Destructor
*/
public function __destruct()
{
if (null !== $this->repository) {
$this->repository->close();
}
}
/**
* Create a new zip Archive if the file does not exists
* opens a zip archive if the file exists
@@ -61,6 +75,10 @@ class Zipper
* @param $pathToFile string The file to open
* @param RepositoryInterface|string $type The type of the archive, defaults to zip, possible are zip, phar
*
* @throws \RuntimeException
* @throws \Exception
* @throws \InvalidArgumentException
*
* @return $this Zipper instance
*/
public function make($pathToFile, $type = 'zip')
@@ -68,12 +86,19 @@ class Zipper
$new = $this->createArchiveFile($pathToFile);
$this->filePath = $pathToFile;
$name = 'Chumper\Zipper\Repositories\\' . ucwords($type) . 'Repository';
if (is_subclass_of($name, 'Chumper\Zipper\Repositories\RepositoryInterface'))
$this->repository = new $name($pathToFile, $new);
else
//TODO $type should be a class name and not a string
$this->repository = $type;
$objectOrName = $type;
if (is_string($type)) {
$objectOrName = 'Chumper\Zipper\Repositories\\'.ucwords($type).'Repository';
}
if (!is_subclass_of($objectOrName, 'Chumper\Zipper\Repositories\RepositoryInterface')) {
throw new \InvalidArgumentException("Class for '{$objectOrName}' must implement RepositoryInterface interface");
}
$this->repository = $type;
if (is_string($objectOrName)) {
$this->repository = new $objectOrName($pathToFile, $new);
}
return $this;
}
@@ -82,11 +107,15 @@ class Zipper
* Create a new zip archive or open an existing one
*
* @param $pathToFile
*
* @throws \Exception
*
* @return $this
*/
public function zip($pathToFile)
{
$this->make($pathToFile);
return $this;
}
@@ -94,48 +123,115 @@ class Zipper
* Create a new phar file or open one
*
* @param $pathToFile
*
* @throws \Exception
*
* @return $this
*/
public function phar($pathToFile)
{
$this->make($pathToFile, 'phar');
return $this;
}
/**
* Create a new rar file or open one
*
* @param $pathToFile
*
* @throws \Exception
*
* @return $this
*/
public function rar($pathToFile)
{
$this->make($pathToFile, 'rar');
return $this;
}
/**
* Extracts the opened zip archive to the specified location <br/>
* you can provide an array of files and folders and define if they should be a white list
* or a black list to extract.
* or a black list to extract. By default this method compares file names using "string starts with" logic
*
* @param $path string The path to extract to
* @param array $files An array of files
* @param int $method The Method the files should be treated
* @param array $files An array of files
* @param int $methodFlags The Method the files should be treated
*
* @throws \Exception
*/
public function extractTo($path, array $files = array(), $method = Zipper::BLACKLIST)
public function extractTo($path, array $files = [], $methodFlags = self::BLACKLIST)
{
$path = realpath($path);
if (!$this->file->exists($path))
$this->file->makeDirectory($path, 0755, true);
if (!$this->file->exists($path) && !$this->file->makeDirectory($path, 0755, true)) {
throw new \RuntimeException('Failed to create folder');
}
if ($method == Zipper::WHITELIST)
$this->extractWithWhiteList($path, $files);
else
$this->extractWithBlackList($path, $files);
if ($methodFlags & self::EXACT_MATCH) {
$matchingMethod = function ($haystack) use ($files) {
return in_array($haystack, $files, true);
};
} else {
$matchingMethod = function ($haystack) use ($files) {
return starts_with($haystack, $files);
};
}
if ($methodFlags & self::WHITELIST) {
$this->extractFilesInternal($path, $matchingMethod);
} else {
// blacklist - extract files that do not match with $matchingMethod
$this->extractFilesInternal($path, function ($filename) use ($matchingMethod) {
return !$matchingMethod($filename);
});
}
}
/**
* Extracts matching files/folders from the opened zip archive to the specified location.
*
* @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)
{
if (empty($regex)) {
throw new \InvalidArgumentException('Missing pass valid regex parameter');
}
$this->extractFilesInternal($extractToPath, function ($filename) use ($regex) {
$match = preg_match($regex, $filename);
if ($match === 1) {
return true;
} elseif ($match === false) {
//invalid pattern for preg_match raises E_WARNING and returns FALSE
//so if you have custom error_handler set to catch and throw E_WARNINGs you never end up here
//but if you have not - this will throw exception
throw new \RuntimeException("regular expression match on '$filename' failed with error. Please check if pattern is valid regular expression.");
}
return false;
});
}
/**
* Gets the content of a single file if available
*
* @param $filePath string The full path (including all folders) of the file in the zip
*
* @throws \Exception
*
* @return mixed returns the content or throws an exception
*/
public function getFileContent($filePath)
{
if ($this->repository->fileExists($filePath) === false)
if ($this->repository->fileExists($filePath) === false) {
throw new Exception(sprintf('The file "%s" cannot be found', $filePath));
}
return $this->repository->getFileContent($filePath);
}
@@ -143,27 +239,53 @@ class Zipper
* Add one or multiple files to the zip.
*
* @param $pathToAdd array|string An array or string of files and folders to add
* @param null|mixed $fileName
*
* @return $this Zipper instance
*/
public function add($pathToAdd)
public function add($pathToAdd, $fileName = null)
{
if (is_array($pathToAdd)) {
foreach ($pathToAdd as $dir) {
$this->add($dir);
foreach ($pathToAdd as $key=>$dir) {
if (!is_int($key)) {
$this->add($dir, $key); }
else {
$this->add($dir);
}
}
} else if ($this->file->isFile($pathToAdd)) {
$this->addFile($pathToAdd);
} else
} elseif ($this->file->isFile($pathToAdd)) {
if ($fileName) {
$this->addFile($pathToAdd, $fileName);
} else {
$this->addFile($pathToAdd);
}
} else {
$this->addDir($pathToAdd);
}
return $this;
}
/**
* Add an empty directory
*
* @param $dirName
*
* @return Zipper
*/
public function addEmptyDir($dirName)
{
$this->repository->addEmptyDir($dirName);
return $this;
}
/**
* Add a file to the zip using its contents
*
* @param $filename string The name of the file to create
* @param $content string The file contents
* @param $content string The file contents
*
* @return $this Zipper instance
*/
public function addString($filename, $content)
@@ -172,12 +294,11 @@ class Zipper
return $this;
}
/**
* Gets the status of the zip.
*
* @return integer The status of the internal zip file
* @return int The status of the internal zip file
*/
public function getStatus()
{
@@ -188,6 +309,7 @@ class Zipper
* Remove a file or array of files and folders from the zip archive
*
* @param $fileToRemove array|string The path/array to the files in the zip
*
* @return $this Zipper instance
*/
public function remove($fileToRemove)
@@ -199,14 +321,16 @@ class Zipper
$self->getRepository()->removeFile($file);
}
});
} else
} else {
$this->repository->removeFile($fileToRemove);
}
return $this;
}
/**
* Returns the path of the current zip file if there is one.
*
* @return string The path to the file
*/
public function getFilePath()
@@ -214,25 +338,41 @@ class Zipper
return $this->filePath;
}
/**
* Sets the password to be used for decompressing
*
* @param $password
*
* @return bool
*/
public function usePassword($password)
{
return $this->repository->usePassword($password);
}
/**
* Closes the zip file and frees all handles
*/
public function close()
{
if(!is_null($this->repository))
if (null !== $this->repository) {
$this->repository->close();
$this->filePath = "";
}
$this->filePath = '';
}
/**
* Sets the internal folder to the given path.<br/>
* Useful for extracting only a segment of a zip file.
*
* @param $path
*
* @return $this
*/
public function folder($path)
{
$this->currentFolder = $path;
return $this;
}
@@ -244,6 +384,7 @@ class Zipper
public function home()
{
$this->currentFolder = '';
return $this;
}
@@ -252,11 +393,12 @@ class Zipper
*/
public function delete()
{
if(!is_null($this->repository))
if (null !== $this->repository) {
$this->repository->close();
}
$this->file->delete($this->filePath);
$this->filePath = "";
$this->filePath = '';
}
/**
@@ -269,15 +411,6 @@ class Zipper
return get_class($this->repository);
}
/**
* Destructor
*/
public function __destruct()
{
if(!is_null($this->repository))
$this->repository->close();
}
/**
* Get the current internal folder pointer
*
@@ -292,6 +425,7 @@ class Zipper
* Checks if a file is present in the archive
*
* @param $fileInArchive
*
* @return bool
*/
public function contains($fileInArchive)
@@ -322,28 +456,81 @@ class Zipper
*/
public function getInternalPath()
{
return empty($this->currentFolder) ? '' : $this->currentFolder . '/';
return empty($this->currentFolder) ? '' : $this->currentFolder.'/';
}
/**
* List all files that are within the archive
*
* @param string|null $regexFilter regular expression to filter returned files/folders. See @link http://php.net/manual/en/reference.pcre.pattern.syntax.php
*
* @throws \RuntimeException
*
* @return array
*/
public function listFiles($regexFilter = null)
{
$filesList = [];
if ($regexFilter) {
$filter = function ($file) use (&$filesList, $regexFilter) {
// push/pop an error handler here to to make sure no error/exception thrown if $expected is not a regex
set_error_handler(function () {
});
$match = preg_match($regexFilter, $file);
restore_error_handler();
if ($match === 1) {
$filesList[] = $file;
} elseif ($match === false) {
throw new \RuntimeException("regular expression match on '$file' failed with error. Please check if pattern is valid regular expression.");
}
};
} else {
$filter = function ($file) use (&$filesList) {
$filesList[] = $file;
};
}
$this->repository->each($filter);
return $filesList;
}
private function getCurrentFolderWithTrailingSlash()
{
if (empty($this->currentFolder)) {
return '';
}
$lastChar = mb_substr($this->currentFolder, -1);
if ($lastChar !== '/' || $lastChar !== '\\') {
return $this->currentFolder.'/';
}
return $this->currentFolder;
}
//---------------------PRIVATE FUNCTIONS-------------
/**
* @param $pathToZip
*
* @throws \Exception
*
* @return bool
*/
private function createArchiveFile($pathToZip)
{
if (!$this->file->exists($pathToZip)) {
if (!$this->file->exists(dirname($pathToZip)))
$this->file->makeDirectory(dirname($pathToZip), 0755, true);
if (!$this->file->isWritable(dirname($pathToZip)))
$dirname = dirname($pathToZip);
if (!$this->file->exists($dirname) && !$this->file->makeDirectory($dirname, 0755, true)) {
throw new \RuntimeException('Failed to create folder');
} elseif (!$this->file->isWritable($dirname)) {
throw new Exception(sprintf('The path "%s" is not writeable', $pathToZip));
}
return true;
}
return false;
}
@@ -354,14 +541,14 @@ class Zipper
{
// First go over the files in this directory and add them to the repository.
foreach ($this->file->files($pathToDir) as $file) {
$this->addFile($pathToDir . '/' . basename($file));
$this->addFile($pathToDir.'/'.basename($file));
}
// Now let's visit the subdirectories and add them, too.
foreach ($this->file->directories($pathToDir) as $dir) {
$old_folder = $this->currentFolder;
$this->currentFolder = empty($this->currentFolder) ? basename($dir) : $this->currentFolder . '/' . basename($dir);
$this->addDir($pathToDir . '/' . basename($dir));
$this->currentFolder = empty($this->currentFolder) ? basename($dir) : $this->currentFolder.'/'.basename($dir);
$this->addDir($pathToDir.'/'.basename($dir));
$this->currentFolder = $old_folder;
}
}
@@ -369,106 +556,67 @@ class Zipper
/**
* Add the file to the zip
*
* @param $pathToAdd
* @param string $pathToAdd
* @param string $fileName
*/
private function addFile($pathToAdd)
private function addFile($pathToAdd, $fileName = null)
{
$info = pathinfo($pathToAdd);
$file_name = isset($info['extension']) ?
$info['filename'] . '.' . $info['extension'] :
$info['filename'];
if (!$fileName) {
$fileName = isset($info['extension']) ?
$info['filename'].'.'.$info['extension'] :
$info['filename'];
}
$this->repository->addFile($pathToAdd, $this->getInternalPath() . $file_name);
$this->repository->addFile($pathToAdd, $this->getInternalPath().$fileName);
}
/**
* Add the file to the zip from content
*
* @param $filename
* @param $content
* @param $content
*/
private function addFromString($filename, $content)
{
$this->repository->addFromString($this->getInternalPath() . $filename, $content);
$this->repository->addFromString($this->getInternalPath().$filename, $content);
}
/**
* @param $path
* @param $filesArray
* @throws \Exception
*/
private function extractWithBlackList($path, $filesArray)
private function extractFilesInternal($path, callable $matchingMethod)
{
$self = $this;
$this->repository->each(function ($fileName) use ($path, $filesArray, $self) {
$oriName = $fileName;
$currentPath = $self->getCurrentFolderPath();
if (!empty($currentPath) && !starts_with($fileName, $currentPath))
return;
if (starts_with($fileName, $filesArray)) {
$this->repository->each(function ($fileName) use ($path, $matchingMethod, $self) {
$currentPath = $self->getCurrentFolderWithTrailingSlash();
if (!empty($currentPath) && !starts_with($fileName, $currentPath)) {
return;
}
$tmpPath = str_replace($self->getInternalPath(), '', $fileName);
// We need to create the directory first in case it doesn't exist
$full_path = $path . '/' . $tmpPath;
$dir = substr($full_path, 0, strrpos($full_path, '/'));
if(!is_dir($dir))
$self->getFileHandler()->makeDirectory($dir, 0777, true, true);
$self->getFileHandler()->put($path . '/' . $tmpPath, $self->getRepository()->getFileStream($oriName));
});
}
/**
* @param $path
* @param $filesArray
* @throws \Exception
*/
private function extractWithWhiteList($path, $filesArray)
{
$self = $this;
$this->repository->each(function ($fileName) use ($path, $filesArray, $self) {
$oriName = $fileName;
$currentPath = $self->getCurrentFolderPath();
if (!empty($currentPath) && !starts_with($fileName, $currentPath))
return;
if (starts_with($self->getInternalPath() . $fileName, $filesArray)) {
$tmpPath = str_replace($self->getInternalPath(), '', $fileName);
// We need to create the directory first in case it doesn't exist
$full_path = $path . '/' . $tmpPath;
$dir = substr($full_path, 0, strrpos($full_path, '/'));
if(!is_dir($dir))
$self->getFileHandler()->makeDirectory($dir, 0777, true, true);
$self->getFileHandler()->put($path . '/' . $tmpPath, $self->getRepository()->getFileStream($oriName));
$filename = str_replace($self->getInternalPath(), '', $fileName);
if ($matchingMethod($filename)) {
$self->extractOneFileInternal($fileName, $path);
}
});
}
/**
* List files that are within the archive
* @param $fileName
* @param $path
*
* @return array
* @throws \RuntimeException
*/
public function listFiles()
private function extractOneFileInternal($fileName, $path)
{
$filesList = array();
$this->repository->each(
function ($file) use (&$filesList) {
$filesList[] = $file;
}
);
$tmpPath = str_replace($this->getInternalPath(), '', $fileName);
return $filesList;
// We need to create the directory first in case it doesn't exist
$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');
}
$toPath = $path.DIRECTORY_SEPARATOR.$tmpPath;
$fileStream = $this->getRepository()->getFileStream($fileName);
$this->getFileHandler()->put($toPath, $fileStream);
}
}

View File

@@ -1,55 +1,50 @@
<?php namespace Chumper\Zipper;
<?php
namespace Chumper\Zipper;
use Illuminate\Foundation\AliasLoader;
use Illuminate\Support\ServiceProvider;
class ZipperServiceProvider extends ServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
class ZipperServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app['zipper'] = $this->app->share(function($app)
{
$this->app->singleton('zipper', function ($app) {
$return = $app->make('Chumper\Zipper\Zipper');
return $return;
});
$this->app->booting(function()
{
$this->app->booting(function () {
$loader = AliasLoader::getInstance();
$loader->alias('Zipper', 'Chumper\Zipper\Facades\Zipper');
});
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return array('zipper');
}
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['zipper'];
}
}

View File

View File

@@ -1,10 +1,12 @@
<?php
namespace Chumper\Zipper;
use Chumper\Zipper\Repositories\RepositoryInterface;
class ArrayArchive implements RepositoryInterface
{
private $entries = array();
private $entries = [];
/**
* Construct with a given path
@@ -13,7 +15,7 @@ class ArrayArchive implements RepositoryInterface
* @param bool $new
* @param $archiveImplementation
*/
function __construct($filePath, $new = false, $archiveImplementation = null)
public function __construct($filePath, $new = false, $archiveImplementation = null)
{
}
@@ -22,18 +24,27 @@ class ArrayArchive implements RepositoryInterface
*
* @param $pathToFile
* @param $pathInArchive
* @return void
*/
public function addFile($pathToFile, $pathInArchive)
{
$this->entries[$pathInArchive] = $pathInArchive;
}
/**
* Add a file to the opened Archive using its contents
*
* @param $name
* @param $content
*/
public function addFromString($name, $content)
{
$this->entries[$name] = $name;
}
/**
* Remove a file permanently from the Archive
*
* @param $pathInArchive
* @return void
*/
public function removeFile($pathInArchive)
{
@@ -44,6 +55,7 @@ class ArrayArchive implements RepositoryInterface
* Get the content of a file
*
* @param $pathInArchive
*
* @return string
*/
public function getFileContent($pathInArchive)
@@ -55,6 +67,7 @@ class ArrayArchive implements RepositoryInterface
* Get the stream of a file
*
* @param $pathInArchive
*
* @return mixed
*/
public function getFileStream($pathInArchive)
@@ -67,23 +80,22 @@ class ArrayArchive implements RepositoryInterface
* Will provide the filename for every item
*
* @param $callback
* @return void
*/
public function each($callback)
{
foreach ($this->entries as $entry) {
call_user_func_array($callback, array(
call_user_func_array($callback, [
'file' => $entry,
));
]);
}
}
/**
* Checks whether the file is in the archive
*
* @param $fileInArchive
* @return boolean
*
* @return bool
*/
public function fileExists($fileInArchive)
{
@@ -97,14 +109,33 @@ class ArrayArchive implements RepositoryInterface
*/
public function getStatus()
{
return "OK";
return 'OK';
}
/**
* Closes the archive and saves it
* @return void
*/
public function close()
{
}
/**
* Add an empty directory
*
* @param $dirName
*/
public function addEmptyDir($dirName)
{
// CODE...
}
/**
* Sets the password to be used for decompressing
*
* @param $password
*/
public function usePassword($password)
{
// CODE...
}
}

View File

@@ -1,5 +1,10 @@
<?php
use Chumper\Zipper\Repositories\ZipRepository;
namespace Chumper\Zipper\Repositories;
use Exception;
use Mockery;
use ZipArchive;
/**
* Created by JetBrains PhpStorm.
@@ -8,10 +13,8 @@ use Chumper\Zipper\Repositories\ZipRepository;
* Time: 20:57
* To change this template use File | Settings | File Templates.
*/
class ZipRepositoryTest extends PHPUnit_Framework_TestCase
class ZipRepositoryTest extends \PHPUnit_Framework_TestCase
{
/**
* @var ZipRepository
*/
@@ -24,16 +27,35 @@ class ZipRepositoryTest extends PHPUnit_Framework_TestCase
public function setUp()
{
$this->mock = Mockery::mock(new ZipArchive);
$this->mock = Mockery::mock(new ZipArchive());
$this->zip = new ZipRepository('foo', true, $this->mock);
}
protected function tearDown()
{
Mockery::close();
}
public function testMake()
{
$zip = new ZipRepository('foo.zip', true);
$this->assertFalse($zip->fileExists('foo'));
}
public function testOpenNonExistentZipThrowsException()
{
$this->expectException(Exception::class);
$this->expectExceptionMessage('Error: Failed to open idonotexist.zip! Error: ZipArchive::ER_');
new ZipRepository('idonotexist.zip', false);
}
public function testOpenNonZipThrowsException()
{
$this->expectException(Exception::class);
$this->expectExceptionMessageRegExp('/Error: Failed to open (.*)ZipRepositoryTest.php! Error: ZipArchive::ER_NOZIP - Not a zip archive./');
new ZipRepository(__DIR__.DIRECTORY_SEPARATOR.'ZipRepositoryTest.php', false);
}
public function testAddFile()
{
$this->mock->shouldReceive('addFile')->once()->with('bar', 'bar');
@@ -61,8 +83,8 @@ class ZipRepositoryTest extends PHPUnit_Framework_TestCase
$this->mock->shouldReceive('getFromName')->once()
->with('foo/bar')->andReturn('baz');
$this->assertEquals('foo', $this->zip->getFileContent('bar'));
$this->assertEquals('baz', $this->zip->getFileContent('foo/bar'));
$this->assertSame('foo', $this->zip->getFileContent('bar'));
$this->assertSame('baz', $this->zip->getFileContent('foo/bar'));
}
public function testGetFileStream()
@@ -72,8 +94,8 @@ class ZipRepositoryTest extends PHPUnit_Framework_TestCase
$this->mock->shouldReceive('getStream')->once()
->with('foo/bar')->andReturn('baz');
$this->assertEquals('foo', $this->zip->getFileStream('bar'));
$this->assertEquals('baz', $this->zip->getFileStream('foo/bar'));
$this->assertSame('foo', $this->zip->getFileStream('bar'));
$this->assertSame('baz', $this->zip->getFileStream('foo/bar'));
}
public function testFileExists()
@@ -91,11 +113,4 @@ class ZipRepositoryTest extends PHPUnit_Framework_TestCase
{
$this->zip->close();
}
protected function tearDown()
{
Mockery::close();
}
}

View File

@@ -1,14 +1,15 @@
<?php
use Chumper\Zipper\Zipper;
namespace Chumper\Zipper;
use Exception;
use Illuminate\Filesystem\Filesystem;
use InvalidArgumentException;
use Mockery;
use RuntimeException;
require_once 'ArrayArchive.php';
class ZipperTest extends PHPUnit_Framework_TestCase
class ZipperTest extends \PHPUnit_Framework_TestCase
{
/**
* @var \Chumper\Zipper\Zipper
*/
@@ -19,78 +20,121 @@ class ZipperTest extends PHPUnit_Framework_TestCase
*/
public $file;
public function __construct()
protected function setUp()
{
$this->archive = new \Chumper\Zipper\Zipper(
$this->file = Mockery::mock(new Filesystem)
);
$this->file = Mockery::mock(new Filesystem());
$this->archive = new Zipper($this->file);
$this->archive->make('foo', new ArrayArchive('foo', true));
}
protected function tearDown()
{
Mockery::close();
}
public function testMake()
{
$this->assertEquals('ArrayArchive', $this->archive->getArchiveType());
$this->assertEquals('foo', $this->archive->getFilePath());
$this->assertSame('Chumper\\Zipper\\ArrayArchive', $this->archive->getArchiveType());
$this->assertSame('foo', $this->archive->getFilePath());
}
public function testExtractTo()
public function testMakeThrowsExceptionWhenCouldNotCreateDirectory()
{
$path = getcwd().time();
$this->file->shouldReceive('makeDirectory')
->with($path, 0755, true)
->andReturn(false);
$zip = new Zipper($this->file);
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Failed to create folder');
$zip->make($path.DIRECTORY_SEPARATOR.'createMe.zip');
}
public function testAddAndGet()
{
$this->file->shouldReceive('isFile')->with('foo.bar')
->times(3)->andReturn(true);
->times(1)->andReturn(true);
$this->file->shouldReceive('isFile')->with('foo')
->times(3)->andReturn(true);
->times(1)->andReturn(true);
$this->archive->add('foo.bar');
$this->archive->add('foo');
$this->assertSame('foo', $this->archive->getFileContent('foo'));
$this->assertSame('foo.bar', $this->archive->getFileContent('foo.bar'));
}
public function testAddAndGetWithArray()
{
$this->file->shouldReceive('isFile')->with('foo.bar')
->times(1)->andReturn(true);
$this->file->shouldReceive('isFile')->with('foo')
->times(1)->andReturn(true);
/**Array**/
$this->archive->add([
'foo.bar',
'foo',
]);
$this->assertSame('foo', $this->archive->getFileContent('foo'));
$this->assertSame('foo.bar', $this->archive->getFileContent('foo.bar'));
}
public function testAddAndGetWithCustomFilenameArray()
{
$this->file->shouldReceive('isFile')->with('foo.bar')
->times(1)->andReturn(true);
$this->file->shouldReceive('isFile')->with('foo')
->times(1)->andReturn(true);
/**Array**/
$this->archive->add([
'custom.bar' => 'foo.bar',
'custom' => 'foo',
]);
$this->assertSame('custom', $this->archive->getFileContent('custom'));
$this->assertSame('custom.bar', $this->archive->getFileContent('custom.bar'));
}
public function testAddAndGetWithSubFolder()
{
/*
* Add the local folder /path/to/fooDir as folder fooDir to the repository
* and make sure the folder structure within the repository is there.
*/
$this->file->shouldReceive('isFile')->with('/path/to/fooDir')
->once()->andReturn(false);
$this->file->shouldReceive('files')->with('/path/to/fooDir')
->once()->andReturn(array('foo.bar', 'bar.foo'));
->once()->andReturn(['fileInFooDir.bar', 'fileInFooDir.foo']);
$this->file->shouldReceive('directories')->with('/path/to/fooDir')
->once()->andReturn(array('fooSubdir'));
->once()->andReturn(['fooSubdir']);
$this->file->shouldReceive('files')->with('/path/to/fooDir/fooSubdir')
->once()->andReturn(array('foo.bar'));
->once()->andReturn(['fileInFooDir.bar']);
$this->file->shouldReceive('directories')->with('/path/to/fooDir/fooSubdir')
->once()->andReturn(array());
->once()->andReturn([]);
//test1
$this->archive->add('foo.bar');
$this->archive->add('foo');
$this->assertEquals('foo', $this->archive->getFileContent('foo'));
$this->assertEquals('foo.bar', $this->archive->getFileContent('foo.bar'));
//test2
$this->archive->add(array(
'foo.bar',
'foo'
));
$this->assertEquals('foo', $this->archive->getFileContent('foo'));
$this->assertEquals('foo.bar', $this->archive->getFileContent('foo.bar'));
/**
* test3:
* Add the local folder /path/to/fooDir as folder fooDir to the repository
* and make sure the folder structure within the repository is there.
*/
$this->archive->folder('fooDir')->add('/path/to/fooDir');
$this->assertEquals('fooDir/foo.bar', $this->archive->getFileContent('fooDir/foo.bar'));
$this->assertEquals('fooDir/bar.foo', $this->archive->getFileContent('fooDir/bar.foo'));
$this->assertEquals('fooDir/fooSubdir/foo.bar', $this->archive->getFileContent('fooDir/fooSubdir/foo.bar'));
$this->archive->folder('fooDir')
->add('/path/to/fooDir');
$this->assertSame('fooDir/fileInFooDir.bar', $this->archive->getFileContent('fooDir/fileInFooDir.bar'));
$this->assertSame('fooDir/fileInFooDir.foo', $this->archive->getFileContent('fooDir/fileInFooDir.foo'));
$this->assertSame('fooDir/fooSubdir/fileInFooDir.bar', $this->archive->getFileContent('fooDir/fooSubdir/fileInFooDir.bar'));
}
/**
* @expectedException Exception
*/
public function testGetFileContent()
{
$this->expectException(Exception::class);
$this->expectExceptionMessage('The file "baz" cannot be found');
$this->archive->getFileContent('baz');
}
@@ -114,12 +158,12 @@ class ZipperTest extends PHPUnit_Framework_TestCase
$this->file->shouldReceive('isFile')->with('fooBar')
->andReturn(true);
$this->archive->add(array('foo', 'fooBar'));
$this->archive->add(['foo', 'fooBar']);
$this->assertTrue($this->archive->contains('foo'));
$this->assertTrue($this->archive->contains('fooBar'));
$this->archive->remove(array('foo', 'fooBar'));
$this->archive->remove(['foo', 'fooBar']);
$this->assertFalse($this->archive->contains('foo'));
$this->assertFalse($this->archive->contains('fooBar'));
@@ -127,53 +171,222 @@ class ZipperTest extends PHPUnit_Framework_TestCase
public function testExtractWhiteList()
{
$this->file->shouldReceive('isFile')->with('foo')
$this->file
->shouldReceive('isFile')
->with('foo')
->andReturn(true);
$this->archive->add('foo');
$this->file->shouldReceive('put')->with(realpath(NULL) . '/foo', 'foo');
$this->archive->extractTo('', array('foo'), Zipper::WHITELIST);
//----
$this->file->shouldReceive('isFile')->with('foo')
$this->file
->shouldReceive('isFile')
->with('foo.log')
->andReturn(true);
$this->archive->folder('foo/bar')->add('foo');
$this->archive
->add('foo')
->add('foo.log');
$this->file->shouldReceive('put')->with(realpath(NULL) . '/foo', 'foo/bar/foo');
$this->file
->shouldReceive('put')
->with(realpath(null).DIRECTORY_SEPARATOR.'foo', 'foo');
$this->archive->extractTo('', array('foo'), Zipper::WHITELIST);
$this->file
->shouldReceive('put')
->with(realpath(null).DIRECTORY_SEPARATOR.'foo.log', 'foo.log');
$this->archive
->extractTo(getcwd(), ['foo'], Zipper::WHITELIST);
}
public function testExtractBlackList()
public function testExtractToThrowsExceptionWhenCouldNotCreateDirectory()
{
$path = getcwd().time();
$this->file
->shouldReceive('isFile')
->with('foo.log')
->andReturn(true);
$this->file->shouldReceive('makeDirectory')
->with($path, 0755, true)
->andReturn(false);
$this->archive->add('foo.log');
$this->file->shouldNotReceive('put')
->with(realpath(null).DIRECTORY_SEPARATOR.'foo.log', 'foo.log');
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Failed to create folder');
$this->archive
->extractTo($path, ['foo'], Zipper::WHITELIST);
}
public function testExtractWhiteListFromSubDirectory()
{
$this->file->shouldReceive('isFile')->andReturn(true);
$this->file->shouldReceive('makeDirectory')->andReturn(true);
$this->archive
->folder('foo/bar')
->add('baz')
->add('baz.log');
$this->file
->shouldReceive('put')
->with(realpath(null).DIRECTORY_SEPARATOR.'baz', 'foo/bar/baz');
$this->file
->shouldReceive('put')
->with(realpath(null).DIRECTORY_SEPARATOR.'baz.log', 'foo/bar/baz.log');
$this->archive
->extractTo(getcwd(), ['baz'], Zipper::WHITELIST);
}
public function testExtractWhiteListWithExactMatching()
{
$this->file->shouldReceive('isFile')->andReturn(true);
$this->file->shouldReceive('makeDirectory')->andReturn(true);
$this->archive
->folder('foo/bar')
->add('baz')
->add('baz.log');
$this->file
->shouldReceive('put')
->with(realpath(null).DIRECTORY_SEPARATOR.'baz', 'foo/bar/baz');
$this->archive
->extractTo(getcwd(), ['baz'], Zipper::WHITELIST | Zipper::EXACT_MATCH);
}
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')
->add('bazInSubDirectory')
->add('bazInSubDirectory.log');
$this->archive->folder('foo/bar')
->add('baz')
->add('baz.log');
$subDirectoryPath = realpath(null).DIRECTORY_SEPARATOR.'subDirectory';
$subDirectoryFilePath = $subDirectoryPath.'/bazInSubDirectory';
$this->file->shouldReceive('put')
->with($subDirectoryFilePath, 'foo/bar/subDirectory/bazInSubDirectory');
$this->archive
->extractTo(getcwd(), ['subDirectory/bazInSubDirectory'], Zipper::WHITELIST | Zipper::EXACT_MATCH);
$this->file->shouldHaveReceived('makeDirectory')->with($subDirectoryPath, 0755, true, true);
}
public function testExtractToIgnoresBlackListFile()
{
$this->file->shouldReceive('isFile')->with('foo')
->andReturn(true);
$this->file->shouldReceive('isFile')->with('bar')
->andReturn(true);
$this->file->shouldReceive('makeDirectory')->andReturn(true);
$this->archive->add('foo');
$this->archive->add('foo')
->add('bar');
$this->file->shouldReceive('put')->with(realpath(NULL) . '/foo', 'foo');
$this->file->shouldReceive('put')->with(realpath(null).DIRECTORY_SEPARATOR.'foo', 'foo');
$this->file->shouldNotReceive('put')->with(realpath(null).DIRECTORY_SEPARATOR.'bar', 'bar');
$this->archive->extractTo('', array(), Zipper::BLACKLIST);
$this->archive->extractTo(getcwd(), ['bar'], Zipper::BLACKLIST);
}
//----
$this->file->shouldReceive('isFile')->with('foo')
public function testExtractBlackListFromSubDirectory()
{
$currentDir = getcwd();
$this->file->shouldReceive('isFile')->andReturn(true);
$this->file->shouldReceive('makeDirectory')->andReturn(true);
$this->archive->add('rootLevelFile');
$this->archive->folder('foo/bar/sub')
->add('fileInSubSubDir');
$this->archive->folder('foo/bar')
->add('fileInSubDir')
->add('fileBlackListedInSubDir');
$this->file->shouldReceive('put')->with($currentDir.DIRECTORY_SEPARATOR.'fileInSubDir', 'foo/bar/fileInSubDir');
$this->file->shouldReceive('put')->with($currentDir.DIRECTORY_SEPARATOR.'sub/fileInSubSubDir', 'foo/bar/sub/fileInSubSubDir');
$this->file->shouldNotReceive('put')->with($currentDir.DIRECTORY_SEPARATOR.'fileBlackListedInSubDir', 'fileBlackListedInSubDir');
$this->file->shouldNotReceive('put')->with($currentDir.DIRECTORY_SEPARATOR.'rootLevelFile', 'rootLevelFile');
$this->archive->extractTo($currentDir, ['fileBlackListedInSubDir'], Zipper::BLACKLIST);
}
public function testExtractBlackListFromSubDirectoryWithExactMatching()
{
$this->file->shouldReceive('isFile')->with('baz')
->andReturn(true);
$this->file->shouldReceive('makeDirectory')->andReturn(true);
$this->file->shouldReceive('isFile')->with('baz.log')
->andReturn(true);
$this->archive->folder('foo/bar')->add('foo');
$this->archive->folder('foo/bar')
->add('baz')
->add('baz.log');
$this->file->shouldReceive('put')->with(realpath(NULL) . '/foo', 'foo/bar/foo');
$this->file->shouldReceive('put')->with(realpath(null).DIRECTORY_SEPARATOR.'baz.log', 'foo/bar/baz.log');
$this->archive->extractTo('', array('foo'), Zipper::BLACKLIST);
$this->archive->extractTo(getcwd(), ['baz'], Zipper::BLACKLIST | Zipper::EXACT_MATCH);
}
public function testExtractMatchingRegexFromSubFolder()
{
$this->file->shouldReceive('isFile')->with('baz')->andReturn(true);
$this->file->shouldReceive('isFile')->with('baz.log')->andReturn(true);
$this->file->shouldReceive('isFile')->with('subFolderFileToIgnore')->andReturn(true);
$this->file->shouldReceive('isFile')->with('subFolderFileToExtract.log')->andReturn(true);
$this->file->shouldReceive('isFile')->with('rootLevelMustBeIgnored.log')->andReturn(true);
$this->file->shouldReceive('makeDirectory')->andReturn(true);
$this->archive->add('rootLevelMustBeIgnored.log');
$this->archive->folder('foo/bar/subFolder')
->add('subFolderFileToIgnore')
->add('subFolderFileToExtract.log');
$this->archive->folder('foo/bar')
->add('baz')
->add('baz.log');
$this->file->shouldReceive('put')->with(realpath(null).DIRECTORY_SEPARATOR.'baz.log', 'foo/bar/baz.log');
$this->file->shouldReceive('put')->with(realpath(null).DIRECTORY_SEPARATOR.'subFolder/subFolderFileToExtract.log', 'foo/bar/subFolder/subFolderFileToExtract.log');
$this->file->shouldNotReceive('put')->with(realpath(null).DIRECTORY_SEPARATOR.'rootLevelMustBeIgnored.log', 'rootLevelMustBeIgnored.log');
$this->file->shouldNotReceive('put')->with(realpath(null).DIRECTORY_SEPARATOR.'baz', 'foo/bar/baz');
$this->file->shouldNotReceive('put')->with(realpath(null).DIRECTORY_SEPARATOR.'subFolder/subFolderFileToIgnore', 'foo/bar/subFolder/subFolderFileToIgnore');
$this->archive->extractMatchingRegex(getcwd(), '/\.log$/i');
}
public function testExtractMatchingRegexThrowsExceptionWhenRegexIsEmpty()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage('Missing pass valid regex parameter');
$this->archive->extractMatchingRegex(getcwd(), '');
}
public function testNavigationFolderAndHome()
{
$this->archive->folder('foo/bar');
$this->assertEquals('foo/bar', $this->archive->getCurrentFolderPath());
$this->assertSame('foo/bar', $this->archive->getCurrentFolderPath());
//----
@@ -181,7 +394,7 @@ class ZipperTest extends PHPUnit_Framework_TestCase
->andReturn(true);
$this->archive->add('foo');
$this->assertEquals('foo/bar/foo', $this->archive->getFileContent('foo/bar/foo'));
$this->assertSame('foo/bar/foo', $this->archive->getFileContent('foo/bar/foo'));
//----
@@ -189,7 +402,7 @@ class ZipperTest extends PHPUnit_Framework_TestCase
->andReturn(true);
$this->archive->home()->add('bar');
$this->assertEquals('bar', $this->archive->getFileContent('bar'));
$this->assertSame('bar', $this->archive->getFileContent('bar'));
//----
@@ -197,8 +410,7 @@ class ZipperTest extends PHPUnit_Framework_TestCase
->andReturn(true);
$this->archive->folder('test')->add('baz/bar/bing');
$this->assertEquals('test/bing', $this->archive->getFileContent('test/bing'));
$this->assertSame('test/bing', $this->archive->getFileContent('test/bing'));
}
public function testListFiles()
@@ -207,32 +419,70 @@ class ZipperTest extends PHPUnit_Framework_TestCase
$this->file->shouldReceive('isFile')->with('foo.file')->andReturn(true);
$this->file->shouldReceive('isFile')->with('bar.file')->andReturn(true);
$this->assertEquals(array(), $this->archive->listFiles());
$this->assertSame([], $this->archive->listFiles());
// testing not empty file
$this->archive->add('foo.file');
$this->archive->add('bar.file');
$this->assertEquals(array('foo.file', 'bar.file'), $this->archive->listFiles());
$this->assertSame(['foo.file', 'bar.file'], $this->archive->listFiles());
// testing with a empty sub dir
$this->file->shouldReceive('isFile')->with('/path/to/subDirEmpty')->andReturn(false);
$this->file->shouldReceive('files')->with('/path/to/subDirEmpty')->andReturn(array());
$this->file->shouldReceive('directories')->with('/path/to/subDirEmpty')->andReturn(array());
$this->file->shouldReceive('files')->with('/path/to/subDirEmpty')->andReturn([]);
$this->file->shouldReceive('directories')->with('/path/to/subDirEmpty')->andReturn([]);
$this->archive->folder('subDirEmpty')->add('/path/to/subDirEmpty');
$this->assertEquals(array('foo.file', 'bar.file'), $this->archive->listFiles());
$this->assertSame(['foo.file', 'bar.file'], $this->archive->listFiles());
// testing with a not empty sub dir
$this->file->shouldReceive('isFile')->with('/path/to/subDir')->andReturn(false);
$this->file->shouldReceive('isFile')->with('sub.file')->andReturn(true);
$this->file->shouldReceive('files')->with('/path/to/subDir')->andReturn(array('sub.file'));
$this->file->shouldReceive('directories')->with('/path/to/subDir')->andReturn(array());
$this->file->shouldReceive('files')->with('/path/to/subDir')->andReturn(['sub.file']);
$this->file->shouldReceive('directories')->with('/path/to/subDir')->andReturn([]);
$this->archive->folder('subDir')->add('/path/to/subDir');
$this->assertEquals(array('foo.file', 'bar.file', 'subDir/sub.file'), $this->archive->listFiles());
$this->assertSame(['foo.file', 'bar.file', 'subDir/sub.file'], $this->archive->listFiles());
}
public function testListFilesWithRegexFilter()
{
// add 2 files to root level in zip
$this->file->shouldReceive('isFile')->with('foo.file')->andReturn(true);
$this->file->shouldReceive('isFile')->with('bar.log')->andReturn(true);
$this->archive
->add('foo.file')
->add('bar.log');
// add sub directory with 2 files inside
$this->file->shouldReceive('isFile')->with('/path/to/subDir')->andReturn(false);
$this->file->shouldReceive('isFile')->with('sub.file')->andReturn(true);
$this->file->shouldReceive('isFile')->with('anotherSub.log')->andReturn(true);
$this->file->shouldReceive('files')->with('/path/to/subDir')->andReturn(['sub.file', 'anotherSub.log']);
$this->file->shouldReceive('directories')->with('/path/to/subDir')->andReturn([]);
$this->archive->folder('subDir')->add('/path/to/subDir');
$this->assertSame(
['foo.file', 'subDir/sub.file'],
$this->archive->listFiles('/\.file$/i') // filter out files ending with ".file" pattern
);
}
public function testListFilesThrowsExceptionWithInvalidRegexFilter()
{
$this->file->shouldReceive('isFile')->with('foo.file')->andReturn(true);
$this->archive->add('foo.file');
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('regular expression match on \'foo.file\' failed with error. Please check if pattern is valid regular expression.');
$invalidPattern = 'asdasd';
$this->archive->listFiles($invalidPattern);
}
}