From 8e06f103cf68f7b56147e6afff17149fac0b63bc Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 12:08:18 +0200 Subject: [PATCH 01/14] Remove unnecessary return --- src/Command/ImportDataCommand.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Command/ImportDataCommand.php b/src/Command/ImportDataCommand.php index 6d443853..b8c843ca 100644 --- a/src/Command/ImportDataCommand.php +++ b/src/Command/ImportDataCommand.php @@ -100,8 +100,6 @@ protected function execute(InputInterface $input, OutputInterface $output): void sprintf('Failed %s: %s', $countOrRows, $failed), ] ); - - return; } private function listImporters(InputInterface $input, OutputInterface $output, ?string $errorMessage = null): void From 2d513723ffaf6142ef90ec1d2244988782d8093f Mon Sep 17 00:00:00 2001 From: enesaktay <21998826+enesaktay@users.noreply.github.com> Date: Wed, 25 Jul 2018 12:14:43 +0200 Subject: [PATCH 02/14] remove date check on import --- src/Exporter/MqItemReader.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/Exporter/MqItemReader.php b/src/Exporter/MqItemReader.php index ddf02ba5..e9dc0011 100644 --- a/src/Exporter/MqItemReader.php +++ b/src/Exporter/MqItemReader.php @@ -65,22 +65,10 @@ public function readAndImport(): void /** @var RedisConsumer $consumer */ $consumer = $this->redisContext->createConsumer($this->queue); - $dataTimestampArray = []; - /** @var RedisMessage $message */ while ($message = $consumer->receive()) { $dataArrayToImport = (array) json_decode($message->getBody()); - $dataTimestamp = strtotime($message->getHeader('recordedOn')); - - if (array_key_exists($dataArrayToImport['Id'], $dataTimestampArray)) { - if ($dataTimestampArray[$dataArrayToImport['Id']] >= $dataTimestamp) { - ++$this->messagesSkippedCount; - - continue; - } - } - $dataTimestampArray[$dataArrayToImport['Id']] = $dataTimestamp; $this->service->importSingleDataArrayWithoutResult($dataArrayToImport); ++$this->messagesImportedCount; } From 4242d303359d5cd1b78a40ad112a5b40945e5708 Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 12:59:47 +0200 Subject: [PATCH 03/14] Add phpstan-symfony & phpstan-webmozart-assert --- .travis.yml | 2 +- composer.json | 3 +- composer.lock | 491 +++++++++++++++++++++++++++- phpstan.neon | 7 + tests/Application/app/AppKernel.php | 16 - 5 files changed, 485 insertions(+), 34 deletions(-) diff --git a/.travis.yml b/.travis.yml index 30e62386..dc1012b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -65,7 +65,7 @@ before_script: script: - composer validate --strict - - bin/phpstan.phar analyse -c phpstan.neon -l max src/ + - bin/phpstan analyse -c phpstan.neon -l max src/ - bin/ecs check src/ spec/ tests/Behat/ # - bin/phpunit diff --git a/composer.json b/composer.json index 900f4a24..fef370c3 100644 --- a/composer.json +++ b/composer.json @@ -34,7 +34,8 @@ "friends-of-behat/variadic-extension": "^1.0", "lakion/mink-debug-extension": "^1.2.3", "phpspec/phpspec": "^3.2", - "phpstan/phpstan-shim": "^0.9.2", + "phpstan/phpstan-symfony": "^0.10.0", + "phpstan/phpstan-webmozart-assert": "^0.10.0", "phpunit/phpunit": "^5.6", "portphp/csv": "^1.1.0", "portphp/excel": "^1.1.0", diff --git a/composer.lock b/composer.lock index f9538833..249a12a1 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "872aea1950d60d71f59941aed6f2929c", + "content-hash": "e85bc9b443a1039506c8ddff0e5f1634", "packages": [ { "name": "behat/transliterator", @@ -8654,6 +8654,151 @@ ], "time": "2018-05-29T17:25:09+00:00" }, + { + "name": "nette/bootstrap", + "version": "v2.4.6", + "source": { + "type": "git", + "url": "https://github.com/nette/bootstrap.git", + "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/bootstrap/zipball/268816e3f1bb7426c3a4ceec2bd38a036b532543", + "reference": "268816e3f1bb7426c3a4ceec2bd38a036b532543", + "shasum": "" + }, + "require": { + "nette/di": "~2.4.7", + "nette/utils": "~2.4", + "php": ">=5.6.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "latte/latte": "~2.2", + "nette/application": "~2.3", + "nette/caching": "~2.3", + "nette/database": "~2.3", + "nette/forms": "~2.3", + "nette/http": "~2.4.0", + "nette/mail": "~2.3", + "nette/robot-loader": "^2.4.2 || ^3.0", + "nette/safe-stream": "~2.2", + "nette/security": "~2.3", + "nette/tester": "~2.0", + "tracy/tracy": "^2.4.1" + }, + "suggest": { + "nette/robot-loader": "to use Configurator::createRobotLoader()", + "tracy/tracy": "to use Configurator::enableTracy()" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "๐Ÿ…ฑ Nette Bootstrap: the simple way to configure and bootstrap your Nette application.", + "homepage": "https://nette.org", + "keywords": [ + "bootstrapping", + "configurator", + "nette" + ], + "time": "2018-05-17T12:52:20+00:00" + }, + { + "name": "nette/di", + "version": "v2.4.13", + "source": { + "type": "git", + "url": "https://github.com/nette/di.git", + "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/di/zipball/3f8f212b02d5c17feb97a7e0a39ab306f40c06ca", + "reference": "3f8f212b02d5c17feb97a7e0a39ab306f40c06ca", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "nette/neon": "^2.3.3 || ~3.0.0", + "nette/php-generator": "^2.6.1 || ~3.0.0", + "nette/utils": "^2.4.3 || ~3.0.0", + "php": ">=5.6.0" + }, + "conflict": { + "nette/bootstrap": "<2.4", + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "๐Ÿ’Ž Nette Dependency Injection Container: Flexible, compiled and full-featured DIC with perfectly usable autowiring and support for all new PHP 7.1 features.", + "homepage": "https://nette.org", + "keywords": [ + "compiled", + "di", + "dic", + "factory", + "ioc", + "nette", + "static" + ], + "time": "2018-06-11T08:46:01+00:00" + }, { "name": "nette/finder", "version": "v2.4.2", @@ -8716,6 +8861,129 @@ ], "time": "2018-06-28T11:49:23+00:00" }, + { + "name": "nette/neon", + "version": "v2.4.3", + "source": { + "type": "git", + "url": "https://github.com/nette/neon.git", + "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/neon/zipball/5e72b1dd3e2d34f0863c5561139a19df6a1ef398", + "reference": "5e72b1dd3e2d34f0863c5561139a19df6a1ef398", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "ext-json": "*", + "php": ">=5.6.0" + }, + "require-dev": { + "nette/tester": "~2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "๐Ÿธ Nette NEON: encodes and decodes NEON file format.", + "homepage": "http://ne-on.org", + "keywords": [ + "export", + "import", + "neon", + "nette", + "yaml" + ], + "time": "2018-03-21T12:12:21+00:00" + }, + { + "name": "nette/php-generator", + "version": "v3.0.4", + "source": { + "type": "git", + "url": "https://github.com/nette/php-generator.git", + "reference": "b381ecacbf5a0b5f99cc0b303d5b0578d409f446" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/php-generator/zipball/b381ecacbf5a0b5f99cc0b303d5b0578d409f446", + "reference": "b381ecacbf5a0b5f99cc0b303d5b0578d409f446", + "shasum": "" + }, + "require": { + "nette/utils": "^2.4.2 || ~3.0.0", + "php": ">=7.0" + }, + "conflict": { + "nette/nette": "<2.2" + }, + "require-dev": { + "nette/tester": "^2.0", + "tracy/tracy": "^2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0", + "GPL-3.0" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "๐Ÿ˜ Nette PHP Generator: generates neat PHP code for you. Supports new PHP 7.2 features.", + "homepage": "https://nette.org", + "keywords": [ + "code", + "nette", + "php", + "scaffolding" + ], + "time": "2018-04-26T16:48:20+00:00" + }, { "name": "nette/robot-loader", "version": "v3.0.4", @@ -8863,6 +9131,57 @@ ], "time": "2018-05-02T17:16:08+00:00" }, + { + "name": "nikic/php-parser", + "version": "v4.0.3", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bd088dc940a418f09cda079a9b5c7c478890fb8d", + "reference": "bd088dc940a418f09cda079a9b5c7c478890fb8d", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.5 || ^7.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2018-07-15T17:25:16+00:00" + }, { "name": "php-cs-fixer/diff", "version": "v1.3.0", @@ -9354,41 +9673,181 @@ "time": "2018-06-20T17:48:01+00:00" }, { - "name": "phpstan/phpstan-shim", - "version": "0.9.2", + "name": "phpstan/phpstan", + "version": "0.10.2", "source": { "type": "git", - "url": "https://github.com/phpstan/phpstan-shim.git", - "reference": "e4720fb2916be05de02869780072253e7e0e8a75" + "url": "https://github.com/phpstan/phpstan.git", + "reference": "d69658794514e57ad9f247e623513397038f362f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-shim/zipball/e4720fb2916be05de02869780072253e7e0e8a75", - "reference": "e4720fb2916be05de02869780072253e7e0e8a75", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d69658794514e57ad9f247e623513397038f362f", + "reference": "d69658794514e57ad9f247e623513397038f362f", "shasum": "" }, "require": { - "php": "~7.0" - }, - "replace": { - "phpstan/phpstan": "self.version" + "composer/xdebug-handler": "^1.0", + "jean85/pretty-package-versions": "^1.0.3", + "nette/bootstrap": "^2.4 || ^3.0", + "nette/di": "^2.4.7 || ^3.0", + "nette/robot-loader": "^3.0.1", + "nette/utils": "^2.4.5 || ^3.0", + "nikic/php-parser": "^4.0.2", + "php": "~7.1", + "phpstan/phpdoc-parser": "^0.3", + "symfony/console": "~3.2 || ~4.0", + "symfony/finder": "~3.2 || ~4.0" + }, + "require-dev": { + "brianium/paratest": "^2.0", + "consistence/coding-standard": "^3.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "ext-gd": "*", + "ext-intl": "*", + "ext-mysqli": "*", + "ext-zip": "*", + "jakub-onderka/php-parallel-lint": "^1.0", + "localheinz/composer-normalize": "~0.8.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-deprecation-rules": "^0.10.2", + "phpstan/phpstan-php-parser": "^0.10", + "phpstan/phpstan-phpunit": "^0.10", + "phpstan/phpstan-strict-rules": "^0.10", + "phpunit/phpunit": "^7.0", + "slevomat/coding-standard": "^4.6.2" }, "bin": [ - "phpstan", - "phpstan.phar" + "bin/phpstan" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.10-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": [ + "src/", + "build/PHPStan" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "time": "2018-07-22T17:55:11+00:00" + }, + { + "name": "phpstan/phpstan-symfony", + "version": "0.10", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-symfony.git", + "reference": "34b1940a678768ba1b957ca550f99bf7c81f6222" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-symfony/zipball/34b1940a678768ba1b957ca550f99bf7c81f6222", + "reference": "34b1940a678768ba1b957ca550f99bf7c81f6222", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "nikic/php-parser": "^4.0", + "php": "^7.1", + "phpstan/phpstan": "^0.10" + }, + "conflict": { + "symfony/framework-bundle": "<3.0" + }, + "require-dev": { + "consistence/coding-standard": "^3.0.1", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "jakub-onderka/php-parallel-lint": "^1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-phpunit": "^0.10", + "phpstan/phpstan-strict-rules": "^0.10", + "phpunit/phpunit": "^7.0", + "satooshi/php-coveralls": "^1.0", + "slevomat/coding-standard": "^4.5.2", + "symfony/framework-bundle": "^3.0 || ^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.10-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lukรกลก Unger", + "email": "looky.msc@gmail.com", + "homepage": "https://lookyman.net" + } ], + "description": "Symfony Framework extensions and rules for PHPStan", + "time": "2018-06-21T12:00:50+00:00" + }, + { + "name": "phpstan/phpstan-webmozart-assert", + "version": "0.10", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-webmozart-assert.git", + "reference": "5954bb88827ae8e4b45ee5db4f430c1ced69818a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-webmozart-assert/zipball/5954bb88827ae8e4b45ee5db4f430c1ced69818a", + "reference": "5954bb88827ae8e4b45ee5db4f430c1ced69818a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.0", + "php": "~7.1", + "phpstan/phpstan": "^0.10" + }, + "require-dev": { + "consistence/coding-standard": "^3.0.1", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.4", + "jakub-onderka/php-parallel-lint": "^1.0", + "phing/phing": "^2.16.0", + "phpstan/phpstan-phpunit": "^0.10", + "phpstan/phpstan-strict-rules": "^0.10", + "phpunit/phpunit": "^7.1.3", + "slevomat/coding-standard": "^4.5.2", + "webmozart/assert": "^1.3.0" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "0.9-dev" + "dev-master": "0.10-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "PHPStan Phar distribution", - "time": "2018-01-28T14:29:27+00:00" + "description": "PHPStan webmozart/assert extension", + "time": "2018-06-23T17:24:59+00:00" }, { "name": "phpunit/php-code-coverage", diff --git a/phpstan.neon b/phpstan.neon index 1cbc5e8d..a933d7a7 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,11 @@ +includes: + - vendor/phpstan/phpstan-symfony/extension.neon + - vendor/phpstan/phpstan-webmozart-assert/extension.neon + parameters: + symfony: + container_xml_path: tests/Application/var/cache/dev/appDevDebugProjectContainer.xml + excludes_analyse: # Makes PHPStan crash - 'src/DependencyInjection/Configuration.php' diff --git a/tests/Application/app/AppKernel.php b/tests/Application/app/AppKernel.php index b84745b3..2846ca67 100644 --- a/tests/Application/app/AppKernel.php +++ b/tests/Application/app/AppKernel.php @@ -30,20 +30,4 @@ public function registerContainerConfiguration(LoaderInterface $loader): void { $loader->load($this->getRootDir() . '/config/config.yml'); } - - /** - * {@inheritdoc} - */ - public function getCacheDir(): string - { - return sprintf('%s/%s/cache', sys_get_temp_dir(), md5(__DIR__)); - } - - /** - * {@inheritdoc} - */ - public function getLogDir(): string - { - return sprintf('%s/%s/logs', sys_get_temp_dir(), md5(__DIR__)); - } } From 3b6d76a30d17dd8ed3fba724bd7fe8b63d75750a Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 13:00:04 +0200 Subject: [PATCH 04/14] Check whether file contents could be loaded before JSON decoding it --- src/Importer/JsonResourceImporter.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Importer/JsonResourceImporter.php b/src/Importer/JsonResourceImporter.php index b12a185f..79a5dd0a 100644 --- a/src/Importer/JsonResourceImporter.php +++ b/src/Importer/JsonResourceImporter.php @@ -5,6 +5,7 @@ namespace FriendsOfSylius\SyliusImportExportPlugin\Importer; use Doctrine\Common\Persistence\ObjectManager; +use FriendsOfSylius\SyliusImportExportPlugin\Exception\ImporterException; use FriendsOfSylius\SyliusImportExportPlugin\Processor\ResourceProcessorInterface; final class JsonResourceImporter extends ResourceImporter implements SingleDataArrayImporterInterface @@ -32,9 +33,12 @@ public function import(string $fileName): ImporterResultInterface { $this->result->start(); - $dataAsArray = json_decode(file_get_contents($fileName), true); + $contents = file_get_contents($fileName); + if (false === $contents) { + throw new ImporterException(sprintf('File %s could not be loaded', $fileName)); + } - foreach ($dataAsArray as $i => $row) { + foreach (json_decode($contents, true) as $i => $row) { if ($this->importData($i, $row)) { break; } From ee59a7117b428db7db34555d2475fabdc497ba39 Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 13:04:30 +0200 Subject: [PATCH 05/14] Set batchCount default value on property --- src/Importer/ResourceImporter.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Importer/ResourceImporter.php b/src/Importer/ResourceImporter.php index 7f0c80f9..cad022e1 100644 --- a/src/Importer/ResourceImporter.php +++ b/src/Importer/ResourceImporter.php @@ -50,7 +50,7 @@ class ResourceImporter implements ImporterInterface /** * @var int */ - private $batchCount; + private $batchCount = 0; public function __construct( ReaderFactory $readerFactory, @@ -75,8 +75,7 @@ public function import(string $fileName): ImporterResultInterface $reader = $this->readerFactory->getReader(new \SplFileObject($fileName)); $this->result->start(); - - $this->batchCount = 0; + foreach ($reader as $i => $row) { if ($this->importData($i, $row)) { break; From 97c25d829431d2068b7e684009f8519514e508de Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 14:11:10 +0200 Subject: [PATCH 06/14] Throw exception if stream could not be read --- src/Importer/ResourceImporter.php | 2 +- src/Writer/CsvWriter.php | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Importer/ResourceImporter.php b/src/Importer/ResourceImporter.php index cad022e1..34398610 100644 --- a/src/Importer/ResourceImporter.php +++ b/src/Importer/ResourceImporter.php @@ -75,7 +75,7 @@ public function import(string $fileName): ImporterResultInterface $reader = $this->readerFactory->getReader(new \SplFileObject($fileName)); $this->result->start(); - + foreach ($reader as $i => $row) { if ($this->importData($i, $row)) { break; diff --git a/src/Writer/CsvWriter.php b/src/Writer/CsvWriter.php index ceab46ab..6e58b447 100644 --- a/src/Writer/CsvWriter.php +++ b/src/Writer/CsvWriter.php @@ -4,6 +4,7 @@ namespace FriendsOfSylius\SyliusImportExportPlugin\Writer; +use FriendsOfSylius\SyliusImportExportPlugin\Exception\ExporterException; use Port\Csv\CsvWriter as PortCsvWriter; class CsvWriter implements WriterInterface @@ -42,6 +43,9 @@ public function getFileContent(): string rewind($this->writer->getStream()); $contents = stream_get_contents($this->writer->getStream()); + if (false === $contents) { + throw new ExporterException(sprintf('Data stream could not be opened')); + } $this->finish(); From 5a782af8c2c1e951cf0dcfdfa14ca0c14b6854d4 Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 15:01:20 +0200 Subject: [PATCH 07/14] First header is returned by default, which is already a string --- src/Controller/ImportDataController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Controller/ImportDataController.php b/src/Controller/ImportDataController.php index cbc317ca..89608adb 100644 --- a/src/Controller/ImportDataController.php +++ b/src/Controller/ImportDataController.php @@ -79,7 +79,7 @@ public function importAction(Request $request): RedirectResponse if ($form->isSubmitted() && $form->isValid()) { $this->importData($importer, $form); } - $referer = (string) $request->headers->get('referer'); + $referer = $request->headers->get('referer'); return new RedirectResponse($referer); } From 9c8c9121bee40bb8c1252ba89a0c9c1e0746bef1 Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 15:04:48 +0200 Subject: [PATCH 08/14] Throw Exception if uploaded file is not available --- src/Controller/ImportDataController.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Controller/ImportDataController.php b/src/Controller/ImportDataController.php index 89608adb..36ef6cc1 100644 --- a/src/Controller/ImportDataController.php +++ b/src/Controller/ImportDataController.php @@ -4,6 +4,7 @@ namespace FriendsOfSylius\SyliusImportExportPlugin\Controller; +use FriendsOfSylius\SyliusImportExportPlugin\Exception\ImporterException; use FriendsOfSylius\SyliusImportExportPlugin\Form\ImportType; use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImporterInterface; use FriendsOfSylius\SyliusImportExportPlugin\Importer\ImporterRegistry; @@ -102,7 +103,11 @@ private function importData(string $importer, FormInterface $form): void $file = $form->get('import-data')->getData(); /** @var ImporterInterface $service */ $service = $this->registry->get($name); - $result = $service->import($file->getRealPath()); + $path = $file->getRealPath(); + if (false === $path) { + throw new ImporterException(sprintf('File %s could not be loaded', $file->getClientOriginalName())); + } + $result = $service->import($path); $message = sprintf( 'Imported via %s importer (Time taken in ms: %s, Imported %s, Skipped %s, Failed %s)', From d76aa636421de4e0293be003297e5395a3d113db Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 15:07:58 +0200 Subject: [PATCH 09/14] Always return string, also when JSON encode fails --- src/Exporter/JsonResourceExporter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Exporter/JsonResourceExporter.php b/src/Exporter/JsonResourceExporter.php index d9d5a554..7ecde63b 100644 --- a/src/Exporter/JsonResourceExporter.php +++ b/src/Exporter/JsonResourceExporter.php @@ -50,7 +50,7 @@ public function export(array $idsToExport): void */ public function getExportedData(): string { - return json_encode($this->data); + return json_encode($this->data) ?: ''; } /** From 7523e48956baed13fd52b61ce46449fee1c6ad82 Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 15:08:51 +0200 Subject: [PATCH 10/14] Make sure always a string is injected, also when JSON encode fails --- src/Exporter/MqItemWriter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Exporter/MqItemWriter.php b/src/Exporter/MqItemWriter.php index b2d815c0..2ce5e194 100644 --- a/src/Exporter/MqItemWriter.php +++ b/src/Exporter/MqItemWriter.php @@ -50,7 +50,7 @@ public function write(array $items): void { foreach ($items as $item) { $message = $this->redisContext->createMessage( - json_encode($item), + json_encode($item) ?: '', [], ['recordedOn' => (new \DateTime())->format('Y-m-d H:i:s')] ); From b6b86e4635705e26664d754878ca8f671e3b603d Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 15:10:24 +0200 Subject: [PATCH 11/14] Parameter #1 of method FriendsOfSylius\SyliusImportExportPlugin\Importer\ResourceImporter::importData() expects int, int|string given. --- src/Importer/ResourceImporter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Importer/ResourceImporter.php b/src/Importer/ResourceImporter.php index 34398610..89208207 100644 --- a/src/Importer/ResourceImporter.php +++ b/src/Importer/ResourceImporter.php @@ -77,7 +77,7 @@ public function import(string $fileName): ImporterResultInterface $this->result->start(); foreach ($reader as $i => $row) { - if ($this->importData($i, $row)) { + if ($this->importData((int)$i, $row)) { break; } } From 5ac9556259878e7aab3884175694fd46cd51e8f9 Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 15:12:26 +0200 Subject: [PATCH 12/14] Better checks on file existence and creation of temporary folder --- src/Writer/ExcelWriter.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/Writer/ExcelWriter.php b/src/Writer/ExcelWriter.php index dd121388..5a752c20 100644 --- a/src/Writer/ExcelWriter.php +++ b/src/Writer/ExcelWriter.php @@ -4,6 +4,7 @@ namespace FriendsOfSylius\SyliusImportExportPlugin\Writer; +use FriendsOfSylius\SyliusImportExportPlugin\Exception\ExporterException; use FriendsOfSylius\SyliusImportExportPlugin\Exception\InvalidOrderException; use Port\Excel\ExcelWriter as PortExcelWriter; @@ -59,6 +60,9 @@ public function getFileContent(): string $this->finish(); $contents = file_get_contents($this->filename); + if (false === $contents) { + throw new ExporterException(sprintf('File %s could not be loaded', $this->filename)); + } unlink($this->filename); @@ -68,7 +72,11 @@ public function getFileContent(): string private function prepare(): void { if (null === $this->filename) { - $this->filename = tempnam($this->temporaryFolder, 'exp'); + $tmp = tempnam($this->temporaryFolder, 'exp'); + if (false === $tmp) { + throw new ExporterException(sprintf('Could not create temporary file in "%s"', $this->temporaryFolder)); + } + $this->filename = $tmp; } if (null === $this->writer) { From 880e5fc46f36fbe78c759f88629e450a9c428d50 Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 15:15:11 +0200 Subject: [PATCH 13/14] Minor CS --- src/Importer/ResourceImporter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Importer/ResourceImporter.php b/src/Importer/ResourceImporter.php index 89208207..aab0bf64 100644 --- a/src/Importer/ResourceImporter.php +++ b/src/Importer/ResourceImporter.php @@ -77,7 +77,7 @@ public function import(string $fileName): ImporterResultInterface $this->result->start(); foreach ($reader as $i => $row) { - if ($this->importData((int)$i, $row)) { + if ($this->importData((int) $i, $row)) { break; } } From 909af92a03fa9cf9fb01c615b18d2134d5317e4b Mon Sep 17 00:00:00 2001 From: Stefan Doorn Date: Wed, 25 Jul 2018 15:21:50 +0200 Subject: [PATCH 14/14] Make sure there is a dev container loaded for PHPStan to use --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index dc1012b7..80452372 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,6 +32,7 @@ before_script: - (cd tests/Application && bin/console doctrine:database:create --env=test -vvv) - (cd tests/Application && bin/console doctrine:schema:create --env=test -vvv) - (cd tests/Application && bin/console assets:install web --env=test -vvv) + - (cd tests/Application && bin/console cache:warmup --env=dev -vvv) - (cd tests/Application && yarn run gulp) # Configure display @@ -68,7 +69,6 @@ script: - bin/phpstan analyse -c phpstan.neon -l max src/ - bin/ecs check src/ spec/ tests/Behat/ -# - bin/phpunit - bin/phpspec run - bin/behat features/ --strict -vvv --no-interaction || bin/behat features/ --strict -vvv --no-interaction --rerun