Skip to content

Commit d9e007d

Browse files
authored
ISSUE-47: refactor to ZipArchive and bump dependencies (#48)
* Remove chumper/zipper, add min PHP 7.1 and bump Library versions This also syncs now with frictionlessdata/tableschema: v0.2.0 * Refactor to use Vanilla \ZipArchive() Adds ext-zip to composer.json and checks at Package Class level if the ZipArchive class is present if not Throw \Exception * Fix Utils::removeDir It was assuming always that a direct path was a dir. May not be the case and removes warning during tests * Update .install_cs_fixer.sh Updates php-cs-fixer to 2.18.2. This may be a problem for PHP 7.2 > since fixer is 7.1.* max * Type Hinting Function arguments * PHPDOCS and type hinting Not every function has PHPDocs but we will get there * $descriptor can be JSON or an PHP Object so skipping type hint for now Add more info to PHPDOCS * Data source can be also an array. The @param entry is wrong here * Update BaseResource.php Small PHPDOCS updates * Coding Standards Mostly Indentation and PHPDOCS and type hints * Indent PHPDOCS * Indentation Indentation * Fix Mock function signature * add dev dependency to php_codesniffer and make code psr-2 compliant. This passes php vendor/bin/phpcs --standard=psr2 * CI and composer scripts for phpcs/phpcbf Just a test. Can roll back if this goes against the project's rules * Move to Xenial. Trusty 7.4 has not zip * Removing left over Debug statement * kept ::isZipPresent as public static on Package.php, but called only when needed. Also quite a few PHPDOCs indentations and `@throws`
1 parent 3047665 commit d9e007d

17 files changed

Lines changed: 188 additions & 72 deletions

.install_cs_fixer.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22

33
if [ ! -f ./php-cs-fixer ]; then
4-
wget https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v2.3.2/php-cs-fixer.phar -O php-cs-fixer
4+
wget https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v2.18.2/php-cs-fixer.phar -O php-cs-fixer
55
chmod +x php-cs-fixer
66
fi

.travis.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
language: php
22
php:
3-
- '5.6'
4-
- '7.0'
53
- '7.1'
64
- '7.2'
75
- '7.3'
6+
- '7.4'
87
before_script:
98
- COMPOSER_DISABLE_XDEBUG_WARN=1 composer install --prefer-dist
109
script:
1110
- COMPOSER_DISABLE_XDEBUG_WARN=1 composer test
12-
- '[ "$TRAVIS_PHP_VERSION" != "7.1" ] || composer style-check'
11+
- 'composer style-check'
1312
after_success:
14-
- '[ "$TRAVIS_PHP_VERSION" == "7.1" ] && vendor/bin/coveralls'
15-
dist: trusty
13+
- 'vendor/bin/coveralls'
14+
dist: xenial

composer.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@
33
"description": "A utility library for working with Data Packages",
44
"license": "MIT",
55
"require": {
6-
"php": ">=5.6",
6+
"php": ">=7.1",
7+
"ext-zip": "*",
78
"justinrainbow/json-schema": "^5.2",
8-
"frictionlessdata/tableschema": "^0.1.9",
9-
"chumper/zipper": "1.0.x"
9+
"frictionlessdata/tableschema": "^v0.2.0"
1010
},
1111
"require-dev": {
12-
"phpunit/phpunit": "^4.8.35",
12+
"phpunit/phpunit": "^7.5.20",
1313
"satooshi/php-coveralls": "^1.0",
14-
"psy/psysh": "@stable"
14+
"psy/psysh": "@stable",
15+
"squizlabs/php_codesniffer": "^3.5"
1516
},
1617
"autoload": {
1718
"psr-4": {
@@ -21,7 +22,7 @@
2122
"scripts": {
2223
"test": "phpunit --coverage-clover coverage-clover.xml --bootstrap tests/autoload.php tests/",
2324
"update_registry": "php update_registry.php",
24-
"style-check": "./.install_cs_fixer.sh && ./php-cs-fixer fix --dry-run --verbose --diff",
25-
"style-fix": "./.install_cs_fixer.sh && ./php-cs-fixer fix --verbose"
25+
"style-check": "php vendor/bin/phpcs --standard=psr2 src/ -n",
26+
"style-fix": "php vendor/bin/phpcbf --standard=psr2 src/ -n"
2627
}
2728
}

src/DataStreams/BaseDataStream.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@ abstract class BaseDataStream implements \Iterator
1414
public $dataSourceOptions;
1515

1616
/**
17-
* @param string $dataSource
18-
* @param mixed $dataSourceOptions
19-
*
20-
* @throws \frictionlessdata\datapackage\Exceptions\DataStreamOpenException
17+
* @param $dataSource
18+
* @param mixed $dataSourceOptions
2119
*/
2220
public function __construct($dataSource, $dataSourceOptions = null)
2321
{

src/DataStreams/DefaultDataStream.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,11 @@ class DefaultDataStream extends BaseDataStream
1212
public $fopenResource;
1313

1414
/**
15-
* @param string $dataSource
15+
* @param $dataSource
1616
*
17-
* @throws DataStreamOpenException
17+
* @param null $dataSourceOptions
18+
*
19+
* @throws \frictionlessdata\datapackage\Exceptions\DataStreamOpenException
1820
*/
1921
public function __construct($dataSource, $dataSourceOptions = null)
2022
{

src/Datapackages/BaseDatapackage.php

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,26 @@
33
namespace frictionlessdata\datapackage\Datapackages;
44

55
use frictionlessdata\datapackage\Factory;
6+
use frictionlessdata\datapackage\Package;
67
use frictionlessdata\datapackage\Registry;
78
use frictionlessdata\datapackage\Utils;
89
use frictionlessdata\datapackage\Validators\DatapackageValidator;
910
use frictionlessdata\datapackage\Exceptions\DatapackageValidationFailedException;
10-
use Chumper\Zipper\Zipper;
11+
use frictionlessdata\datapackage\Exceptions\DatapackageInvalidSourceException;
12+
use ZipArchive;
1113

1214
abstract class BaseDatapackage implements \Iterator
1315
{
16+
1417
/**
1518
* BaseDatapackage constructor.
1619
*
17-
* @param object $descriptor
20+
* @param object $descriptor
1821
* @param null|string $basePath
1922
*
20-
* @throws DatapackageValidationFailedException
23+
* @param bool $skipValidations
24+
*
25+
* @throws \frictionlessdata\datapackage\Exceptions\DatapackageValidationFailedException
2126
*/
2227
public function __construct($descriptor, $basePath = null, $skipValidations = false)
2328
{
@@ -168,9 +173,16 @@ public function valid()
168173
return isset($this->descriptor()->resources[$this->currentResourcePosition]);
169174
}
170175

176+
/**
177+
* @param $zip_filename
178+
*
179+
* @throws \frictionlessdata\datapackage\Exceptions\DatapackageInvalidSourceException
180+
* @throws \Exception
181+
*/
171182
public function save($zip_filename)
172183
{
173-
$zipper = new Zipper();
184+
Package::isZipPresent();
185+
$zip = new ZipArchive();
174186
$base = tempnam(sys_get_temp_dir(), 'datapackage-zip-');
175187
$files = [
176188
'datapackage.json' => $base.'datapackage.json',
@@ -185,10 +197,16 @@ public function save($zip_filename)
185197
++$ri;
186198
}
187199
$this->saveDescriptor($files['datapackage.json']);
188-
/* @noinspection PhpUnhandledExceptionInspection Never occurs with our args */
189-
$zipper->make($zip_filename)->add($files)->close();
190-
foreach (array_values($files) as $file) {
191-
unlink($file);
200+
register_shutdown_function(function () use ($base) {
201+
Utils::removeDir($base);
202+
});
203+
if ($zip->open($zip_filename, ZipArchive::CREATE | ZipArchive::OVERWRITE) === true) {
204+
foreach ($files as $filename => $resource) {
205+
$zip->addFile($resource, $filename);
206+
}
207+
$zip->close();
208+
} else {
209+
throw new DatapackageInvalidSourceException('zip file could not be saved.');
192210
}
193211
}
194212

@@ -197,13 +215,14 @@ public function save($zip_filename)
197215
protected $basePath;
198216
protected $skipValidations = false;
199217

200-
/**
201-
* called by the resources iterator for each iteration.
202-
*
203-
* @param object $descriptor
204-
*
205-
* @return \frictionlessdata\datapackage\Resources\BaseResource
206-
*/
218+
/**
219+
* called by the resources iterator for each iteration.
220+
*
221+
* @param object $descriptor
222+
*
223+
* @return \frictionlessdata\datapackage\Resources\BaseResource
224+
* @throws \frictionlessdata\datapackage\Exceptions\ResourceValidationFailedException
225+
*/
207226
protected function initResource($descriptor)
208227
{
209228
return Factory::resource($descriptor, $this->basePath, $this->skipValidations);

src/Factory.php

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use frictionlessdata\datapackage\Datapackages\BaseDatapackage;
66
use frictionlessdata\datapackage\Resources\BaseResource;
7-
use Chumper\Zipper\Zipper;
7+
use ZipArchive;
88

99
/**
1010
* datapackage and resource have different classes depending on the corresponding profile
@@ -32,7 +32,6 @@ class Factory
3232
* @return Datapackages\BaseDatapackage
3333
*
3434
* @throws Exceptions\DatapackageInvalidSourceException
35-
* @throws Exceptions\DatapackageValidationFailedException
3635
*/
3736
public static function datapackage($source, $basePath = null)
3837
{
@@ -54,7 +53,6 @@ public static function datapackage($source, $basePath = null)
5453
*
5554
* @return Resources\BaseResource
5655
*
57-
* @throws Exceptions\ResourceValidationFailedException
5856
*/
5957
public static function resource($descriptor, $basePath = null, $skipValidations = false)
6058
{
@@ -96,7 +94,8 @@ public static function validate($source, $basePath = null)
9694
// return a list containing a single LOAD_FAILED validation error
9795
return [
9896
new Validators\DatapackageValidationError(
99-
Validators\DatapackageValidationError::LOAD_FAILED, $e->getMessage()
97+
Validators\DatapackageValidationError::LOAD_FAILED,
98+
$e->getMessage()
10099
),
101100
];
102101
} catch (Exceptions\DatapackageValidationFailedException $e) {
@@ -158,7 +157,7 @@ public static function clearRegisteredDatapackageClasses()
158157
public static function getDatapackageClass($descriptor)
159158
{
160159
$datapackageClasses = array_merge(
161-
// custom classes
160+
// custom classes
162161
static::$registeredDatapackageClasses,
163162
// core classes
164163
[
@@ -200,7 +199,7 @@ public static function getResourceClass($descriptor)
200199
{
201200
$descriptor = Utils::objectify($descriptor);
202201
$resourceClasses = array_merge(
203-
// custom classes
202+
// custom classes
204203
static::$registeredResourceClasses,
205204
// core classes
206205
[
@@ -229,6 +228,10 @@ public static function getResourceClass($descriptor)
229228
/**
230229
* allows extending classes to add custom sources
231230
* used by unit tests to add a mock http source.
231+
*
232+
* @param $source
233+
*
234+
* @return mixed
232235
*/
233236
protected static function normalizeHttpSource($source)
234237
{
@@ -238,6 +241,8 @@ protected static function normalizeHttpSource($source)
238241
/**
239242
* allows extending classes to add custom sources
240243
* used by unit tests to add a mock http source.
244+
* @param $source
245+
* @return bool
241246
*/
242247
protected static function isHttpSource($source)
243248
{
@@ -256,6 +261,7 @@ protected static function isHttpSource($source)
256261
* @return object
257262
*
258263
* @throws Exceptions\DatapackageInvalidSourceException
264+
* @throws \Exception
259265
*/
260266
protected static function loadSource($source, $basePath)
261267
{
@@ -336,31 +342,54 @@ protected static function isFileZipSource($source)
336342
return strtolower(substr($source, -4)) == '.zip';
337343
}
338344

345+
/**
346+
* @param $source
347+
*
348+
* @return object
349+
* @throws \frictionlessdata\datapackage\Exceptions\DatapackageInvalidSourceException
350+
* @throws \Exception
351+
*/
339352
protected static function loadHttpZipSource($source)
340353
{
354+
Package::isZipPresent();
341355
$tempfile = tempnam(sys_get_temp_dir(), 'datapackage-php');
342356
unlink($tempfile);
343357
$tempfile .= '.zip';
344358
stream_copy_to_stream(fopen($source, 'r'), fopen($tempfile, 'w'));
345-
register_shutdown_function(function () use ($tempfile) {unlink($tempfile); });
359+
register_shutdown_function(function () use ($tempfile) {
360+
unlink($tempfile);
361+
});
346362

347363
return self::loadFileZipSource($tempfile);
348364
}
349365

366+
/**
367+
* @param $source
368+
*
369+
* @return object
370+
* @throws \frictionlessdata\datapackage\Exceptions\DatapackageInvalidSourceException
371+
* @throws \Exception
372+
*/
350373
protected static function loadFileZipSource($source)
351374
{
352-
$zipper = new Zipper();
375+
Package::isZipPresent();
376+
$zip = new ZipArchive();
353377
$tempdir = tempnam(sys_get_temp_dir(), 'datapackage-php');
354378
unlink($tempdir);
355379
mkdir($tempdir);
356-
register_shutdown_function(function () use ($tempdir) {Utils::removeDir($tempdir); });
380+
register_shutdown_function(function () use ($tempdir) {
381+
Utils::removeDir($tempdir);
382+
});
357383
/* @noinspection PhpUnhandledExceptionInspection File existence is checked afterwards anyway */
358-
$zipper->make($source)->extractTo($tempdir);
359-
$zipper->close();
384+
if (($zip->open($source) === true) && ($zip->extractTo($tempdir) === true)) {
385+
$zip->close();
386+
} else {
387+
throw new Exceptions\DatapackageInvalidSourceException('zip file could not be opened from source.');
388+
}
389+
360390
if (!file_exists($tempdir.'/datapackage.json')) {
361391
throw new Exceptions\DatapackageInvalidSourceException('zip file must contain a datapackage.json file');
362392
}
363-
364-
return static::loadSource($tempdir.'/datapackage.json', $tempdir);
393+
return static::loadSource('datapackage.json', $tempdir);
365394
}
366395
}

src/Package.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,44 @@
22

33
namespace frictionlessdata\datapackage;
44

5+
use Exception;
6+
use ZipArchive;
7+
58
class Package
69
{
10+
11+
/**
12+
* @param $source
13+
* @param null $basePath
14+
*
15+
* @return \frictionlessdata\datapackage\Datapackages\BaseDatapackage
16+
* @throws \Exception
17+
* @throws \frictionlessdata\datapackage\Exceptions\DatapackageInvalidSourceException
18+
*/
719
public static function load($source, $basePath = null)
820
{
921
return Factory::datapackage($source, $basePath);
1022
}
1123

24+
/**
25+
* @param $source
26+
* @param null $basePath
27+
*
28+
* @return \frictionlessdata\datapackage\Validators\DatapackageValidationError[]
29+
* @throws \Exception
30+
*/
1231
public static function validate($source, $basePath = null)
1332
{
1433
return Factory::validate($source, $basePath);
1534
}
1635

36+
/**
37+
* @param null $descriptor
38+
* @param null $basePath
39+
*
40+
* @return mixed
41+
* @throws \Exception
42+
*/
1743
public static function create($descriptor = null, $basePath = null)
1844
{
1945
$descriptor = Utils::objectify($descriptor);
@@ -24,4 +50,15 @@ public static function create($descriptor = null, $basePath = null)
2450

2551
return new $packageClass($descriptor, $basePath, true);
2652
}
53+
54+
/**
55+
* @throws \Exception
56+
*/
57+
public static function isZipPresent()
58+
{
59+
//If ZipArchive is not available throw Exception.
60+
if (!class_exists('ZipArchive')) {
61+
throw new Exception('Error: Your PHP version is not compiled with zip support');
62+
}
63+
}
2764
}

0 commit comments

Comments
 (0)