From 6c05e5ab48b5f08ad38a761a1067d647db057c22 Mon Sep 17 00:00:00 2001 From: ADmad Date: Sun, 28 Jul 2019 22:45:21 +0530 Subject: [PATCH 01/40] Update constraints and code for CakePHP 4.x. --- composer.json | 12 +++++------ src/Model/Behavior/UploadBehavior.php | 2 +- tests/Fixture/FilesFixture.php | 2 +- .../Transformer/DefaultTransformerTest.php | 7 +------ .../File/Transformer/SlugTransformerTest.php | 7 +------ .../File/Writer/DefaultWriterTest.php | 2 +- .../Model/Behavior/UploadBehaviorTest.php | 20 +++++++++---------- .../Validation/ImageValidationTest.php | 7 +------ .../Validation/UploadValidationTest.php | 7 +------ 9 files changed, 23 insertions(+), 43 deletions(-) diff --git a/composer.json b/composer.json index 2aecfd3b..12818455 100644 --- a/composer.json +++ b/composer.json @@ -12,15 +12,13 @@ } ], "require": { - "cakephp/orm": "^3.5", + "cakephp/cakephp": "4.x-dev", "league/flysystem": "*" }, "require-dev": { - "cakephp/cakephp": "^3.5", - "cakephp/chronos": "^1.1", - "phpunit/phpunit": "^5.7.14|^6.0", + "phpunit/phpunit": "^8.0", "league/flysystem-vfs": "*", - "cakephp/cakephp-codesniffer": "dev-master" + "cakephp/cakephp-codesniffer": "dev-next" }, "autoload": { "psr-4": { @@ -32,5 +30,7 @@ "psr-4": { "Josegonzalez\\Upload\\Test\\": "tests" } - } + }, + "minimum-stability": "dev", + "prefer-stable": true } diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 07bbbbce..b8d5264a 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -26,7 +26,7 @@ class UploadBehavior extends Behavior * @param array $config The config for this behavior. * @return void */ - public function initialize(array $config) + public function initialize(array $config): void { $configs = []; foreach ($config as $field => $settings) { diff --git a/tests/Fixture/FilesFixture.php b/tests/Fixture/FilesFixture.php index 68481378..535f0979 100644 --- a/tests/Fixture/FilesFixture.php +++ b/tests/Fixture/FilesFixture.php @@ -30,7 +30,7 @@ class FilesFixture extends TestFixture ['filename' => 'FileThree'], ]; - public function init() + public function init(): void { $created = $modified = date('Y-m-d H:i:s'); array_walk($this->records, function (&$record) use ($created, $modified) { diff --git a/tests/TestCase/File/Transformer/DefaultTransformerTest.php b/tests/TestCase/File/Transformer/DefaultTransformerTest.php index 684c1b24..5d34cb3e 100644 --- a/tests/TestCase/File/Transformer/DefaultTransformerTest.php +++ b/tests/TestCase/File/Transformer/DefaultTransformerTest.php @@ -9,7 +9,7 @@ class DefaultTransformerTest extends TestCase { - public function setup() + public function setUp(): void { $entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); @@ -19,11 +19,6 @@ public function setup() $this->transformer = new DefaultTransformer($table, $entity, $data, $field, $settings); } - public function teardown() - { - unset($this->transformer); - } - public function testIsProcessorInterface() { $this->assertInstanceOf('Josegonzalez\Upload\File\Transformer\TransformerInterface', $this->transformer); diff --git a/tests/TestCase/File/Transformer/SlugTransformerTest.php b/tests/TestCase/File/Transformer/SlugTransformerTest.php index 85e916ab..72eebd61 100644 --- a/tests/TestCase/File/Transformer/SlugTransformerTest.php +++ b/tests/TestCase/File/Transformer/SlugTransformerTest.php @@ -9,7 +9,7 @@ class SlugTransformerTest extends TestCase { - public function setup() + public function setUp(): void { $entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); @@ -19,11 +19,6 @@ public function setup() $this->transformer = new SlugTransformer($table, $entity, $data, $field, $settings); } - public function teardown() - { - unset($this->transformer); - } - public function testTransform() { $this->assertEquals(['path/to/file' => 'foo-e-a.txt'], $this->transformer->transform()); diff --git a/tests/TestCase/File/Writer/DefaultWriterTest.php b/tests/TestCase/File/Writer/DefaultWriterTest.php index 2273c6a1..209afd21 100644 --- a/tests/TestCase/File/Writer/DefaultWriterTest.php +++ b/tests/TestCase/File/Writer/DefaultWriterTest.php @@ -20,7 +20,7 @@ class DefaultWriterTest extends TestCase protected $field; protected $settings; - public function setup() + public function setUp(): void { $this->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $this->table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index d3f24fc0..4396013f 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -17,7 +17,7 @@ class UploadBehaviorTest extends TestCase 'plugin.Josegonzalez/Upload.Files', ]; - public function setup() + public function setUp(): void { $this->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $this->table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); @@ -59,9 +59,9 @@ public function setup() public function testInitialize() { $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); - $schema = $this->getMockBuilder('Cake\Database\Schema\Table') - ->setMethods([]) - ->setConstructorArgs([$table, []]) + $schema = $this->getMockBuilder('Cake\Database\Schema\TableSchema') + ->setMethods(['setColumnType', 'getSchema', 'setSchema']) + ->disableOriginalConstructor() ->getMock(); $schema->expects($this->once()) ->method('setColumnType') @@ -104,9 +104,9 @@ public function testInitializeIndexedConfig() { $settings = ['field']; $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); - $schema = $this->getMockBuilder('Cake\Database\Schema\Table') - ->setMethods([]) - ->setConstructorArgs([$table, []]) + $schema = $this->getMockBuilder('Cake\Database\Schema\TableSchema') + ->setMethods(['setColumnType', 'getSchema', 'setSchema']) + ->disableOriginalConstructor() ->getMock(); $schema->expects($this->once()) ->method('setColumnType') @@ -139,9 +139,9 @@ public function testInitializeAddBehaviorOptionsInterfaceConfig() 'field' => [] ]; $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); - $schema = $this->getMockBuilder('Cake\Database\Schema\Table') - ->setMethods([]) - ->setConstructorArgs([$table, []]) + $schema = $this->getMockBuilder('Cake\Database\Schema\TableSchema') + ->setMethods(['setColumnType', 'getSchema', 'setSchema']) + ->disableOriginalConstructor() ->getMock(); $schema->expects($this->once()) ->method('setColumnType') diff --git a/tests/TestCase/Validation/ImageValidationTest.php b/tests/TestCase/Validation/ImageValidationTest.php index 964ac8b4..907118c0 100644 --- a/tests/TestCase/Validation/ImageValidationTest.php +++ b/tests/TestCase/Validation/ImageValidationTest.php @@ -11,7 +11,7 @@ class ImageValidationTest extends TestCase private $data; private $vfs; - public function setup() + public function setUp(): void { parent::setUp(); @@ -32,11 +32,6 @@ public function setup() ]; } - public function teardown() - { - parent::tearDown(); - } - public function testIsAboveMinWidth() { $this->assertTrue(ImageValidation::isAboveMinWidth($this->data, 10)); diff --git a/tests/TestCase/Validation/UploadValidationTest.php b/tests/TestCase/Validation/UploadValidationTest.php index cfa0c627..6bae9cc4 100644 --- a/tests/TestCase/Validation/UploadValidationTest.php +++ b/tests/TestCase/Validation/UploadValidationTest.php @@ -9,7 +9,7 @@ class UploadValidationTest extends TestCase { private $data; - public function setup() + public function setUp(): void { parent::setUp(); $this->data = [ @@ -20,11 +20,6 @@ public function setup() ]; } - public function teardown() - { - parent::tearDown(); - } - public function testIsUnderPhpSizeLimit() { $this->assertTrue(UploadValidation::isUnderPhpSizeLimit($this->data + ['error' => UPLOAD_ERR_OK])); From e677fca034725fb3ea5afb7b6145f3b7eebb5c5d Mon Sep 17 00:00:00 2001 From: ADmad Date: Sun, 28 Jul 2019 22:46:04 +0530 Subject: [PATCH 02/40] Update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d1502b08..3d7e132f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ vendor/ composer.lock +.phpunit.result.cache From e9d0d67cb325c33465140e3ab360d0195222a56a Mon Sep 17 00:00:00 2001 From: ADmad Date: Sun, 28 Jul 2019 23:19:08 +0530 Subject: [PATCH 03/40] Fix CS errors. --- src/Database/Type/FileType.php | 2 + src/File/Path/Basepath/DefaultTrait.php | 19 +++++-- src/File/Path/DefaultProcessor.php | 3 +- src/File/Path/Filename/DefaultTrait.php | 2 + src/File/Path/ProcessorInterface.php | 2 + src/File/Transformer/DefaultTransformer.php | 3 +- src/File/Transformer/SlugTransformer.php | 3 +- src/File/Transformer/TransformerInterface.php | 2 + src/File/Writer/DefaultWriter.php | 8 ++- src/File/Writer/WriterInterface.php | 2 + src/Model/Behavior/UploadBehavior.php | 8 +-- src/Plugin.php | 1 + src/Validation/DefaultValidation.php | 1 + src/Validation/ImageValidation.php | 1 + .../Traits/ImageValidationTrait.php | 9 +-- .../Traits/UploadValidationTrait.php | 15 +---- src/Validation/UploadValidation.php | 1 + tests/Fixture/FilesFixture.php | 2 +- tests/Stub/ChildBehavior.php | 2 + tests/TestCase/Database/Type/FileTypeTest.php | 2 + .../File/Path/Basepath/DefaultTraitTest.php | 5 +- .../File/Path/DefaultProcessorTest.php | 3 +- .../File/Path/Filename/DefaultTraitTest.php | 3 +- .../Transformer/DefaultTransformerTest.php | 5 +- .../File/Transformer/SlugTransformerTest.php | 5 +- .../File/Writer/DefaultWriterTest.php | 35 ++++++------ .../Model/Behavior/UploadBehaviorTest.php | 57 ++++++++++--------- .../Validation/ImageValidationTest.php | 5 +- .../Validation/UploadValidationTest.php | 3 +- tests/bootstrap.php | 2 + 30 files changed, 120 insertions(+), 91 deletions(-) diff --git a/src/Database/Type/FileType.php b/src/Database/Type/FileType.php index 9d6e59a6..ce1517ba 100644 --- a/src/Database/Type/FileType.php +++ b/src/Database/Type/FileType.php @@ -1,4 +1,6 @@ entity->get($field); if ($value === null) { - throw new LogicException(sprintf('Field value for substitution is missing: %s', $field)); + throw new LogicException(sprintf( + 'Field value for substitution is missing: %s', + $field + )); } elseif (!is_scalar($value)) { - throw new LogicException(sprintf('Field value for substitution must be a integer, float, string or boolean: %s', $field)); + throw new LogicException(sprintf( + 'Field value for substitution must be a integer, float, string or boolean: %s', + $field + )); } elseif (strlen($value) < 1) { - throw new LogicException(sprintf('Field value for substitution must be non-zero in length: %s', $field)); + throw new LogicException(sprintf( + 'Field value for substitution must be non-zero in length: %s', + $field + )); } $replacements[sprintf('{field-value:%s}', $field)] = $value; diff --git a/src/File/Path/DefaultProcessor.php b/src/File/Path/DefaultProcessor.php index 7afe4df3..152272dd 100644 --- a/src/File/Path/DefaultProcessor.php +++ b/src/File/Path/DefaultProcessor.php @@ -1,11 +1,12 @@ AdapterInterface::VISIBILITY_PUBLIC + 'visibility' => AdapterInterface::VISIBILITY_PUBLIC, ])); } diff --git a/src/File/Writer/WriterInterface.php b/src/File/Writer/WriterInterface.php index 48ce243d..b093a9a0 100644 --- a/src/File/Writer/WriterInterface.php +++ b/src/File/Writer/WriterInterface.php @@ -1,4 +1,6 @@ 0 && $imgWidth >= $width; } @@ -35,7 +36,7 @@ public static function isBelowMaxWidth($check, $width) if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { return false; } - list($imgWidth) = getimagesize($check['tmp_name']); + [$imgWidth] = getimagesize($check['tmp_name']); return $width > 0 && $imgWidth <= $width; } @@ -53,7 +54,7 @@ public static function isAboveMinHeight($check, $height) if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { return false; } - list(, $imgHeight) = getimagesize($check['tmp_name']); + [, $imgHeight] = getimagesize($check['tmp_name']); return $height > 0 && $imgHeight >= $height; } @@ -71,7 +72,7 @@ public static function isBelowMaxHeight($check, $height) if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { return false; } - list(, $imgHeight) = getimagesize($check['tmp_name']); + [, $imgHeight] = getimagesize($check['tmp_name']); return $height > 0 && $imgHeight <= $height; } diff --git a/src/Validation/Traits/UploadValidationTrait.php b/src/Validation/Traits/UploadValidationTrait.php index 9dd48fd5..3f591258 100644 --- a/src/Validation/Traits/UploadValidationTrait.php +++ b/src/Validation/Traits/UploadValidationTrait.php @@ -1,4 +1,5 @@ = $size; + return !empty($check['size']) && $check['size'] >= $size; } /** @@ -89,11 +85,6 @@ public static function isAboveMinSize($check, $size) */ public static function isBelowMaxSize($check, $size) { - // Non-file uploads also mean the size is too small - if (!isset($check['size']) || !strlen($check['size'])) { - return false; - } - - return $check['size'] <= $size; + return !empty($check['size']) && $check['size'] <= $size; } } diff --git a/src/Validation/UploadValidation.php b/src/Validation/UploadValidation.php index a4408065..93da00d6 100644 --- a/src/Validation/UploadValidation.php +++ b/src/Validation/UploadValidation.php @@ -1,4 +1,5 @@ ['type' => 'integer'], 'filename' => ['type' => 'string'], 'created' => ['type' => 'datetime', 'null' => true], - '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]] + '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]], ]; /** diff --git a/tests/Stub/ChildBehavior.php b/tests/Stub/ChildBehavior.php index 18899051..2f4546bf 100644 --- a/tests/Stub/ChildBehavior.php +++ b/tests/Stub/ChildBehavior.php @@ -1,4 +1,6 @@ settings = [ 'filesystem' => [ 'adapter' => function () { - return new VfsAdapter(new Vfs); - } - ] + return new VfsAdapter(new Vfs()); + }, + ], ]; $this->writer = new DefaultWriter( $this->table, @@ -41,7 +40,7 @@ public function setUp(): void $this->settings ); - $this->vfs = new Vfs; + $this->vfs = new Vfs(); mkdir($this->vfs->path('/tmp')); file_put_contents($this->vfs->path('/tmp/tempfile'), 'content'); } @@ -55,11 +54,11 @@ public function testInvoke() { $this->assertEquals([], $this->writer->write([])); $this->assertEquals([true], $this->writer->write([ - $this->vfs->path('/tmp/tempfile') => 'file.txt' + $this->vfs->path('/tmp/tempfile') => 'file.txt', ], 'field', [])); $this->assertEquals([false], $this->writer->write([ - $this->vfs->path('/tmp/invalid.txt') => 'file.txt' + $this->vfs->path('/tmp/invalid.txt') => 'file.txt', ], 'field', [])); } @@ -76,11 +75,11 @@ public function testDelete() $this->assertEquals([], $writer->delete([])); $this->assertEquals([true], $writer->delete([ - $this->vfs->path('/tmp/tempfile') + $this->vfs->path('/tmp/tempfile'), ])); $this->assertEquals([false], $writer->delete([ - $this->vfs->path('/tmp/invalid.txt') + $this->vfs->path('/tmp/invalid.txt'), ])); } @@ -120,19 +119,19 @@ public function testGetFilesystem() { $this->assertInstanceOf('League\Flysystem\FilesystemInterface', $this->writer->getFilesystem('field', [])); $this->assertInstanceOf('League\Flysystem\FilesystemInterface', $this->writer->getFilesystem('field', [ - 'key' => 'value' + 'key' => 'value', ])); $this->assertInstanceOf('League\Flysystem\FilesystemInterface', $this->writer->getFilesystem('field', [ 'filesystem' => [ - 'adapter' => new NullAdapter - ] + 'adapter' => new NullAdapter(), + ], ])); $this->assertInstanceOf('League\Flysystem\FilesystemInterface', $this->writer->getFilesystem('field', [ 'filesystem' => [ 'adapter' => function () { - return new NullAdapter; + return new NullAdapter(); }, - ] + ], ])); } @@ -142,8 +141,8 @@ public function testGetFilesystemUnexpectedValueException() $this->writer->getFilesystem('field', [ 'filesystem' => [ - 'adapter' => 'invalid_adapter' - ] + 'adapter' => 'invalid_adapter', + ], ]); } } diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index 4396013f..dc31db09 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -1,10 +1,10 @@ 1, 'type' => 'text', 'keepFilesOnDelete' => false, - 'deleteCallback' => null - ] + 'deleteCallback' => null, + ], ]; $this->dataError = [ 'field' => [ @@ -39,7 +39,7 @@ public function setUp(): void 'error' => UPLOAD_ERR_NO_FILE, 'size' => 0, 'type' => '', - ] + ], ]; $this->field = 'field'; $this->settings = ['field' => []]; @@ -136,7 +136,7 @@ public function testInitializeAddBehaviorOptionsInterfaceConfig() { $settings = [ 'className' => 'Josegonzalez\Upload\Model\Behavior\UploadBehavior', - 'field' => [] + 'field' => [], ]; $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); $schema = $this->getMockBuilder('Cake\Database\Schema\TableSchema') @@ -191,7 +191,7 @@ public function testBeforeMarshalOk() ->will($this->returnValue($this->settings)); $data = new ArrayObject($this->dataOk); - $behavior->beforeMarshal(new Event('fake.event'), $data, new ArrayObject); + $behavior->beforeMarshal(new Event('fake.event'), $data, new ArrayObject()); $this->assertEquals(new ArrayObject($this->dataOk), $data); } @@ -217,8 +217,8 @@ public function testBeforeMarshalError() ->will($this->returnValue($this->settings)); $data = new ArrayObject($this->dataError); - $behavior->beforeMarshal(new Event('fake.event'), $data, new ArrayObject); - $this->assertEquals(new ArrayObject, $data); + $behavior->beforeMarshal(new Event('fake.event'), $data, new ArrayObject()); + $this->assertEquals(new ArrayObject(), $data); } public function testBeforeMarshalEmptyAllowed() @@ -243,7 +243,7 @@ public function testBeforeMarshalEmptyAllowed() ->will($this->returnValue($this->settings)); $data = new ArrayObject($this->dataError); - $behavior->beforeMarshal(new Event('fake.event'), $data, new ArrayObject); + $behavior->beforeMarshal(new Event('fake.event'), $data, new ArrayObject()); $this->assertEquals(new ArrayObject($this->dataError), $data); } @@ -275,7 +275,7 @@ public function testBeforeSaveUploadError() $this->entity->expects($this->once()) ->method('setDirty') ->with('field', false); - $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject)); + $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testBeforeSaveWriteFail() @@ -303,12 +303,12 @@ public function testBeforeSaveWriteFail() ->method('write') ->will($this->returnValue([false])); - $this->assertFalse($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject)); + $this->assertFalse($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testBeforeSaveOk() { - $methods = array_diff($this->behaviorMethods, ['beforeSave', 'config', 'setConfig', 'getConfig']); + $methods = array_diff($this->behaviorMethods, ['beforeSave', 'setConfig', 'getConfig']); $behavior = $this->getMockBuilder('Josegonzalez\Upload\Model\Behavior\UploadBehavior') ->setMethods($methods) ->setConstructorArgs([$this->table, $this->settings]) @@ -327,11 +327,14 @@ public function testBeforeSaveOk() $behavior->expects($this->any()) ->method('constructFiles') ->will($this->returnValue([])); + $this->processor->expects($this->any()) + ->method('filename') + ->will($this->returnValue('derp')); $this->writer->expects($this->any()) ->method('write') ->will($this->returnValue([true])); - $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject)); + $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testBeforeSaveDoesNotRestoreOriginalValue() @@ -348,7 +351,7 @@ public function testBeforeSaveDoesNotRestoreOriginalValue() $this->entity->expects($this->never())->method('getOriginal'); $this->entity->expects($this->never())->method('set'); - $behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject); + $behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject()); } public function testBeforeSaveWithProtectedFieldName() @@ -363,7 +366,7 @@ public function testBeforeSaveWithProtectedFieldName() ->getMock(); $behavior->setConfig($settings); - $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject)); + $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testAfterDeleteOk() @@ -385,7 +388,7 @@ public function testAfterDeleteOk() ->method('delete') ->will($this->returnValue([true])); - $this->assertTrue($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject)); + $this->assertTrue($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testAfterDeleteFail() @@ -407,7 +410,7 @@ public function testAfterDeleteFail() ->method('delete') ->will($this->returnValue([false])); - $this->assertFalse($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject)); + $this->assertFalse($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testAfterDeleteSkip() @@ -426,7 +429,7 @@ public function testAfterDeleteSkip() ->method('delete') ->will($this->returnValue([true])); - $this->assertTrue($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject)); + $this->assertTrue($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testAfterDeleteUsesPathProcessorToDetectPathToTheFile() @@ -474,7 +477,7 @@ public function testAfterDeleteUsesPathProcessorToDetectPathToTheFile() ->with([$dir . $field]) ->willReturn([true]); - $behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject); + $behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject()); } public function testAfterDeletePrefersStoredPathOverPathProcessor() @@ -513,7 +516,7 @@ public function testAfterDeletePrefersStoredPathOverPathProcessor() ->with([$dir . $field]) ->will($this->returnValue([true])); - $this->assertTrue($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject)); + $this->assertTrue($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testAfterDeleteNoDeleteCallback() @@ -540,11 +543,11 @@ public function testAfterDeleteNoDeleteCallback() $this->writer->expects($this->once()) ->method('delete') ->with([ - $path . $this->entity->field + $path . $this->entity->field, ]) ->willReturn([true, true, true]); - $behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject); + $behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject()); } public function testAfterDeleteUsesDeleteCallback() @@ -561,7 +564,7 @@ public function testAfterDeleteUsesDeleteCallback() return [ $path . $entity->{$field}, $path . 'sm-' . $entity->{$field}, - $path . 'lg-' . $entity->{$field} + $path . 'lg-' . $entity->{$field}, ]; }; @@ -579,11 +582,11 @@ public function testAfterDeleteUsesDeleteCallback() ->with([ $path . $this->entity->field, $path . 'sm-' . $this->entity->field, - $path . 'lg-' . $this->entity->field + $path . 'lg-' . $this->entity->field, ]) ->willReturn([true, true, true]); - $behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject); + $behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject()); } public function testAfterDeleteWithProtectedFieldName() @@ -604,7 +607,7 @@ public function testAfterDeleteWithProtectedFieldName() ->method('delete') ->will($this->returnValue([true])); - $this->assertTrue($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject)); + $this->assertTrue($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testGetWriter() diff --git a/tests/TestCase/Validation/ImageValidationTest.php b/tests/TestCase/Validation/ImageValidationTest.php index 907118c0..fe3615f4 100644 --- a/tests/TestCase/Validation/ImageValidationTest.php +++ b/tests/TestCase/Validation/ImageValidationTest.php @@ -1,4 +1,5 @@ vfs = new Vfs; + $this->vfs = new Vfs(); mkdir($this->vfs->path('/tmp')); // Write sample image with dimensions: 20x20 @@ -28,7 +29,7 @@ public function setUp(): void 'type' => 'text/plain', 'tmp_name' => $this->vfs->path('/tmp/tmpimage'), 'size' => 200, - 'error' => UPLOAD_ERR_OK + 'error' => UPLOAD_ERR_OK, ]; } diff --git a/tests/TestCase/Validation/UploadValidationTest.php b/tests/TestCase/Validation/UploadValidationTest.php index 6bae9cc4..2cd52f23 100644 --- a/tests/TestCase/Validation/UploadValidationTest.php +++ b/tests/TestCase/Validation/UploadValidationTest.php @@ -1,4 +1,5 @@ 'sample.txt', 'type' => 'text/plain', 'tmp_name' => '/tmp/tmpfile', - 'size' => 200 + 'size' => 200, ]; } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index b1532adc..443a4d2e 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,4 +1,6 @@ Date: Sun, 28 Jul 2019 23:19:30 +0530 Subject: [PATCH 04/40] Fix phpunit config --- phpunit.xml.dist | 1 - 1 file changed, 1 deletion(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 8dca33a0..a07d13d9 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,7 +2,6 @@ colors="true" processIsolation="false" stopOnFailure="false" - syntaxCheck="false" bootstrap="./tests/bootstrap.php" > From e01d48e125bc1f63975dcf95c11b9ae57087f63f Mon Sep 17 00:00:00 2001 From: ADmad Date: Mon, 29 Jul 2019 00:06:41 +0530 Subject: [PATCH 05/40] Add typehints. --- phpstan.neon | 2 +- src/Database/Type/FileType.php | 10 ++--- src/File/Path/Basepath/DefaultTrait.php | 2 +- src/File/Path/DefaultProcessor.php | 14 +++---- src/File/Path/Filename/DefaultTrait.php | 2 +- src/File/Path/ProcessorInterface.php | 8 ++-- src/File/Transformer/DefaultTransformer.php | 4 +- src/File/Transformer/SlugTransformer.php | 2 +- src/File/Transformer/TransformerInterface.php | 4 +- src/File/Writer/DefaultWriter.php | 12 +++--- src/File/Writer/WriterInterface.php | 6 +-- src/Model/Behavior/UploadBehavior.php | 41 ++++++++----------- .../Traits/ImageValidationTrait.php | 8 ++-- .../Traits/UploadValidationTrait.php | 14 +++---- .../File/Path/Filename/DefaultTraitTest.php | 8 ++-- .../Model/Behavior/UploadBehaviorTest.php | 12 ------ 16 files changed, 64 insertions(+), 85 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 94d8acda..155930db 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,4 +2,4 @@ parameters: level: 5 ignoreErrors: - '#Constant ROOT not found#' - - '#Parameter \#2 \$options of static method Cake\\Utility\\Text::slug\(\) expects array, string given#' + - '#Constant DS not found#' diff --git a/src/Database/Type/FileType.php b/src/Database/Type/FileType.php index ce1517ba..22092a94 100644 --- a/src/Database/Type/FileType.php +++ b/src/Database/Type/FileType.php @@ -3,10 +3,10 @@ namespace Josegonzalez\Upload\Database\Type; -use Cake\Database\Driver; -use Cake\Database\Type; +use Cake\Database\DriverInterface; +use Cake\Database\Type\BaseType; -class FileType extends Type +class FileType extends BaseType { /** * Marshalls flat data into PHP objects. @@ -25,7 +25,7 @@ public function marshal($value) /** * {@inheritDoc} */ - public function toDatabase($value, Driver $driver) + public function toDatabase($value, DriverInterface $driver) { return $value; } @@ -33,7 +33,7 @@ public function toDatabase($value, Driver $driver) /** * {@inheritDoc} */ - public function toPHP($value, Driver $driver) + public function toPHP($value, DriverInterface $driver) { return $value; } diff --git a/src/File/Path/Basepath/DefaultTrait.php b/src/File/Path/Basepath/DefaultTrait.php index 6ac07804..9c1e706a 100644 --- a/src/File/Path/Basepath/DefaultTrait.php +++ b/src/File/Path/Basepath/DefaultTrait.php @@ -16,7 +16,7 @@ trait DefaultTrait * @return string * @throws \LogicException if a replacement is not valid for the current dataset */ - public function basepath() + public function basepath(): string { $defaultPath = 'webroot{DS}files{DS}{model}{DS}{field}{DS}'; $path = Hash::get($this->settings, 'path', $defaultPath); diff --git a/src/File/Path/DefaultProcessor.php b/src/File/Path/DefaultProcessor.php index 152272dd..539d74fb 100644 --- a/src/File/Path/DefaultProcessor.php +++ b/src/File/Path/DefaultProcessor.php @@ -10,6 +10,9 @@ class DefaultProcessor implements ProcessorInterface { + use BasepathTrait; + use FilenameTrait; + /** * Table instance. * @@ -25,9 +28,9 @@ class DefaultProcessor implements ProcessorInterface protected $entity; /** - * Array of uploaded data for this field + * Array of uploaded data for this field or filename stored in db * - * @var array + * @var array|string */ protected $data; @@ -50,11 +53,11 @@ class DefaultProcessor implements ProcessorInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\ORM\Entity $entity the entity to construct a path for. - * @param array $data the data being submitted for a save + * @param array|string $data the data being submitted for a save or filename stored in db * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, $data, $field, $settings) + public function __construct(Table $table, Entity $entity, $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; @@ -62,7 +65,4 @@ public function __construct(Table $table, Entity $entity, $data, $field, $settin $this->field = $field; $this->settings = $settings; } - - use BasepathTrait; - use FilenameTrait; } diff --git a/src/File/Path/Filename/DefaultTrait.php b/src/File/Path/Filename/DefaultTrait.php index 033185c6..d463c1bd 100644 --- a/src/File/Path/Filename/DefaultTrait.php +++ b/src/File/Path/Filename/DefaultTrait.php @@ -14,7 +14,7 @@ trait DefaultTrait * * @return string */ - public function filename() + public function filename(): string { $processor = Hash::get($this->settings, 'nameCallback', null); if (is_callable($processor)) { diff --git a/src/File/Path/ProcessorInterface.php b/src/File/Path/ProcessorInterface.php index 7952e51d..fcf4f870 100644 --- a/src/File/Path/ProcessorInterface.php +++ b/src/File/Path/ProcessorInterface.php @@ -13,23 +13,23 @@ interface ProcessorInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\ORM\Entity $entity the entity to construct a path for. - * @param array $data the data being submitted for a save + * @param array|string $data the data being submitted for a save or filename stored in db * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, $data, $field, $settings); + public function __construct(Table $table, Entity $entity, $data, string $field, array $settings); /** * Returns the basepath for the current field/data combination * * @return string */ - public function basepath(); + public function basepath(): string; /** * Returns the filename for the current field/data combination * * @return string */ - public function filename(); + public function filename(): string; } diff --git a/src/File/Transformer/DefaultTransformer.php b/src/File/Transformer/DefaultTransformer.php index 7b51e422..d4f5879b 100644 --- a/src/File/Transformer/DefaultTransformer.php +++ b/src/File/Transformer/DefaultTransformer.php @@ -52,7 +52,7 @@ class DefaultTransformer implements TransformerInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, $data, $field, $settings) + public function __construct(Table $table, Entity $entity, array $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; @@ -73,7 +73,7 @@ public function __construct(Table $table, Entity $entity, $data, $field, $settin * * @return array key/value pairs of temp files mapping to their names */ - public function transform() + public function transform(): array { return [$this->data['tmp_name'] => $this->data['name']]; } diff --git a/src/File/Transformer/SlugTransformer.php b/src/File/Transformer/SlugTransformer.php index 19cdc647..dcfa1d48 100644 --- a/src/File/Transformer/SlugTransformer.php +++ b/src/File/Transformer/SlugTransformer.php @@ -23,7 +23,7 @@ class SlugTransformer extends DefaultTransformer * * @return array key/value pairs of temp files mapping to their names */ - public function transform() + public function transform(): array { $filename = pathinfo($this->data['name'], PATHINFO_FILENAME); $filename = Text::slug($filename, '-'); diff --git a/src/File/Transformer/TransformerInterface.php b/src/File/Transformer/TransformerInterface.php index 8af8030c..4dcb8400 100644 --- a/src/File/Transformer/TransformerInterface.php +++ b/src/File/Transformer/TransformerInterface.php @@ -17,7 +17,7 @@ interface TransformerInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, $data, $field, $settings); + public function __construct(Table $table, Entity $entity, array $data, string $field, array $settings); /** * Creates a set of files from the initial data and returns them as key/value @@ -31,5 +31,5 @@ public function __construct(Table $table, Entity $entity, $data, $field, $settin * * @return array key/value pairs of temp files mapping to their names */ - public function transform(); + public function transform(): array; } diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index e06dbcd7..2737e3b0 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -59,7 +59,7 @@ class DefaultWriter implements WriterInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, $data, $field, $settings) + public function __construct(Table $table, Entity $entity, array $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; @@ -74,7 +74,7 @@ public function __construct(Table $table, Entity $entity, $data, $field, $settin * @param array $files the files being written out * @return array array of results */ - public function write(array $files) + public function write(array $files): array { $filesystem = $this->getFilesystem($this->field, $this->settings); $results = []; @@ -91,7 +91,7 @@ public function write(array $files) * @param array $files the files being written out * @return array array of results */ - public function delete(array $files) + public function delete(array $files): array { $filesystem = $this->getFilesystem($this->field, $this->settings); $results = []; @@ -110,7 +110,7 @@ public function delete(array $files) * @param string $path that path to which the file should be written * @return bool */ - public function writeFile(FilesystemInterface $filesystem, $file, $path) + public function writeFile(FilesystemInterface $filesystem, $file, $path): bool { // phpcs:ignore $stream = @fopen($file, 'r'); @@ -138,7 +138,7 @@ public function writeFile(FilesystemInterface $filesystem, $file, $path) * @param string $path the path that should be deleted * @return bool */ - public function deletePath(FilesystemInterface $filesystem, $path) + public function deletePath(FilesystemInterface $filesystem, string $path): bool { $success = false; try { @@ -157,7 +157,7 @@ public function deletePath(FilesystemInterface $filesystem, $path) * @param array $settings the settings for the current field * @return \League\Flysystem\FilesystemInterface */ - public function getFilesystem($field, array $settings = []) + public function getFilesystem(string $field, array $settings = []): FilesystemInterface { $adapter = new Local(Hash::get($settings, 'filesystem.root', ROOT . DS)); $adapter = Hash::get($settings, 'filesystem.adapter', $adapter); diff --git a/src/File/Writer/WriterInterface.php b/src/File/Writer/WriterInterface.php index b093a9a0..4f9fc706 100644 --- a/src/File/Writer/WriterInterface.php +++ b/src/File/Writer/WriterInterface.php @@ -17,7 +17,7 @@ interface WriterInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, $data, $field, $settings); + public function __construct(Table $table, Entity $entity, array $data, string $field, array $settings); /** * Writes a set of files to an output @@ -25,7 +25,7 @@ public function __construct(Table $table, Entity $entity, $data, $field, $settin * @param array $files the files being written out * @return array array of results */ - public function write(array $files); + public function write(array $files): array; /** * Deletes a set of files to an output @@ -33,5 +33,5 @@ public function write(array $files); * @param array $files the files being written out * @return array array of results */ - public function delete(array $files); + public function delete(array $files): array; } diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 8a37af2e..1a3a7e2f 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -10,6 +10,12 @@ use Cake\ORM\Behavior; use Cake\ORM\Entity; use Cake\Utility\Hash; +use Josegonzalez\Upload\File\Path\DefaultProcessor; +use Josegonzalez\Upload\File\Path\ProcessorInterface; +use Josegonzalez\Upload\File\Transformer\DefaultTransformer; +use Josegonzalez\Upload\File\Transformer\TransformerInterface; +use Josegonzalez\Upload\File\Writer\DefaultWriter; +use Josegonzalez\Upload\File\Writer\WriterInterface; use UnexpectedValueException; class UploadBehavior extends Behavior @@ -162,23 +168,16 @@ public function afterDelete(Event $event, Entity $entity, ArrayObject $options) * for a given file upload * * @param \Cake\ORM\Entity $entity an entity - * @param array $data the data being submitted for a save + * @param array|string $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Path\ProcessorInterface */ - public function getPathProcessor(Entity $entity, $data, $field, $settings) + public function getPathProcessor(Entity $entity, $data, string $field, array $settings): ProcessorInterface { - $default = 'Josegonzalez\Upload\File\Path\DefaultProcessor'; - $processorClass = Hash::get($settings, 'pathProcessor', $default); - if (is_subclass_of($processorClass, 'Josegonzalez\Upload\File\Path\ProcessorInterface')) { - return new $processorClass($this->_table, $entity, $data, $field, $settings); - } + $processorClass = Hash::get($settings, 'pathProcessor', DefaultProcessor::class); - throw new UnexpectedValueException(sprintf( - "'pathProcessor' not set to instance of ProcessorInterface: %s", - $processorClass - )); + return new $processorClass($this->_table, $entity, $data, $field, $settings); } /** @@ -190,18 +189,11 @@ public function getPathProcessor(Entity $entity, $data, $field, $settings) * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Writer\WriterInterface */ - public function getWriter(Entity $entity, $data, $field, $settings) + public function getWriter(Entity $entity, array $data, string $field, array $settings): WriterInterface { - $default = 'Josegonzalez\Upload\File\Writer\DefaultWriter'; - $writerClass = Hash::get($settings, 'writer', $default); - if (is_subclass_of($writerClass, 'Josegonzalez\Upload\File\Writer\WriterInterface')) { - return new $writerClass($this->_table, $entity, $data, $field, $settings); - } + $writerClass = Hash::get($settings, 'writer', DefaultWriter::class); - throw new UnexpectedValueException(sprintf( - "'writer' not set to instance of WriterInterface: %s", - $writerClass - )); + return new $writerClass($this->_table, $entity, $data, $field, $settings); } /** @@ -226,13 +218,12 @@ public function getWriter(Entity $entity, $data, $field, $settings) * @param string $basepath a basepath where the files are written to * @return array key/value pairs of temp files mapping to their names */ - public function constructFiles(Entity $entity, $data, $field, $settings, $basepath) + public function constructFiles(Entity $entity, array $data, string $field, array $settings, string $basepath): array { $basepath = substr($basepath, -1) == DS ? $basepath : $basepath . DS; - $default = 'Josegonzalez\Upload\File\Transformer\DefaultTransformer'; - $transformerClass = Hash::get($settings, 'transformer', $default); + $transformerClass = Hash::get($settings, 'transformer', DefaultTransformer::class); $results = []; - if (is_subclass_of($transformerClass, 'Josegonzalez\Upload\File\Transformer\TransformerInterface')) { + if (is_subclass_of($transformerClass, TransformerInterface::class)) { $transformer = new $transformerClass($this->_table, $entity, $data, $field, $settings); $results = $transformer->transform(); foreach ($results as $key => $value) { diff --git a/src/Validation/Traits/ImageValidationTrait.php b/src/Validation/Traits/ImageValidationTrait.php index ee0a69fc..10de9b48 100644 --- a/src/Validation/Traits/ImageValidationTrait.php +++ b/src/Validation/Traits/ImageValidationTrait.php @@ -12,7 +12,7 @@ trait ImageValidationTrait * @param int $width Width of Image * @return bool Success */ - public static function isAboveMinWidth($check, $width) + public static function isAboveMinWidth($check, int $width): bool { // Non-file uploads also mean the height is too big if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { @@ -30,7 +30,7 @@ public static function isAboveMinWidth($check, $width) * @param int $width Width of Image * @return bool Success */ - public static function isBelowMaxWidth($check, $width) + public static function isBelowMaxWidth($check, int $width): bool { // Non-file uploads also mean the height is too big if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { @@ -48,7 +48,7 @@ public static function isBelowMaxWidth($check, $width) * @param int $height Height of Image * @return bool Success */ - public static function isAboveMinHeight($check, $height) + public static function isAboveMinHeight($check, int $height): bool { // Non-file uploads also mean the height is too big if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { @@ -66,7 +66,7 @@ public static function isAboveMinHeight($check, $height) * @param int $height Height of Image * @return bool Success */ - public static function isBelowMaxHeight($check, $height) + public static function isBelowMaxHeight($check, int $height): bool { // Non-file uploads also mean the height is too big if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { diff --git a/src/Validation/Traits/UploadValidationTrait.php b/src/Validation/Traits/UploadValidationTrait.php index 3f591258..bc8287de 100644 --- a/src/Validation/Traits/UploadValidationTrait.php +++ b/src/Validation/Traits/UploadValidationTrait.php @@ -14,7 +14,7 @@ trait UploadValidationTrait * @param mixed $check Value to check * @return bool Success */ - public static function isUnderPhpSizeLimit($check) + public static function isUnderPhpSizeLimit($check): bool { return Hash::get($check, 'error') !== UPLOAD_ERR_INI_SIZE; } @@ -26,7 +26,7 @@ public static function isUnderPhpSizeLimit($check) * @param mixed $check Value to check * @return bool Success */ - public static function isUnderFormSizeLimit($check) + public static function isUnderFormSizeLimit($check): bool { return Hash::get($check, 'error') !== UPLOAD_ERR_FORM_SIZE; } @@ -37,7 +37,7 @@ public static function isUnderFormSizeLimit($check) * @param mixed $check Value to check * @return bool Success */ - public static function isCompletedUpload($check) + public static function isCompletedUpload($check): bool { return Hash::get($check, 'error') !== UPLOAD_ERR_PARTIAL; } @@ -48,7 +48,7 @@ public static function isCompletedUpload($check) * @param mixed $check Value to check * @return bool Success */ - public static function isFileUpload($check) + public static function isFileUpload($check): bool { return Hash::get($check, 'error') !== UPLOAD_ERR_NO_FILE; } @@ -59,7 +59,7 @@ public static function isFileUpload($check) * @param mixed $check Value to check * @return bool Success */ - public static function isSuccessfulWrite($check) + public static function isSuccessfulWrite($check): bool { return Hash::get($check, 'error') !== UPLOAD_ERR_CANT_WRITE; } @@ -71,7 +71,7 @@ public static function isSuccessfulWrite($check) * @param int $size Minimum file size * @return bool Success */ - public static function isAboveMinSize($check, $size) + public static function isAboveMinSize($check, $size): bool { return !empty($check['size']) && $check['size'] >= $size; } @@ -83,7 +83,7 @@ public static function isAboveMinSize($check, $size) * @param int $size Maximum file size * @return bool Success */ - public static function isBelowMaxSize($check, $size) + public static function isBelowMaxSize($check, $size): bool { return !empty($check['size']) && $check['size'] <= $size; } diff --git a/tests/TestCase/File/Path/Filename/DefaultTraitTest.php b/tests/TestCase/File/Path/Filename/DefaultTraitTest.php index d9e3bc3d..00cf1898 100644 --- a/tests/TestCase/File/Path/Filename/DefaultTraitTest.php +++ b/tests/TestCase/File/Path/Filename/DefaultTraitTest.php @@ -26,11 +26,11 @@ public function testFilename() $mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait'); $mock->settings = [ 'nameCallback' => function ($data, $settings) { - return $data; + return $data['name']; }, ]; $mock->data = ['name' => 'filename']; - $this->assertEquals(['name' => 'filename'], $mock->filename()); + $this->assertEquals('filename', $mock->filename()); $mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait'); $mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); @@ -38,10 +38,10 @@ public function testFilename() $mock->field = 'field'; $mock->settings = [ 'nameCallback' => function ($table, $entity, $data, $field, $settings) { - return $data; + return $data['name']; }, ]; $mock->data = ['name' => 'filename']; - $this->assertEquals(['name' => 'filename'], $mock->filename()); + $this->assertEquals('filename', $mock->filename()); } } diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index dc31db09..5b052c3f 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -616,12 +616,6 @@ public function testGetWriter() $this->assertInstanceOf('Josegonzalez\Upload\File\Writer\WriterInterface', $processor); } - public function testGetWriterException() - { - $this->expectException('UnexpectedValueException', "'writer' not set to instance of WriterInterface: UnexpectedValueException"); - $this->behavior->getWriter($this->entity, [], 'field', ['writer' => 'UnexpectedValueException']); - } - public function testConstructFiles() { $files = $this->behavior->constructFiles( @@ -711,10 +705,4 @@ public function testGetPathProcessor() $processor = $this->behavior->getPathProcessor($this->entity, [], 'field', []); $this->assertInstanceOf('Josegonzalez\Upload\File\Path\ProcessorInterface', $processor); } - - public function testGetPathProcessorException() - { - $this->expectException('UnexpectedValueException', "'pathProcessor' not set to instance of ProcessorInterface: UnexpectedValueException"); - $this->behavior->getPathProcessor($this->entity, [], 'field', ['pathProcessor' => 'UnexpectedValueException']); - } } From 98d8a30a6c38879737be5de9cef2c4f622c7f5a3 Mon Sep 17 00:00:00 2001 From: ADmad Date: Mon, 29 Jul 2019 00:09:56 +0530 Subject: [PATCH 06/40] Set 'upload.file' db type mapping in plugin's bootstrap. --- src/Model/Behavior/UploadBehavior.php | 2 -- src/Plugin.php | 9 ++++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 1a3a7e2f..059ca1bf 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -5,7 +5,6 @@ use ArrayObject; use Cake\Collection\Collection; -use Cake\Database\Type; use Cake\Event\Event; use Cake\ORM\Behavior; use Cake\ORM\Entity; @@ -44,7 +43,6 @@ public function initialize(array $config): void $this->setConfig($configs); $this->setConfig('className', null); - Type::map('upload.file', 'Josegonzalez\Upload\Database\Type\FileType'); $schema = $this->_table->getSchema(); foreach (array_keys($this->getConfig()) as $field) { $schema->setColumnType($field, 'upload.file'); diff --git a/src/Plugin.php b/src/Plugin.php index 06fe8555..6958b896 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -4,10 +4,17 @@ namespace Josegonzalez\Upload; use Cake\Core\BasePlugin; +use Cake\Core\PluginApplicationInterface; +use Cake\Database\TypeFactory; +use Josegonzalez\Upload\Database\Type\FileType; /** - * Plugin class for CakePHP 3.6.0 plugin collection. + * Plugin class. */ class Plugin extends BasePlugin { + public function bootstrap(PluginApplicationInterface $app): void + { + TypeFactory::map('upload.file', FileType::class); + } } From d0075782d1f6d4e536a87ae80b5b913877866cde Mon Sep 17 00:00:00 2001 From: ADmad Date: Mon, 29 Jul 2019 00:14:29 +0530 Subject: [PATCH 07/40] Typehint using interface instead of concrete class. --- src/File/Path/DefaultProcessor.php | 8 ++--- src/File/Path/ProcessorInterface.php | 6 ++-- src/File/Transformer/DefaultTransformer.php | 8 ++--- src/File/Transformer/TransformerInterface.php | 6 ++-- src/File/Writer/DefaultWriter.php | 8 ++--- src/File/Writer/WriterInterface.php | 6 ++-- src/Model/Behavior/UploadBehavior.php | 32 +++++++++---------- 7 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/File/Path/DefaultProcessor.php b/src/File/Path/DefaultProcessor.php index 539d74fb..339165cd 100644 --- a/src/File/Path/DefaultProcessor.php +++ b/src/File/Path/DefaultProcessor.php @@ -3,7 +3,7 @@ namespace Josegonzalez\Upload\File\Path; -use Cake\ORM\Entity; +use Cake\Datasource\EntityInterface; use Cake\ORM\Table; use Josegonzalez\Upload\File\Path\Basepath\DefaultTrait as BasepathTrait; use Josegonzalez\Upload\File\Path\Filename\DefaultTrait as FilenameTrait; @@ -23,7 +23,7 @@ class DefaultProcessor implements ProcessorInterface /** * Entity instance. * - * @var \Cake\ORM\Entity + * @var \Cake\Datasource\EntityInterface */ protected $entity; @@ -52,12 +52,12 @@ class DefaultProcessor implements ProcessorInterface * Constructor * * @param \Cake\ORM\Table $table the instance managing the entity - * @param \Cake\ORM\Entity $entity the entity to construct a path for. + * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. * @param array|string $data the data being submitted for a save or filename stored in db * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Path/ProcessorInterface.php b/src/File/Path/ProcessorInterface.php index fcf4f870..65d59451 100644 --- a/src/File/Path/ProcessorInterface.php +++ b/src/File/Path/ProcessorInterface.php @@ -3,7 +3,7 @@ namespace Josegonzalez\Upload\File\Path; -use Cake\ORM\Entity; +use Cake\Datasource\EntityInterface; use Cake\ORM\Table; interface ProcessorInterface @@ -12,12 +12,12 @@ interface ProcessorInterface * Constructor * * @param \Cake\ORM\Table $table the instance managing the entity - * @param \Cake\ORM\Entity $entity the entity to construct a path for. + * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. * @param array|string $data the data being submitted for a save or filename stored in db * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, $data, string $field, array $settings); /** * Returns the basepath for the current field/data combination diff --git a/src/File/Transformer/DefaultTransformer.php b/src/File/Transformer/DefaultTransformer.php index d4f5879b..2503bba9 100644 --- a/src/File/Transformer/DefaultTransformer.php +++ b/src/File/Transformer/DefaultTransformer.php @@ -3,7 +3,7 @@ namespace Josegonzalez\Upload\File\Transformer; -use Cake\ORM\Entity; +use Cake\Datasource\EntityInterface; use Cake\ORM\Table; class DefaultTransformer implements TransformerInterface @@ -18,7 +18,7 @@ class DefaultTransformer implements TransformerInterface /** * Entity instance. * - * @var \Cake\ORM\Entity + * @var \Cake\Datasource\EntityInterface */ protected $entity; @@ -47,12 +47,12 @@ class DefaultTransformer implements TransformerInterface * Constructor * * @param \Cake\ORM\Table $table the instance managing the entity - * @param \Cake\ORM\Entity $entity the entity to construct a path for. + * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. * @param array $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, array $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, array $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Transformer/TransformerInterface.php b/src/File/Transformer/TransformerInterface.php index 4dcb8400..a1112db4 100644 --- a/src/File/Transformer/TransformerInterface.php +++ b/src/File/Transformer/TransformerInterface.php @@ -3,7 +3,7 @@ namespace Josegonzalez\Upload\File\Transformer; -use Cake\ORM\Entity; +use Cake\Datasource\EntityInterface; use Cake\ORM\Table; interface TransformerInterface @@ -12,12 +12,12 @@ interface TransformerInterface * Constructor. * * @param \Cake\ORM\Table $table the instance managing the entity - * @param \Cake\ORM\Entity $entity the entity to construct a path for. + * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. * @param array $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, array $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, array $data, string $field, array $settings); /** * Creates a set of files from the initial data and returns them as key/value diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index 2737e3b0..b3a30afc 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -3,7 +3,7 @@ namespace Josegonzalez\Upload\File\Writer; -use Cake\ORM\Entity; +use Cake\Datasource\EntityInterface; use Cake\ORM\Table; use Cake\Utility\Hash; use League\Flysystem\Adapter\Local; @@ -25,7 +25,7 @@ class DefaultWriter implements WriterInterface /** * Entity instance. * - * @var \Cake\ORM\Entity + * @var \Cake\Datasource\EntityInterface */ protected $entity; @@ -54,12 +54,12 @@ class DefaultWriter implements WriterInterface * Constructs a writer * * @param \Cake\ORM\Table $table the instance managing the entity - * @param \Cake\ORM\Entity $entity the entity to construct a path for. + * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. * @param array $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, array $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, array $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Writer/WriterInterface.php b/src/File/Writer/WriterInterface.php index 4f9fc706..842feb07 100644 --- a/src/File/Writer/WriterInterface.php +++ b/src/File/Writer/WriterInterface.php @@ -3,7 +3,7 @@ namespace Josegonzalez\Upload\File\Writer; -use Cake\ORM\Entity; +use Cake\Datasource\EntityInterface; use Cake\ORM\Table; interface WriterInterface @@ -12,12 +12,12 @@ interface WriterInterface * Constructor. * * @param \Cake\ORM\Table $table the instance managing the entity - * @param \Cake\ORM\Entity $entity the entity to construct a path for. + * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. * @param array $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, Entity $entity, array $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, array $data, string $field, array $settings); /** * Writes a set of files to an output diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 059ca1bf..c404fa52 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -5,9 +5,9 @@ use ArrayObject; use Cake\Collection\Collection; -use Cake\Event\Event; +use Cake\Datasource\EntityInterface; +use Cake\Event\EventInterface; use Cake\ORM\Behavior; -use Cake\ORM\Entity; use Cake\Utility\Hash; use Josegonzalez\Upload\File\Path\DefaultProcessor; use Josegonzalez\Upload\File\Path\ProcessorInterface; @@ -53,12 +53,12 @@ public function initialize(array $config): void /** * Modifies the data being marshalled to ensure invalid upload data is not inserted * - * @param \Cake\Event\Event $event an event instance + * @param \Cake\Event\EventInterface $event an event instance * @param \ArrayObject $data data being marshalled * @param \ArrayObject $options options for the current event * @return void */ - public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $options) + public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObject $options) { $validator = $this->_table->getValidator(); $dataArray = $data->getArrayCopy(); @@ -77,12 +77,12 @@ public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $opti * Modifies the entity before it is saved so that uploaded file data is persisted * in the database too. * - * @param \Cake\Event\Event $event The beforeSave event that was fired - * @param \Cake\ORM\Entity $entity The entity that is going to be saved + * @param \Cake\Event\EventInterface $event The beforeSave event that was fired + * @param \Cake\Datasource\EntityInterface $entity The entity that is going to be saved * @param \ArrayObject $options the options passed to the save method * @return void|false */ - public function beforeSave(Event $event, Entity $entity, ArrayObject $options) + public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) { foreach ($this->getConfig(null, []) as $field => $settings) { if (in_array($field, $this->protectedFieldNames)) { @@ -122,12 +122,12 @@ public function beforeSave(Event $event, Entity $entity, ArrayObject $options) /** * Deletes the files after the entity is deleted * - * @param \Cake\Event\Event $event The afterDelete event that was fired - * @param \Cake\ORM\Entity $entity The entity that was deleted + * @param \Cake\Event\EventInterface $event The afterDelete event that was fired + * @param \Cake\Datasource\EntityInterface $entity The entity that was deleted * @param \ArrayObject $options the options passed to the delete method * @return bool */ - public function afterDelete(Event $event, Entity $entity, ArrayObject $options) + public function afterDelete(EventInterface $event, EntityInterface $entity, ArrayObject $options) { $result = true; @@ -165,13 +165,13 @@ public function afterDelete(Event $event, Entity $entity, ArrayObject $options) * Retrieves an instance of a path processor which knows how to build paths * for a given file upload * - * @param \Cake\ORM\Entity $entity an entity + * @param \Cake\Datasource\EntityInterface $entity an entity * @param array|string $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Path\ProcessorInterface */ - public function getPathProcessor(Entity $entity, $data, string $field, array $settings): ProcessorInterface + public function getPathProcessor(EntityInterface $entity, $data, string $field, array $settings): ProcessorInterface { $processorClass = Hash::get($settings, 'pathProcessor', DefaultProcessor::class); @@ -181,13 +181,13 @@ public function getPathProcessor(Entity $entity, $data, string $field, array $se /** * Retrieves an instance of a file writer which knows how to write files to disk * - * @param \Cake\ORM\Entity $entity an entity + * @param \Cake\Datasource\EntityInterface $entity an entity * @param array $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Writer\WriterInterface */ - public function getWriter(Entity $entity, array $data, string $field, array $settings): WriterInterface + public function getWriter(EntityInterface $entity, array $data, string $field, array $settings): WriterInterface { $writerClass = Hash::get($settings, 'writer', DefaultWriter::class); @@ -209,14 +209,14 @@ public function getWriter(Entity $entity, array $data, string $field, array $set * used to construct this key/value array. This processor can be used to * create the source files. * - * @param \Cake\ORM\Entity $entity an entity + * @param \Cake\Datasource\EntityInterface $entity an entity * @param array $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @param string $basepath a basepath where the files are written to * @return array key/value pairs of temp files mapping to their names */ - public function constructFiles(Entity $entity, array $data, string $field, array $settings, string $basepath): array + public function constructFiles(EntityInterface $entity, array $data, string $field, array $settings, string $basepath): array { $basepath = substr($basepath, -1) == DS ? $basepath : $basepath . DS; $transformerClass = Hash::get($settings, 'transformer', DefaultTransformer::class); From 8601f0b4caa3d354cd8bf37a5d6bcafc056aac59 Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 25 Dec 2019 00:42:04 +0530 Subject: [PATCH 08/40] Update dependency constraints --- composer.json | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 12818455..7f49c3de 100644 --- a/composer.json +++ b/composer.json @@ -12,13 +12,13 @@ } ], "require": { - "cakephp/cakephp": "4.x-dev", + "cakephp/cakephp": "^4.0", "league/flysystem": "*" }, "require-dev": { - "phpunit/phpunit": "^8.0", + "phpunit/phpunit": "~8.5.0", "league/flysystem-vfs": "*", - "cakephp/cakephp-codesniffer": "dev-next" + "cakephp/cakephp-codesniffer": "^4.0" }, "autoload": { "psr-4": { @@ -30,7 +30,5 @@ "psr-4": { "Josegonzalez\\Upload\\Test\\": "tests" } - }, - "minimum-stability": "dev", - "prefer-stable": true + } } From d353f8e4bfc83da7f18bec5433ca60e8bba33b6d Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 25 Dec 2019 00:46:32 +0530 Subject: [PATCH 09/40] Update phpstan config --- phpstan.neon | 20 +++++++++++++++++--- src/Model/Behavior/UploadBehavior.php | 5 +++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 155930db..120aee6e 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,19 @@ parameters: - level: 5 + level: 6 + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false ignoreErrors: - - '#Constant ROOT not found#' - - '#Constant DS not found#' + - + message: "#^Constant ROOT not found\\.$#" + count: 1 + path: src/File/Writer/DefaultWriter.php + + - + message: "#^Method Josegonzalez\\\\Upload\\\\Model\\\\Behavior\\\\UploadBehavior\\:\\:beforeSave\\(\\) should return void\\|false but return statement is missing\\.$#" + count: 1 + path: src/Model/Behavior/UploadBehavior.php + + - + message: "#^Cannot instantiate interface Josegonzalez\\\\Upload\\\\File\\\\Transformer\\\\TransformerInterface\\.$#" + count: 1 + path: src/Model/Behavior/UploadBehavior.php diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index c404fa52..ada6b68c 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -19,6 +19,11 @@ class UploadBehavior extends Behavior { + /** + * Protected file names + * + * @var array + */ private $protectedFieldNames = [ 'priority', ]; From ce262ef50e091bf119bb33777aff09790d46bc40 Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 25 Dec 2019 00:48:37 +0530 Subject: [PATCH 10/40] Update travis config --- .travis.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 85bc5bc1..cb8d6ac3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,13 @@ language: php php: - - 5.6 - - 7.1 - 7.2 - 7.3 + - 7.4 + +services: + - mysql + - postgresql env: matrix: @@ -19,13 +22,13 @@ matrix: fast_finish: true include: - - php: 7.3 + - php: 7.2 env: PHPCS=1 DEFAULT=0 - - php: 7.3 + - php: 7.2 env: STATIC_ANALYSIS=1 DEFAULT=0 - - php: 5.6 + - php: 7.2 env: PREFER_LOWEST=1 before_script: @@ -37,7 +40,7 @@ before_script: - if [[ $DB = 'mysql' ]]; then mysql -e 'CREATE DATABASE cakephp_test;'; fi - if [[ $DB = 'pgsql' ]]; then psql -c 'CREATE DATABASE cakephp_test;' -U postgres; fi - - if [[ $STATIC_ANALYSIS = 1 ]]; then composer require --dev phpstan/phpstan-shim:^0.11; fi + - if [[ $STATIC_ANALYSIS = 1 ]]; then composer require --dev phpstan/phpstan:^0.12; fi script: - | @@ -54,7 +57,7 @@ script: after_success: - | - if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.3 ]]; then + if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.2 ]]; then wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.1.0/php-coveralls.phar chmod +x php-coveralls.phar ./php-coveralls.phar From 50f044514b2aab7160e1c18b5aeb4cbd3ff9f612 Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 25 Dec 2019 00:53:32 +0530 Subject: [PATCH 11/40] Fix CS error --- src/Model/Behavior/UploadBehavior.php | 9 +++++++-- src/Plugin.php | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index ada6b68c..eae32538 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -221,8 +221,13 @@ public function getWriter(EntityInterface $entity, array $data, string $field, a * @param string $basepath a basepath where the files are written to * @return array key/value pairs of temp files mapping to their names */ - public function constructFiles(EntityInterface $entity, array $data, string $field, array $settings, string $basepath): array - { + public function constructFiles( + EntityInterface $entity, + array $data, + string $field, + array $settings, + string $basepath + ): array { $basepath = substr($basepath, -1) == DS ? $basepath : $basepath . DS; $transformerClass = Hash::get($settings, 'transformer', DefaultTransformer::class); $results = []; diff --git a/src/Plugin.php b/src/Plugin.php index 6958b896..141eef7d 100644 --- a/src/Plugin.php +++ b/src/Plugin.php @@ -13,6 +13,12 @@ */ class Plugin extends BasePlugin { + /** + * Plugin bootstrap. + * + * @param \Cake\Core\PluginApplicationInterface $app Application instance. + * @return void + */ public function bootstrap(PluginApplicationInterface $app): void { TypeFactory::map('upload.file', FileType::class); From 1275d1603decdfbeb83bcd434ed19e9ddabcbcca Mon Sep 17 00:00:00 2001 From: Michael Carter Date: Sun, 10 Nov 2019 00:02:01 -0600 Subject: [PATCH 12/40] CakePHP 4 fixes related to uploads using UploadedFile class. --- src/File/Path/DefaultProcessor.php | 7 +++--- src/File/Path/Filename/DefaultTrait.php | 2 +- src/File/Path/ProcessorInterface.php | 5 ++-- src/File/Transformer/DefaultTransformer.php | 7 +++--- src/File/Transformer/TransformerInterface.php | 5 ++-- src/File/Writer/DefaultWriter.php | 5 ++-- src/File/Writer/WriterInterface.php | 5 ++-- src/Model/Behavior/UploadBehavior.php | 24 +++++++++---------- 8 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/File/Path/DefaultProcessor.php b/src/File/Path/DefaultProcessor.php index 339165cd..ba3dc433 100644 --- a/src/File/Path/DefaultProcessor.php +++ b/src/File/Path/DefaultProcessor.php @@ -7,6 +7,7 @@ use Cake\ORM\Table; use Josegonzalez\Upload\File\Path\Basepath\DefaultTrait as BasepathTrait; use Josegonzalez\Upload\File\Path\Filename\DefaultTrait as FilenameTrait; +use Zend\Diactoros\UploadedFile; class DefaultProcessor implements ProcessorInterface { @@ -28,9 +29,9 @@ class DefaultProcessor implements ProcessorInterface protected $entity; /** - * Array of uploaded data for this field or filename stored in db + * Instance of \Zend\Diactoros\UploadedFile conaining the meta info from the file. * - * @var array|string + * @var \Zend\Diactoros\UploadedFile */ protected $data; @@ -57,7 +58,7 @@ class DefaultProcessor implements ProcessorInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Path/Filename/DefaultTrait.php b/src/File/Path/Filename/DefaultTrait.php index d463c1bd..b13b1dc5 100644 --- a/src/File/Path/Filename/DefaultTrait.php +++ b/src/File/Path/Filename/DefaultTrait.php @@ -26,6 +26,6 @@ public function filename(): string return $processor($this->table, $this->entity, $this->data, $this->field, $this->settings); } - return $this->data['name']; + return $this->data->getClientFilename(); } } diff --git a/src/File/Path/ProcessorInterface.php b/src/File/Path/ProcessorInterface.php index 65d59451..31f19b13 100644 --- a/src/File/Path/ProcessorInterface.php +++ b/src/File/Path/ProcessorInterface.php @@ -5,6 +5,7 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\Table; +use Zend\Diactoros\UploadedFile; interface ProcessorInterface { @@ -13,11 +14,11 @@ interface ProcessorInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param array|string $data the data being submitted for a save or filename stored in db + * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save or filename stored in db * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings); /** * Returns the basepath for the current field/data combination diff --git a/src/File/Transformer/DefaultTransformer.php b/src/File/Transformer/DefaultTransformer.php index 2503bba9..ddbb947c 100644 --- a/src/File/Transformer/DefaultTransformer.php +++ b/src/File/Transformer/DefaultTransformer.php @@ -5,6 +5,7 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\Table; +use Zend\Diactoros\UploadedFile; class DefaultTransformer implements TransformerInterface { @@ -48,11 +49,11 @@ class DefaultTransformer implements TransformerInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param array $data the data being submitted for a save + * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, array $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; @@ -75,6 +76,6 @@ public function __construct(Table $table, EntityInterface $entity, array $data, */ public function transform(): array { - return [$this->data['tmp_name'] => $this->data['name']]; + return [$this->data->getStream()->getMetadata('uri') => $this->data->getClientFileName()]; } } diff --git a/src/File/Transformer/TransformerInterface.php b/src/File/Transformer/TransformerInterface.php index a1112db4..425f95c5 100644 --- a/src/File/Transformer/TransformerInterface.php +++ b/src/File/Transformer/TransformerInterface.php @@ -5,6 +5,7 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\Table; +use Zend\Diactoros\UploadedFile; interface TransformerInterface { @@ -13,11 +14,11 @@ interface TransformerInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param array $data the data being submitted for a save + * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, array $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings); /** * Creates a set of files from the initial data and returns them as key/value diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index b3a30afc..d0cb916c 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -12,6 +12,7 @@ use League\Flysystem\Filesystem; use League\Flysystem\FilesystemInterface; use UnexpectedValueException; +use Zend\Diactoros\UploadedFile; class DefaultWriter implements WriterInterface { @@ -55,11 +56,11 @@ class DefaultWriter implements WriterInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param array $data the data being submitted for a save + * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, array $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Writer/WriterInterface.php b/src/File/Writer/WriterInterface.php index 842feb07..08d743be 100644 --- a/src/File/Writer/WriterInterface.php +++ b/src/File/Writer/WriterInterface.php @@ -5,6 +5,7 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\Table; +use Zend\Diactoros\UploadedFile; interface WriterInterface { @@ -13,11 +14,11 @@ interface WriterInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param array $data the data being submitted for a save + * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, array $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings); /** * Writes a set of files to an output diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index eae32538..129c0e0f 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -16,6 +16,7 @@ use Josegonzalez\Upload\File\Writer\DefaultWriter; use Josegonzalez\Upload\File\Writer\WriterInterface; use UnexpectedValueException; +use Zend\Diactoros\UploadedFile; class UploadBehavior extends Behavior { @@ -94,7 +95,7 @@ public function beforeSave(EventInterface $event, EntityInterface $entity, Array continue; } - if (Hash::get((array)$entity->get($field), 'error') !== UPLOAD_ERR_OK) { + if ($entity->get($field)->getError() !== UPLOAD_ERR_OK) { if (Hash::get($settings, 'restoreValueOnFailure', true)) { $entity->set($field, $entity->getOriginal($field)); $entity->setDirty($field, false); @@ -106,21 +107,20 @@ public function beforeSave(EventInterface $event, EntityInterface $entity, Array $path = $this->getPathProcessor($entity, $data, $field, $settings); $basepath = $path->basepath(); $filename = $path->filename(); - $data['name'] = $filename; + $files = $this->constructFiles($entity, $data, $field, $settings, $basepath); $writer = $this->getWriter($entity, $data, $field, $settings); $success = $writer->write($files); - if ((new Collection($success))->contains(false)) { return false; } $entity->set($field, $filename); $entity->set(Hash::get($settings, 'fields.dir', 'dir'), $basepath); - $entity->set(Hash::get($settings, 'fields.size', 'size'), $data['size']); - $entity->set(Hash::get($settings, 'fields.type', 'type'), $data['type']); - $entity->set(Hash::get($settings, 'fields.ext', 'ext'), pathinfo($data['name'], PATHINFO_EXTENSION)); + $entity->set(Hash::get($settings, 'fields.size', 'size'), $data->getSize()); + $entity->set(Hash::get($settings, 'fields.type', 'type'), $data->getClientMediaType()); + $entity->set(Hash::get($settings, 'fields.ext', 'ext'), pathinfo($filename, PATHINFO_EXTENSION)); } } @@ -171,12 +171,12 @@ public function afterDelete(EventInterface $event, EntityInterface $entity, Arra * for a given file upload * * @param \Cake\Datasource\EntityInterface $entity an entity - * @param array|string $data the data being submitted for a save + * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Path\ProcessorInterface */ - public function getPathProcessor(EntityInterface $entity, $data, string $field, array $settings): ProcessorInterface + public function getPathProcessor(EntityInterface $entity, UploadedFile $data, string $field, array $settings): ProcessorInterface { $processorClass = Hash::get($settings, 'pathProcessor', DefaultProcessor::class); @@ -187,12 +187,12 @@ public function getPathProcessor(EntityInterface $entity, $data, string $field, * Retrieves an instance of a file writer which knows how to write files to disk * * @param \Cake\Datasource\EntityInterface $entity an entity - * @param array $data the data being submitted for a save + * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Writer\WriterInterface */ - public function getWriter(EntityInterface $entity, array $data, string $field, array $settings): WriterInterface + public function getWriter(EntityInterface $entity, UploadedFile $data, string $field, array $settings): WriterInterface { $writerClass = Hash::get($settings, 'writer', DefaultWriter::class); @@ -215,7 +215,7 @@ public function getWriter(EntityInterface $entity, array $data, string $field, a * create the source files. * * @param \Cake\Datasource\EntityInterface $entity an entity - * @param array $data the data being submitted for a save + * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @param string $basepath a basepath where the files are written to @@ -223,7 +223,7 @@ public function getWriter(EntityInterface $entity, array $data, string $field, a */ public function constructFiles( EntityInterface $entity, - array $data, + UploadedFile $data, string $field, array $settings, string $basepath From 33eb5db677d5ae62080a6a96371c3eea2118efb7 Mon Sep 17 00:00:00 2001 From: Michael Carter Date: Sun, 10 Nov 2019 16:58:19 -0600 Subject: [PATCH 13/40] Typehint against interface not class. --- src/File/Path/DefaultProcessor.php | 8 ++++---- src/File/Path/ProcessorInterface.php | 6 +++--- src/File/Transformer/DefaultTransformer.php | 6 +++--- src/File/Transformer/TransformerInterface.php | 6 +++--- src/File/Writer/DefaultWriter.php | 6 +++--- src/File/Writer/WriterInterface.php | 6 +++--- src/Model/Behavior/UploadBehavior.php | 14 +++++++------- 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/File/Path/DefaultProcessor.php b/src/File/Path/DefaultProcessor.php index ba3dc433..593c4a96 100644 --- a/src/File/Path/DefaultProcessor.php +++ b/src/File/Path/DefaultProcessor.php @@ -7,7 +7,7 @@ use Cake\ORM\Table; use Josegonzalez\Upload\File\Path\Basepath\DefaultTrait as BasepathTrait; use Josegonzalez\Upload\File\Path\Filename\DefaultTrait as FilenameTrait; -use Zend\Diactoros\UploadedFile; +use Psr\Http\Message\UploadedFileInterface; class DefaultProcessor implements ProcessorInterface { @@ -29,9 +29,9 @@ class DefaultProcessor implements ProcessorInterface protected $entity; /** - * Instance of \Zend\Diactoros\UploadedFile conaining the meta info from the file. + * Instance of \Psr\Http\Message\UploadedFileInterface conaining the meta info from the file. * - * @var \Zend\Diactoros\UploadedFile + * @var \Psr\Http\Message\UploadedFileInterface */ protected $data; @@ -58,7 +58,7 @@ class DefaultProcessor implements ProcessorInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Path/ProcessorInterface.php b/src/File/Path/ProcessorInterface.php index 31f19b13..4b122029 100644 --- a/src/File/Path/ProcessorInterface.php +++ b/src/File/Path/ProcessorInterface.php @@ -5,7 +5,7 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\Table; -use Zend\Diactoros\UploadedFile; +use Psr\Http\Message\UploadedFileInterface; interface ProcessorInterface { @@ -14,11 +14,11 @@ interface ProcessorInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save or filename stored in db + * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save or filename stored in db * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings); /** * Returns the basepath for the current field/data combination diff --git a/src/File/Transformer/DefaultTransformer.php b/src/File/Transformer/DefaultTransformer.php index ddbb947c..239ff6bc 100644 --- a/src/File/Transformer/DefaultTransformer.php +++ b/src/File/Transformer/DefaultTransformer.php @@ -5,7 +5,7 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\Table; -use Zend\Diactoros\UploadedFile; +use Psr\Http\Message\UploadedFileInterface; class DefaultTransformer implements TransformerInterface { @@ -49,11 +49,11 @@ class DefaultTransformer implements TransformerInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Transformer/TransformerInterface.php b/src/File/Transformer/TransformerInterface.php index 425f95c5..ea5dc232 100644 --- a/src/File/Transformer/TransformerInterface.php +++ b/src/File/Transformer/TransformerInterface.php @@ -5,7 +5,7 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\Table; -use Zend\Diactoros\UploadedFile; +use Psr\Http\Message\UploadedFileInterface; interface TransformerInterface { @@ -14,11 +14,11 @@ interface TransformerInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings); /** * Creates a set of files from the initial data and returns them as key/value diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index d0cb916c..e8f8b64d 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -12,7 +12,7 @@ use League\Flysystem\Filesystem; use League\Flysystem\FilesystemInterface; use UnexpectedValueException; -use Zend\Diactoros\UploadedFile; +use Psr\Http\Message\UploadedFileInterface; class DefaultWriter implements WriterInterface { @@ -56,11 +56,11 @@ class DefaultWriter implements WriterInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Writer/WriterInterface.php b/src/File/Writer/WriterInterface.php index 08d743be..a358e776 100644 --- a/src/File/Writer/WriterInterface.php +++ b/src/File/Writer/WriterInterface.php @@ -5,7 +5,7 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\Table; -use Zend\Diactoros\UploadedFile; +use Psr\Http\Message\UploadedFileInterface; interface WriterInterface { @@ -14,11 +14,11 @@ interface WriterInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFile $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings); /** * Writes a set of files to an output diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 129c0e0f..9d70a589 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -16,7 +16,7 @@ use Josegonzalez\Upload\File\Writer\DefaultWriter; use Josegonzalez\Upload\File\Writer\WriterInterface; use UnexpectedValueException; -use Zend\Diactoros\UploadedFile; +use Psr\Http\Message\UploadedFileInterface; class UploadBehavior extends Behavior { @@ -171,12 +171,12 @@ public function afterDelete(EventInterface $event, EntityInterface $entity, Arra * for a given file upload * * @param \Cake\Datasource\EntityInterface $entity an entity - * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Path\ProcessorInterface */ - public function getPathProcessor(EntityInterface $entity, UploadedFile $data, string $field, array $settings): ProcessorInterface + public function getPathProcessor(EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings): ProcessorInterface { $processorClass = Hash::get($settings, 'pathProcessor', DefaultProcessor::class); @@ -187,12 +187,12 @@ public function getPathProcessor(EntityInterface $entity, UploadedFile $data, st * Retrieves an instance of a file writer which knows how to write files to disk * * @param \Cake\Datasource\EntityInterface $entity an entity - * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Writer\WriterInterface */ - public function getWriter(EntityInterface $entity, UploadedFile $data, string $field, array $settings): WriterInterface + public function getWriter(EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings): WriterInterface { $writerClass = Hash::get($settings, 'writer', DefaultWriter::class); @@ -215,7 +215,7 @@ public function getWriter(EntityInterface $entity, UploadedFile $data, string $f * create the source files. * * @param \Cake\Datasource\EntityInterface $entity an entity - * @param \Zend\Diactoros\UploadedFile $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @param string $basepath a basepath where the files are written to @@ -223,7 +223,7 @@ public function getWriter(EntityInterface $entity, UploadedFile $data, string $f */ public function constructFiles( EntityInterface $entity, - UploadedFile $data, + UploadedFileInterface $data, string $field, array $settings, string $basepath From 3556c70bbe9e14dcc89063203cc25675dd0669df Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Mon, 27 Jan 2020 11:48:14 -0300 Subject: [PATCH 14/40] Fix some tests --- src/File/Transformer/SlugTransformer.php | 6 +- src/Model/Behavior/UploadBehavior.php | 10 +- .../File/Path/DefaultProcessorTest.php | 3 +- .../File/Path/Filename/DefaultTraitTest.php | 15 ++- .../Transformer/DefaultTransformerTest.php | 8 +- .../File/Transformer/SlugTransformerTest.php | 9 +- .../File/Writer/DefaultWriterTest.php | 3 +- .../Model/Behavior/UploadBehaviorTest.php | 100 ++++++++++-------- 8 files changed, 86 insertions(+), 68 deletions(-) diff --git a/src/File/Transformer/SlugTransformer.php b/src/File/Transformer/SlugTransformer.php index dcfa1d48..9f230994 100644 --- a/src/File/Transformer/SlugTransformer.php +++ b/src/File/Transformer/SlugTransformer.php @@ -25,14 +25,14 @@ class SlugTransformer extends DefaultTransformer */ public function transform(): array { - $filename = pathinfo($this->data['name'], PATHINFO_FILENAME); + $filename = pathinfo($this->data->getClientFilename(), PATHINFO_FILENAME); $filename = Text::slug($filename, '-'); - $ext = pathinfo($this->data['name'], PATHINFO_EXTENSION); + $ext = pathinfo($this->data->getClientFilename(), PATHINFO_EXTENSION); if (!empty($ext)) { $filename = $filename . '.' . $ext; } - return [$this->data['tmp_name'] => strtolower($filename)]; + return [$this->data->getStream()->getMetadata('uri') => strtolower($filename)]; } } diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 9d70a589..d07a74fe 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -15,6 +15,7 @@ use Josegonzalez\Upload\File\Transformer\TransformerInterface; use Josegonzalez\Upload\File\Writer\DefaultWriter; use Josegonzalez\Upload\File\Writer\WriterInterface; +use Laminas\Diactoros\UploadedFile; use UnexpectedValueException; use Psr\Http\Message\UploadedFileInterface; @@ -72,7 +73,8 @@ public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObj if (!$validator->isEmptyAllowed($field, false)) { continue; } - if (Hash::get($dataArray, $field . '.error') !== UPLOAD_ERR_NO_FILE) { + + if ($dataArray[$field]->getError() !== UPLOAD_ERR_NO_FILE) { continue; } unset($data[$field]); @@ -95,6 +97,10 @@ public function beforeSave(EventInterface $event, EntityInterface $entity, Array continue; } + if(empty($entity->get($field))) { + continue; + } + if ($entity->get($field)->getError() !== UPLOAD_ERR_OK) { if (Hash::get($settings, 'restoreValueOnFailure', true)) { $entity->set($field, $entity->getOriginal($field)); @@ -155,7 +161,7 @@ public function afterDelete(EventInterface $event, EntityInterface $entity, Arra $files = [$path . $entity->get($field)]; } - $writer = $this->getWriter($entity, [], $field, $settings); + $writer = $this->getWriter($entity, new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK), $field, $settings); $success = $writer->delete($files); if ($result && (new Collection($success))->contains(false)) { diff --git a/tests/TestCase/File/Path/DefaultProcessorTest.php b/tests/TestCase/File/Path/DefaultProcessorTest.php index e4c9c06e..21205a82 100644 --- a/tests/TestCase/File/Path/DefaultProcessorTest.php +++ b/tests/TestCase/File/Path/DefaultProcessorTest.php @@ -5,6 +5,7 @@ use Cake\TestSuite\TestCase; use Josegonzalez\Upload\File\Path\DefaultProcessor; +use Laminas\Diactoros\UploadedFile; class DefaultProcessorTest extends TestCase { @@ -12,7 +13,7 @@ public function testIsProcessorInterface() { $entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); - $data = ['name' => 'filename']; + $data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK); $field = 'field'; $settings = []; $processor = new DefaultProcessor($table, $entity, $data, $field, $settings); diff --git a/tests/TestCase/File/Path/Filename/DefaultTraitTest.php b/tests/TestCase/File/Path/Filename/DefaultTraitTest.php index 00cf1898..11071f1e 100644 --- a/tests/TestCase/File/Path/Filename/DefaultTraitTest.php +++ b/tests/TestCase/File/Path/Filename/DefaultTraitTest.php @@ -4,6 +4,7 @@ namespace Josegonzalez\Upload\Test\TestCase\File\Path\Filename; use Cake\TestSuite\TestCase; +use Laminas\Diactoros\UploadedFile; class DefaultTraitTest extends TestCase { @@ -11,25 +12,23 @@ public function testFilename() { $mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait'); $mock->settings = []; - $mock->data = [ - 'name' => 'filename', - ]; + $mock->data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'filename'); $this->assertEquals('filename', $mock->filename()); $mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait'); $mock->settings = [ 'nameCallback' => 'not_callable', ]; - $mock->data = ['name' => 'filename']; + $mock->data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'filename'); $this->assertEquals('filename', $mock->filename()); $mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait'); $mock->settings = [ 'nameCallback' => function ($data, $settings) { - return $data['name']; + return $data->getClientFilename(); }, ]; - $mock->data = ['name' => 'filename']; + $mock->data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'filename'); $this->assertEquals('filename', $mock->filename()); $mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait'); @@ -38,10 +37,10 @@ public function testFilename() $mock->field = 'field'; $mock->settings = [ 'nameCallback' => function ($table, $entity, $data, $field, $settings) { - return $data['name']; + return $data->getClientFilename(); }, ]; - $mock->data = ['name' => 'filename']; + $mock->data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'filename'); $this->assertEquals('filename', $mock->filename()); } } diff --git a/tests/TestCase/File/Transformer/DefaultTransformerTest.php b/tests/TestCase/File/Transformer/DefaultTransformerTest.php index 4c8d961c..18a68d94 100644 --- a/tests/TestCase/File/Transformer/DefaultTransformerTest.php +++ b/tests/TestCase/File/Transformer/DefaultTransformerTest.php @@ -5,6 +5,7 @@ use Cake\TestSuite\TestCase; use Josegonzalez\Upload\File\Transformer\DefaultTransformer; +use Laminas\Diactoros\UploadedFile; class DefaultTransformerTest extends TestCase { @@ -12,10 +13,11 @@ public function setUp(): void { $entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); - $data = ['tmp_name' => 'path/to/file', 'name' => 'foo.txt']; + $this->uploadedFile = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'foo.txt'); + $field = 'field'; $settings = []; - $this->transformer = new DefaultTransformer($table, $entity, $data, $field, $settings); + $this->transformer = new DefaultTransformer($table, $entity, $this->uploadedFile, $field, $settings); } public function testIsProcessorInterface() @@ -25,6 +27,6 @@ public function testIsProcessorInterface() public function testTransform() { - $this->assertEquals(['path/to/file' => 'foo.txt'], $this->transformer->transform()); + $this->assertEquals([$this->uploadedFile->getStream()->getMetadata('uri') => 'foo.txt'], $this->transformer->transform()); } } diff --git a/tests/TestCase/File/Transformer/SlugTransformerTest.php b/tests/TestCase/File/Transformer/SlugTransformerTest.php index c434964f..e73c0948 100644 --- a/tests/TestCase/File/Transformer/SlugTransformerTest.php +++ b/tests/TestCase/File/Transformer/SlugTransformerTest.php @@ -5,6 +5,7 @@ use Cake\TestSuite\TestCase; use Josegonzalez\Upload\File\Transformer\SlugTransformer; +use Laminas\Diactoros\UploadedFile; class SlugTransformerTest extends TestCase { @@ -12,7 +13,7 @@ public function setUp(): void { $entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); - $data = ['tmp_name' => 'path/to/file', 'name' => 'foo é À.TXT']; + $data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'foo é À.TXT'); $field = 'field'; $settings = []; $this->transformer = new SlugTransformer($table, $entity, $data, $field, $settings); @@ -20,15 +21,15 @@ public function setUp(): void public function testTransform() { - $this->assertEquals(['path/to/file' => 'foo-e-a.txt'], $this->transformer->transform()); + $this->assertEquals(['php://temp' => 'foo-e-a.txt'], $this->transformer->transform()); } public function testTransformWithNoFileExt() { $entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); - $data = ['tmp_name' => 'path/to/file', 'name' => 'foo é À']; + $data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'foo é À'); $transformer = new SlugTransformer($table, $entity, $data, 'field', []); - $this->assertEquals(['path/to/file' => 'foo-e-a'], $transformer->transform()); + $this->assertEquals(['php://temp' => 'foo-e-a'], $transformer->transform()); } } diff --git a/tests/TestCase/File/Writer/DefaultWriterTest.php b/tests/TestCase/File/Writer/DefaultWriterTest.php index 15f92904..6ce625db 100644 --- a/tests/TestCase/File/Writer/DefaultWriterTest.php +++ b/tests/TestCase/File/Writer/DefaultWriterTest.php @@ -5,6 +5,7 @@ use Cake\TestSuite\TestCase; use Josegonzalez\Upload\File\Writer\DefaultWriter; +use Laminas\Diactoros\UploadedFile; use League\Flysystem\Adapter\NullAdapter; use League\Flysystem\Vfs\VfsAdapter; use VirtualFileSystem\FileSystem as Vfs; @@ -23,7 +24,7 @@ public function setUp(): void { $this->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $this->table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); - $this->data = ['tmp_name' => 'path/to/file', 'name' => 'foo.txt']; + $this->data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'foo.txt'); $this->field = 'field'; $this->settings = [ 'filesystem' => [ diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index 5b052c3f..1159bc88 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -9,6 +9,7 @@ use Cake\TestSuite\TestCase; use Josegonzalez\Upload\Model\Behavior\UploadBehavior; use Josegonzalez\Upload\Test\Stub\ChildBehavior; +use Laminas\Diactoros\UploadedFile; use ReflectionClass; class UploadBehaviorTest extends TestCase @@ -22,24 +23,31 @@ public function setUp(): void $this->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $this->table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); $this->dataOk = [ + 'field' => new UploadedFile( + fopen('php://temp', 'wb+'), + 1, + UPLOAD_ERR_OK, + 'derp', + 'text/plain' + ) + ]; + + $this->configOk = [ 'field' => [ - 'tmp_name' => 'path/to/file', - 'name' => 'derp', - 'error' => UPLOAD_ERR_OK, - 'size' => 1, - 'type' => 'text', 'keepFilesOnDelete' => false, - 'deleteCallback' => null, - ], + 'deleteCallback' => null + ] ]; $this->dataError = [ - 'field' => [ - 'tmp_name' => 'path/to/file', - 'name' => 'derp', - 'error' => UPLOAD_ERR_NO_FILE, - 'size' => 0, - 'type' => '', - ], + 'field' => new UploadedFile( + fopen('php://temp', 'wb+'), + 0, + UPLOAD_ERR_NO_FILE, + 'derp' + ) + ]; + $this->configError = [ + 'field' => [] ]; $this->field = 'field'; $this->settings = ['field' => []]; @@ -47,11 +55,11 @@ public function setUp(): void $this->behavior = new UploadBehavior($this->table, []); $this->processor = $this->getMockBuilder('Josegonzalez\Upload\File\Path\DefaultProcessor') ->setMethods([]) - ->setConstructorArgs([$this->table, $this->entity, $this->dataOk, $this->field, $this->settings]) + ->setConstructorArgs([$this->table, $this->entity, $this->dataOk[$this->field], $this->field, $this->settings]) ->getMock(); $this->writer = $this->getMockBuilder('Josegonzalez\Upload\File\Writer\DefaultWriter') ->setMethods([]) - ->setConstructorArgs([$this->table, $this->entity, $this->dataOk, $this->field, $this->settings]) + ->setConstructorArgs([$this->table, $this->entity, $this->dataOk[$this->field], $this->field, $this->settings]) ->getMock(); $this->behaviorMethods = get_class_methods('Josegonzalez\Upload\Model\Behavior\UploadBehavior'); } @@ -376,7 +384,7 @@ public function testAfterDeleteOk() ->setMethods($methods) ->setConstructorArgs([$this->table, $this->dataOk]) ->getMock(); - $behavior->setConfig($this->dataOk); + $behavior->setConfig($this->configOk); $behavior->expects($this->any()) ->method('getPathProcessor') @@ -398,7 +406,7 @@ public function testAfterDeleteFail() ->setMethods($methods) ->setConstructorArgs([$this->table, $this->dataOk]) ->getMock(); - $behavior->setConfig($this->dataOk); + $behavior->setConfig($this->configOk); $behavior->expects($this->any()) ->method('getPathProcessor') @@ -420,7 +428,7 @@ public function testAfterDeleteSkip() ->setMethods($methods) ->setConstructorArgs([$this->table, $this->dataError]) ->getMock(); - $behavior->setConfig($this->dataError); + $behavior->setConfig($this->configError); $behavior->expects($this->any()) ->method('getWriter') @@ -442,7 +450,7 @@ public function testAfterDeleteUsesPathProcessorToDetectPathToTheFile() ->setMethods($methods) ->setConstructorArgs([$this->table, $this->dataOk]) ->getMock(); - $behavior->setConfig($this->dataOk); + $behavior->setConfig($this->configOk); $this->entity->expects($this->at(0)) ->method('has') @@ -490,7 +498,7 @@ public function testAfterDeletePrefersStoredPathOverPathProcessor() ->setMethods($methods) ->setConstructorArgs([$this->table, $this->dataOk]) ->getMock(); - $behavior->setConfig($this->dataOk); + $behavior->setConfig($this->configOk); $this->entity->expects($this->at(0)) ->method('has') @@ -529,16 +537,16 @@ public function testAfterDeleteNoDeleteCallback() ->setConstructorArgs([$this->table, $this->dataOk]) ->getMock(); - $this->dataOk['field']['deleteCallback'] = null; + $this->configOk['field']['deleteCallback'] = null; - $behavior->setConfig($this->dataOk); + $behavior->setConfig($this->configOk); $behavior->expects($this->once())->method('getPathProcessor') - ->with($this->entity, $this->entity->field, 'field', $this->dataOk['field']) + ->with($this->entity, $this->entity->field, 'field', $this->configOk['field']) ->willReturn($this->processor); $this->processor->expects($this->once())->method('basepath') ->willReturn($path); $behavior->expects($this->once())->method('getWriter') - ->with($this->entity, [], 'field', $this->dataOk['field']) + ->with($this->entity, [], 'field', $this->configOk['field']) ->willReturn($this->writer); $this->writer->expects($this->once()) ->method('delete') @@ -560,7 +568,7 @@ public function testAfterDeleteUsesDeleteCallback() ->setConstructorArgs([$this->table, $this->dataOk]) ->getMock(); - $this->dataOk['field']['deleteCallback'] = function ($path, $entity, $field, $settings) { + $this->configOk['field']['deleteCallback'] = function ($path, $entity, $field, $settings) { return [ $path . $entity->{$field}, $path . 'sm-' . $entity->{$field}, @@ -568,14 +576,14 @@ public function testAfterDeleteUsesDeleteCallback() ]; }; - $behavior->setConfig($this->dataOk); + $behavior->setConfig($this->configOk); $behavior->expects($this->once())->method('getPathProcessor') - ->with($this->entity, $this->entity->field, 'field', $this->dataOk['field']) + ->with($this->entity, $this->entity->field, 'field', $this->configOk['field']) ->willReturn($this->processor); $this->processor->expects($this->once())->method('basepath') ->willReturn($path); $behavior->expects($this->once())->method('getWriter') - ->with($this->entity, [], 'field', $this->dataOk['field']) + ->with($this->entity, [], 'field', $this->configOk['field']) ->willReturn($this->writer); $this->writer->expects($this->once()) ->method('delete') @@ -612,7 +620,7 @@ public function testAfterDeleteWithProtectedFieldName() public function testGetWriter() { - $processor = $this->behavior->getWriter($this->entity, [], 'field', []); + $processor = $this->behavior->getWriter($this->entity, new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', []); $this->assertInstanceOf('Josegonzalez\Upload\File\Writer\WriterInterface', $processor); } @@ -620,72 +628,72 @@ public function testConstructFiles() { $files = $this->behavior->constructFiles( $this->entity, - ['tmp_name' => 'path/to/file/on/disk', 'name' => 'file.txt'], + new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', [], 'path' ); - $this->assertEquals(['path/to/file/on/disk' => 'path/file.txt'], $files); + $this->assertEquals(['php://temp' => 'path/file.txt'], $files); $files = $this->behavior->constructFiles( $this->entity, - ['tmp_name' => 'path/to/file/on/disk', 'name' => 'file.txt'], + new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', [], 'some/path' ); - $this->assertEquals(['path/to/file/on/disk' => 'some/path/file.txt'], $files); + $this->assertEquals(['php://temp' => 'some/path/file.txt'], $files); } public function testConstructFilesWithBasePathEndingDS() { $files = $this->behavior->constructFiles( $this->entity, - ['tmp_name' => 'path/to/file/on/disk', 'name' => 'file.txt'], + new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', [], 'path/' ); - $this->assertEquals(['path/to/file/on/disk' => 'path/file.txt'], $files); + $this->assertEquals(['php://temp' => 'path/file.txt'], $files); $files = $this->behavior->constructFiles( $this->entity, - ['tmp_name' => 'path/to/file/on/disk', 'name' => 'file.txt'], + new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', [], 'some/path/' ); - $this->assertEquals(['path/to/file/on/disk' => 'some/path/file.txt'], $files); + $this->assertEquals(['php://temp' => 'some/path/file.txt'], $files); } public function testConstructFilesWithCallable() { $callable = function () { - return ['path/to/callable/file/on/disk' => 'file.text']; + return ['php://temp' => 'file.text']; }; $files = $this->behavior->constructFiles( $this->entity, - ['tmp_name' => 'path/to/file/on/disk', 'name' => 'file.txt'], + new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', ['transformer' => $callable], 'some/path' ); - $this->assertEquals(['path/to/callable/file/on/disk' => 'some/path/file.text'], $files); + $this->assertEquals(['php://temp' => 'some/path/file.text'], $files); } public function testConstructFilesWithCallableAndBasePathEndingDS() { $callable = function () { - return ['path/to/callable/file/on/disk' => 'file.text']; + return ['php://temp' => 'file.text']; }; $files = $this->behavior->constructFiles( $this->entity, - ['tmp_name' => 'path/to/file/on/disk', 'name' => 'file.txt'], + new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK), 'field', ['transformer' => $callable], 'some/path/' ); - $this->assertEquals(['path/to/callable/file/on/disk' => 'some/path/file.text'], $files); + $this->assertEquals(['php://temp' => 'some/path/file.text'], $files); } public function testConstructFilesException() @@ -693,7 +701,7 @@ public function testConstructFilesException() $this->expectException('UnexpectedValueException', "'transformer' not set to instance of TransformerInterface: UnexpectedValueException"); $this->behavior->constructFiles( $this->entity, - ['tmp_name' => 'path/to/file/on/disk', 'name' => 'file.txt'], + new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', ['transformer' => 'UnexpectedValueException'], 'path' @@ -702,7 +710,7 @@ public function testConstructFilesException() public function testGetPathProcessor() { - $processor = $this->behavior->getPathProcessor($this->entity, [], 'field', []); + $processor = $this->behavior->getPathProcessor($this->entity, new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK), 'field', []); $this->assertInstanceOf('Josegonzalez\Upload\File\Path\ProcessorInterface', $processor); } } From 04ea0eb2d3724d07bda95c9e5a8847cd46d0f9d8 Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Mon, 27 Jan 2020 13:29:35 -0300 Subject: [PATCH 15/40] Fix some tests --- src/File/Path/DefaultProcessor.php | 4 ++-- src/File/Path/Filename/DefaultTrait.php | 4 ++++ src/File/Writer/DefaultWriter.php | 4 ++-- src/Model/Behavior/UploadBehavior.php | 10 +++++----- tests/TestCase/Model/Behavior/UploadBehaviorTest.php | 4 ++-- 5 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/File/Path/DefaultProcessor.php b/src/File/Path/DefaultProcessor.php index 593c4a96..5d891ce7 100644 --- a/src/File/Path/DefaultProcessor.php +++ b/src/File/Path/DefaultProcessor.php @@ -54,11 +54,11 @@ class DefaultProcessor implements ProcessorInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param array|string $data the data being submitted for a save or filename stored in db + * @param UploadedFileInterface|string $data the data being submitted for a save or filename stored in db * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Path/Filename/DefaultTrait.php b/src/File/Path/Filename/DefaultTrait.php index b13b1dc5..4bdec2e6 100644 --- a/src/File/Path/Filename/DefaultTrait.php +++ b/src/File/Path/Filename/DefaultTrait.php @@ -26,6 +26,10 @@ public function filename(): string return $processor($this->table, $this->entity, $this->data, $this->field, $this->settings); } + if(is_string($this->data)) { + return $this->data; + } + return $this->data->getClientFilename(); } } diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index e8f8b64d..b1f8124b 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -56,11 +56,11 @@ class DefaultWriter implements WriterInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface|array $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, $data, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index d07a74fe..8a2e9e83 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -161,7 +161,7 @@ public function afterDelete(EventInterface $event, EntityInterface $entity, Arra $files = [$path . $entity->get($field)]; } - $writer = $this->getWriter($entity, new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK), $field, $settings); + $writer = $this->getWriter($entity, [], $field, $settings); $success = $writer->delete($files); if ($result && (new Collection($success))->contains(false)) { @@ -177,12 +177,12 @@ public function afterDelete(EventInterface $event, EntityInterface $entity, Arra * for a given file upload * * @param \Cake\Datasource\EntityInterface $entity an entity - * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface|string $data the data being submitted for a save or the filename * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Path\ProcessorInterface */ - public function getPathProcessor(EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings): ProcessorInterface + public function getPathProcessor(EntityInterface $entity, $data, string $field, array $settings): ProcessorInterface { $processorClass = Hash::get($settings, 'pathProcessor', DefaultProcessor::class); @@ -193,12 +193,12 @@ public function getPathProcessor(EntityInterface $entity, UploadedFileInterface * Retrieves an instance of a file writer which knows how to write files to disk * * @param \Cake\Datasource\EntityInterface $entity an entity - * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface|array $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Writer\WriterInterface */ - public function getWriter(EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings): WriterInterface + public function getWriter(EntityInterface $entity, $data, string $field, array $settings): WriterInterface { $writerClass = Hash::get($settings, 'writer', DefaultWriter::class); diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index 1159bc88..303d16ef 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -468,7 +468,7 @@ public function testAfterDeleteUsesPathProcessorToDetectPathToTheFile() // expecting getPathProcessor to be called with right arguments for dataOk $behavior->expects($this->once()) ->method('getPathProcessor') - ->with($this->entity, $field, 'field', $this->dataOk['field']) + ->with($this->entity, $field, 'field', $this->configOk['field']) ->willReturn($this->processor); // basepath of processor should return our fake path $this->processor->expects($this->once()) @@ -477,7 +477,7 @@ public function testAfterDeleteUsesPathProcessorToDetectPathToTheFile() // expecting getWriter to be called with right arguments for dataOk $behavior->expects($this->once()) ->method('getWriter') - ->with($this->entity, [], 'field', $this->dataOk['field']) + ->with($this->entity, [], 'field', $this->configOk['field']) ->willReturn($this->writer); // and here we check that file with right path will be deleted $this->writer->expects($this->once()) From e9ca3c596ddab4e902525a68ea425bf5eba61292 Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Mon, 27 Jan 2020 15:53:59 -0300 Subject: [PATCH 16/40] Fix codestyle --- src/File/Path/DefaultProcessor.php | 5 ++--- src/File/Path/Filename/DefaultTrait.php | 4 ++-- src/File/Writer/DefaultWriter.php | 1 - src/Model/Behavior/UploadBehavior.php | 5 ++--- .../TestCase/Model/Behavior/UploadBehaviorTest.php | 14 +++++++------- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/File/Path/DefaultProcessor.php b/src/File/Path/DefaultProcessor.php index 5d891ce7..d3b1df92 100644 --- a/src/File/Path/DefaultProcessor.php +++ b/src/File/Path/DefaultProcessor.php @@ -7,7 +7,6 @@ use Cake\ORM\Table; use Josegonzalez\Upload\File\Path\Basepath\DefaultTrait as BasepathTrait; use Josegonzalez\Upload\File\Path\Filename\DefaultTrait as FilenameTrait; -use Psr\Http\Message\UploadedFileInterface; class DefaultProcessor implements ProcessorInterface { @@ -31,7 +30,7 @@ class DefaultProcessor implements ProcessorInterface /** * Instance of \Psr\Http\Message\UploadedFileInterface conaining the meta info from the file. * - * @var \Psr\Http\Message\UploadedFileInterface + * @var \Psr\Http\Message\UploadedFileInterface|string */ protected $data; @@ -54,7 +53,7 @@ class DefaultProcessor implements ProcessorInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param UploadedFileInterface|string $data the data being submitted for a save or filename stored in db + * @param \Psr\Http\Message\UploadedFileInterface|string $data the data being submitted for a save or filename stored in db * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ diff --git a/src/File/Path/Filename/DefaultTrait.php b/src/File/Path/Filename/DefaultTrait.php index 4bdec2e6..b5f9c8be 100644 --- a/src/File/Path/Filename/DefaultTrait.php +++ b/src/File/Path/Filename/DefaultTrait.php @@ -26,10 +26,10 @@ public function filename(): string return $processor($this->table, $this->entity, $this->data, $this->field, $this->settings); } - if(is_string($this->data)) { + if (is_string($this->data)) { return $this->data; } - + return $this->data->getClientFilename(); } } diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index b1f8124b..123e3f84 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -12,7 +12,6 @@ use League\Flysystem\Filesystem; use League\Flysystem\FilesystemInterface; use UnexpectedValueException; -use Psr\Http\Message\UploadedFileInterface; class DefaultWriter implements WriterInterface { diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 8a2e9e83..512e4741 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -15,9 +15,8 @@ use Josegonzalez\Upload\File\Transformer\TransformerInterface; use Josegonzalez\Upload\File\Writer\DefaultWriter; use Josegonzalez\Upload\File\Writer\WriterInterface; -use Laminas\Diactoros\UploadedFile; -use UnexpectedValueException; use Psr\Http\Message\UploadedFileInterface; +use UnexpectedValueException; class UploadBehavior extends Behavior { @@ -97,7 +96,7 @@ public function beforeSave(EventInterface $event, EntityInterface $entity, Array continue; } - if(empty($entity->get($field))) { + if (empty($entity->get($field))) { continue; } diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index 303d16ef..a4434aea 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -28,26 +28,26 @@ public function setUp(): void 1, UPLOAD_ERR_OK, 'derp', - 'text/plain' - ) + 'text/plain', + ), ]; $this->configOk = [ 'field' => [ 'keepFilesOnDelete' => false, - 'deleteCallback' => null - ] + 'deleteCallback' => null, + ], ]; $this->dataError = [ 'field' => new UploadedFile( fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_NO_FILE, - 'derp' - ) + 'derp', + ), ]; $this->configError = [ - 'field' => [] + 'field' => [], ]; $this->field = 'field'; $this->settings = ['field' => []]; From 8658cce6127db484d489c84c2947cbfd6817f439 Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Mon, 27 Jan 2020 16:08:00 -0300 Subject: [PATCH 17/40] Correcting errors introduced in the previous commit --- composer.json | 3 ++- src/File/Transformer/DefaultTransformer.php | 2 +- tests/TestCase/Model/Behavior/UploadBehaviorTest.php | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 7f49c3de..8efce866 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,8 @@ "require-dev": { "phpunit/phpunit": "~8.5.0", "league/flysystem-vfs": "*", - "cakephp/cakephp-codesniffer": "^4.0" + "cakephp/cakephp-codesniffer": "^4.0", + "phpstan/phpstan": "^0.12" }, "autoload": { "psr-4": { diff --git a/src/File/Transformer/DefaultTransformer.php b/src/File/Transformer/DefaultTransformer.php index 239ff6bc..75d10f24 100644 --- a/src/File/Transformer/DefaultTransformer.php +++ b/src/File/Transformer/DefaultTransformer.php @@ -26,7 +26,7 @@ class DefaultTransformer implements TransformerInterface /** * Array of uploaded data for this field * - * @var array + * @var \Psr\Http\Message\UploadedFileInterface */ protected $data; diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index a4434aea..544ed5b1 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -28,7 +28,7 @@ public function setUp(): void 1, UPLOAD_ERR_OK, 'derp', - 'text/plain', + 'text/plain' ), ]; @@ -43,7 +43,7 @@ public function setUp(): void fopen('php://temp', 'wb+'), 0, UPLOAD_ERR_NO_FILE, - 'derp', + 'derp' ), ]; $this->configError = [ From 2de4cadf37fd8005801a279e24dda2fbc02b0ddf Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Mon, 27 Jan 2020 16:22:10 -0300 Subject: [PATCH 18/40] Add missing require --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8efce866..7d614d82 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,8 @@ ], "require": { "cakephp/cakephp": "^4.0", - "league/flysystem": "*" + "league/flysystem": "*", + "laminas/laminas-diactoros": "^2.2.2" }, "require-dev": { "phpunit/phpunit": "~8.5.0", From 8645dae993a9a98a4e923cf4c3d955e57684ab28 Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Tue, 28 Jan 2020 16:20:24 -0300 Subject: [PATCH 19/40] fixing typehints and phpstan.neon configure file --- phpstan.neon | 5 ----- src/File/Writer/DefaultWriter.php | 7 ++++--- src/File/Writer/WriterInterface.php | 4 ++-- src/Model/Behavior/UploadBehavior.php | 6 +++--- tests/TestCase/Model/Behavior/UploadBehaviorTest.php | 6 +++--- 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 120aee6e..fe8ef2b5 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -8,11 +8,6 @@ parameters: count: 1 path: src/File/Writer/DefaultWriter.php - - - message: "#^Method Josegonzalez\\\\Upload\\\\Model\\\\Behavior\\\\UploadBehavior\\:\\:beforeSave\\(\\) should return void\\|false but return statement is missing\\.$#" - count: 1 - path: src/Model/Behavior/UploadBehavior.php - - message: "#^Cannot instantiate interface Josegonzalez\\\\Upload\\\\File\\\\Transformer\\\\TransformerInterface\\.$#" count: 1 diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index 123e3f84..bc70c255 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -11,6 +11,7 @@ use League\Flysystem\FileNotFoundException; use League\Flysystem\Filesystem; use League\Flysystem\FilesystemInterface; +use Psr\Http\Message\UploadedFileInterface; use UnexpectedValueException; class DefaultWriter implements WriterInterface @@ -32,7 +33,7 @@ class DefaultWriter implements WriterInterface /** * Array of uploaded data for this field * - * @var array + * @var \Psr\Http\Message\UploadedFileInterface|null */ protected $data; @@ -55,11 +56,11 @@ class DefaultWriter implements WriterInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param \Psr\Http\Message\UploadedFileInterface|array $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface|null $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, $data, string $field, array $settings) + public function __construct(Table $table, EntityInterface $entity, ?UploadedFileInterface $data = null, string $field, array $settings) { $this->table = $table; $this->entity = $entity; diff --git a/src/File/Writer/WriterInterface.php b/src/File/Writer/WriterInterface.php index a358e776..dceab5b1 100644 --- a/src/File/Writer/WriterInterface.php +++ b/src/File/Writer/WriterInterface.php @@ -14,11 +14,11 @@ interface WriterInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface|null $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, ?UploadedFileInterface $data = null, string $field, array $settings); /** * Writes a set of files to an output diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 512e4741..d0a73086 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -160,7 +160,7 @@ public function afterDelete(EventInterface $event, EntityInterface $entity, Arra $files = [$path . $entity->get($field)]; } - $writer = $this->getWriter($entity, [], $field, $settings); + $writer = $this->getWriter($entity, null, $field, $settings); $success = $writer->delete($files); if ($result && (new Collection($success))->contains(false)) { @@ -192,12 +192,12 @@ public function getPathProcessor(EntityInterface $entity, $data, string $field, * Retrieves an instance of a file writer which knows how to write files to disk * * @param \Cake\Datasource\EntityInterface $entity an entity - * @param \Psr\Http\Message\UploadedFileInterface|array $data the data being submitted for a save + * @param \Psr\Http\Message\UploadedFileInterface|null $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Writer\WriterInterface */ - public function getWriter(EntityInterface $entity, $data, string $field, array $settings): WriterInterface + public function getWriter(EntityInterface $entity, ?UploadedFileInterface $data = null, string $field, array $settings): WriterInterface { $writerClass = Hash::get($settings, 'writer', DefaultWriter::class); diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index 544ed5b1..a8706ad1 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -477,7 +477,7 @@ public function testAfterDeleteUsesPathProcessorToDetectPathToTheFile() // expecting getWriter to be called with right arguments for dataOk $behavior->expects($this->once()) ->method('getWriter') - ->with($this->entity, [], 'field', $this->configOk['field']) + ->with($this->entity, null, 'field', $this->configOk['field']) ->willReturn($this->writer); // and here we check that file with right path will be deleted $this->writer->expects($this->once()) @@ -546,7 +546,7 @@ public function testAfterDeleteNoDeleteCallback() $this->processor->expects($this->once())->method('basepath') ->willReturn($path); $behavior->expects($this->once())->method('getWriter') - ->with($this->entity, [], 'field', $this->configOk['field']) + ->with($this->entity, null, 'field', $this->configOk['field']) ->willReturn($this->writer); $this->writer->expects($this->once()) ->method('delete') @@ -583,7 +583,7 @@ public function testAfterDeleteUsesDeleteCallback() $this->processor->expects($this->once())->method('basepath') ->willReturn($path); $behavior->expects($this->once())->method('getWriter') - ->with($this->entity, [], 'field', $this->configOk['field']) + ->with($this->entity, null, 'field', $this->configOk['field']) ->willReturn($this->writer); $this->writer->expects($this->once()) ->method('delete') From 5276ddad935a84c817e2ee2a5e5d3679d4bfc69e Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Tue, 28 Jan 2020 16:32:14 -0300 Subject: [PATCH 20/40] Fix one more type hint --- src/File/Path/ProcessorInterface.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/File/Path/ProcessorInterface.php b/src/File/Path/ProcessorInterface.php index 4b122029..96735eef 100644 --- a/src/File/Path/ProcessorInterface.php +++ b/src/File/Path/ProcessorInterface.php @@ -5,7 +5,6 @@ use Cake\Datasource\EntityInterface; use Cake\ORM\Table; -use Psr\Http\Message\UploadedFileInterface; interface ProcessorInterface { @@ -14,11 +13,11 @@ interface ProcessorInterface * * @param \Cake\ORM\Table $table the instance managing the entity * @param \Cake\Datasource\EntityInterface $entity the entity to construct a path for. - * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save or filename stored in db + * @param \Psr\Http\Message\UploadedFileInterface|string $data the data being submitted for a save or filename stored in db * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings); + public function __construct(Table $table, EntityInterface $entity, $data, string $field, array $settings); /** * Returns the basepath for the current field/data combination From 10f6de95093a331463493ba1f7dd5755a2099e80 Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Tue, 28 Jan 2020 16:34:59 -0300 Subject: [PATCH 21/40] We need laminas-diactoros only on require-dev --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 7d614d82..af4d8453 100644 --- a/composer.json +++ b/composer.json @@ -13,11 +13,11 @@ ], "require": { "cakephp/cakephp": "^4.0", - "league/flysystem": "*", - "laminas/laminas-diactoros": "^2.2.2" + "league/flysystem": "*" }, "require-dev": { "phpunit/phpunit": "~8.5.0", + "laminas/laminas-diactoros": "^2.2.2", "league/flysystem-vfs": "*", "cakephp/cakephp-codesniffer": "^4.0", "phpstan/phpstan": "^0.12" From 5f56295c453f2876430215a49bd715987c5fccf6 Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Tue, 3 Mar 2020 15:07:09 -0300 Subject: [PATCH 22/40] Remove laminas/laminas-diactoros dependency --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index af4d8453..8efce866 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,6 @@ }, "require-dev": { "phpunit/phpunit": "~8.5.0", - "laminas/laminas-diactoros": "^2.2.2", "league/flysystem-vfs": "*", "cakephp/cakephp-codesniffer": "^4.0", "phpstan/phpstan": "^0.12" From 1c419ad1731c24501d1c8972bcbdf642b7ee3519 Mon Sep 17 00:00:00 2001 From: Gerson Felipe Schwinn Date: Tue, 3 Mar 2020 16:48:06 -0300 Subject: [PATCH 23/40] Bump up cakephp constraint to 4.0.2 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 8efce866..0d2b9eb1 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } ], "require": { - "cakephp/cakephp": "^4.0", + "cakephp/cakephp": "^4.0.2", "league/flysystem": "*" }, "require-dev": { From 5c9ef7c7fceefc227b6016613128f132ba5b970e Mon Sep 17 00:00:00 2001 From: Chris Hallgren Date: Sat, 28 Mar 2020 08:28:17 -0500 Subject: [PATCH 24/40] Fixing validators to use UploadedFileInterface Signed-off-by: Chris Hallgren --- .../Traits/ImageValidationTrait.php | 55 +++++++++++++------ .../Traits/UploadValidationTrait.php | 29 ++++++++++ .../Validation/ImageValidationTest.php | 17 ++++++ .../Validation/UploadValidationTest.php | 39 +++++++++++++ 4 files changed, 124 insertions(+), 16 deletions(-) diff --git a/src/Validation/Traits/ImageValidationTrait.php b/src/Validation/Traits/ImageValidationTrait.php index 10de9b48..b69d0bb4 100644 --- a/src/Validation/Traits/ImageValidationTrait.php +++ b/src/Validation/Traits/ImageValidationTrait.php @@ -3,6 +3,8 @@ namespace Josegonzalez\Upload\Validation\Traits; +use Psr\Http\Message\UploadedFileInterface; + trait ImageValidationTrait { /** @@ -14,11 +16,16 @@ trait ImageValidationTrait */ public static function isAboveMinWidth($check, int $width): bool { - // Non-file uploads also mean the height is too big - if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { - return false; + if ($check instanceof UploadedFileInterface) { + $file = $check->getStream()->getMetadata('uri'); + } else { + // Non-file uploads also mean the height is too big + if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { + return false; + } + $file = $check['tmp_name']; } - [$imgWidth] = getimagesize($check['tmp_name']); + [$imgWidth] = getimagesize($file); return $width > 0 && $imgWidth >= $width; } @@ -32,11 +39,17 @@ public static function isAboveMinWidth($check, int $width): bool */ public static function isBelowMaxWidth($check, int $width): bool { - // Non-file uploads also mean the height is too big - if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { - return false; + if ($check instanceof UploadedFileInterface) { + $file = $check->getStream()->getMetadata('uri'); + } else { + // Non-file uploads also mean the height is too big + if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { + return false; + } + + $file = $check['tmp_name']; } - [$imgWidth] = getimagesize($check['tmp_name']); + [$imgWidth] = getimagesize($file); return $width > 0 && $imgWidth <= $width; } @@ -50,11 +63,16 @@ public static function isBelowMaxWidth($check, int $width): bool */ public static function isAboveMinHeight($check, int $height): bool { - // Non-file uploads also mean the height is too big - if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { - return false; + if ($check instanceof UploadedFileInterface) { + $file = $check->getStream()->getMetadata('uri'); + } else { + // Non-file uploads also mean the height is too big + if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { + return false; + } + $file = $check['tmp_name']; } - [, $imgHeight] = getimagesize($check['tmp_name']); + [, $imgHeight] = getimagesize($file); return $height > 0 && $imgHeight >= $height; } @@ -68,11 +86,16 @@ public static function isAboveMinHeight($check, int $height): bool */ public static function isBelowMaxHeight($check, int $height): bool { - // Non-file uploads also mean the height is too big - if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { - return false; + if ($check instanceof UploadedFileInterface) { + $file = $check->getStream()->getMetadata('uri'); + } else { + // Non-file uploads also mean the height is too big + if (!isset($check['tmp_name']) || !strlen($check['tmp_name'])) { + return false; + } + $file = $check['tmp_name']; } - [, $imgHeight] = getimagesize($check['tmp_name']); + [, $imgHeight] = getimagesize($file); return $height > 0 && $imgHeight <= $height; } diff --git a/src/Validation/Traits/UploadValidationTrait.php b/src/Validation/Traits/UploadValidationTrait.php index bc8287de..21ab3338 100644 --- a/src/Validation/Traits/UploadValidationTrait.php +++ b/src/Validation/Traits/UploadValidationTrait.php @@ -4,6 +4,7 @@ namespace Josegonzalez\Upload\Validation\Traits; use Cake\Utility\Hash; +use Psr\Http\Message\UploadedFileInterface; trait UploadValidationTrait { @@ -16,6 +17,10 @@ trait UploadValidationTrait */ public static function isUnderPhpSizeLimit($check): bool { + if ($check instanceof UploadedFileInterface) { + return $check->getError() !== UPLOAD_ERR_INI_SIZE; + } + return Hash::get($check, 'error') !== UPLOAD_ERR_INI_SIZE; } @@ -28,6 +33,10 @@ public static function isUnderPhpSizeLimit($check): bool */ public static function isUnderFormSizeLimit($check): bool { + if ($check instanceof UploadedFileInterface) { + return $check->getError() !== UPLOAD_ERR_FORM_SIZE; + } + return Hash::get($check, 'error') !== UPLOAD_ERR_FORM_SIZE; } @@ -39,6 +48,10 @@ public static function isUnderFormSizeLimit($check): bool */ public static function isCompletedUpload($check): bool { + if ($check instanceof UploadedFileInterface) { + return $check->getError() !== UPLOAD_ERR_PARTIAL; + } + return Hash::get($check, 'error') !== UPLOAD_ERR_PARTIAL; } @@ -50,6 +63,10 @@ public static function isCompletedUpload($check): bool */ public static function isFileUpload($check): bool { + if ($check instanceof UploadedFileInterface) { + return $check->getError() !== UPLOAD_ERR_NO_FILE; + } + return Hash::get($check, 'error') !== UPLOAD_ERR_NO_FILE; } @@ -61,6 +78,10 @@ public static function isFileUpload($check): bool */ public static function isSuccessfulWrite($check): bool { + if ($check instanceof UploadedFileInterface) { + return $check->getError() !== UPLOAD_ERR_CANT_WRITE; + } + return Hash::get($check, 'error') !== UPLOAD_ERR_CANT_WRITE; } @@ -73,6 +94,10 @@ public static function isSuccessfulWrite($check): bool */ public static function isAboveMinSize($check, $size): bool { + if ($check instanceof UploadedFileInterface) { + return $check->getSize() >= $size; + } + return !empty($check['size']) && $check['size'] >= $size; } @@ -85,6 +110,10 @@ public static function isAboveMinSize($check, $size): bool */ public static function isBelowMaxSize($check, $size): bool { + if ($check instanceof UploadedFileInterface) { + return $check->getSize() <= $size; + } + return !empty($check['size']) && $check['size'] <= $size; } } diff --git a/tests/TestCase/Validation/ImageValidationTest.php b/tests/TestCase/Validation/ImageValidationTest.php index fe3615f4..0b6af1ea 100644 --- a/tests/TestCase/Validation/ImageValidationTest.php +++ b/tests/TestCase/Validation/ImageValidationTest.php @@ -5,6 +5,7 @@ use Cake\TestSuite\TestCase; use Josegonzalez\Upload\Validation\ImageValidation; +use Laminas\Diactoros\UploadedFile; use VirtualFileSystem\FileSystem as Vfs; class ImageValidationTest extends TestCase @@ -35,6 +36,10 @@ public function setUp(): void public function testIsAboveMinWidth() { + $file = new UploadedFile($this->data['tmp_name'], 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(ImageValidation::isAboveMinWidth($file, 10)); + $this->assertFalse(ImageValidation::isAboveMinWidth($file, 30)); + $this->assertTrue(ImageValidation::isAboveMinWidth($this->data, 10)); $this->assertFalse(ImageValidation::isAboveMinWidth($this->data, 30)); @@ -48,6 +53,10 @@ public function testIsAboveMinWidth() public function testIsBelowMaxWidth() { + $file = new UploadedFile($this->data['tmp_name'], 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(ImageValidation::isBelowMaxWidth($file, 30)); + $this->assertFalse(ImageValidation::isBelowMaxWidth($file, 10)); + $this->assertTrue(ImageValidation::isBelowMaxWidth($this->data, 30)); $this->assertFalse(ImageValidation::isBelowMaxWidth($this->data, 10)); @@ -61,6 +70,10 @@ public function testIsBelowMaxWidth() public function testIsAboveMinHeight() { + $file = new UploadedFile($this->data['tmp_name'], 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(ImageValidation::isAboveMinHeight($file, 10)); + $this->assertFalse(ImageValidation::isAboveMinHeight($file, 30)); + $this->assertTrue(ImageValidation::isAboveMinHeight($this->data, 10)); $this->assertFalse(ImageValidation::isAboveMinHeight($this->data, 30)); @@ -74,6 +87,10 @@ public function testIsAboveMinHeight() public function testIsBelowMaxHeight() { + $file = new UploadedFile($this->data['tmp_name'], 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(ImageValidation::isBelowMaxHeight($file, 30)); + $this->assertFalse(ImageValidation::isBelowMaxHeight($file, 10)); + $this->assertTrue(ImageValidation::isBelowMaxHeight($this->data, 30)); $this->assertFalse(ImageValidation::isBelowMaxHeight($this->data, 10)); diff --git a/tests/TestCase/Validation/UploadValidationTest.php b/tests/TestCase/Validation/UploadValidationTest.php index 2cd52f23..48a80cfc 100644 --- a/tests/TestCase/Validation/UploadValidationTest.php +++ b/tests/TestCase/Validation/UploadValidationTest.php @@ -5,6 +5,7 @@ use Cake\TestSuite\TestCase; use Josegonzalez\Upload\Validation\UploadValidation; +use Laminas\Diactoros\UploadedFile; class UploadValidationTest extends TestCase { @@ -25,30 +26,60 @@ public function testIsUnderPhpSizeLimit() { $this->assertTrue(UploadValidation::isUnderPhpSizeLimit($this->data + ['error' => UPLOAD_ERR_OK])); $this->assertFalse(UploadValidation::isUnderPhpSizeLimit($this->data + ['error' => UPLOAD_ERR_INI_SIZE])); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(UploadValidation::isUnderPhpSizeLimit($file)); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_INI_SIZE, 'sample.txt', 'text/plain'); + $this->assertFalse(UploadValidation::isUnderPhpSizeLimit($file)); } public function testIsUnderFormSizeLimit() { $this->assertTrue(UploadValidation::isUnderFormSizeLimit($this->data + ['error' => UPLOAD_ERR_OK])); $this->assertFalse(UploadValidation::isUnderFormSizeLimit($this->data + ['error' => UPLOAD_ERR_FORM_SIZE])); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(UploadValidation::isUnderFormSizeLimit($file)); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_FORM_SIZE, 'sample.txt', 'text/plain'); + $this->assertFalse(UploadValidation::isUnderFormSizeLimit($file)); } public function testIsCompletedUpload() { $this->assertTrue(UploadValidation::isCompletedUpload($this->data + ['error' => UPLOAD_ERR_OK])); $this->assertFalse(UploadValidation::isCompletedUpload($this->data + ['error' => UPLOAD_ERR_PARTIAL])); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(UploadValidation::isCompletedUpload($file)); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_PARTIAL, 'sample.txt', 'text/plain'); + $this->assertFalse(UploadValidation::isCompletedUpload($file)); } public function testIsFileUpload() { $this->assertTrue(UploadValidation::isFileUpload($this->data + ['error' => UPLOAD_ERR_OK])); $this->assertFalse(UploadValidation::isFileUpload($this->data + ['error' => UPLOAD_ERR_NO_FILE])); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(UploadValidation::isFileUpload($file)); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_NO_FILE, 'sample.txt', 'text/plain'); + $this->assertFalse(UploadValidation::isFileUpload($file)); } public function testIsSuccessfulWrite() { $this->assertTrue(UploadValidation::isSuccessfulWrite($this->data + ['error' => UPLOAD_ERR_OK])); $this->assertFalse(UploadValidation::isSuccessfulWrite($this->data + ['error' => UPLOAD_ERR_CANT_WRITE])); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(UploadValidation::isSuccessfulWrite($file)); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_CANT_WRITE, 'sample.txt', 'text/plain'); + $this->assertFalse(UploadValidation::isSuccessfulWrite($file)); } public function testIsAboveMinSize() @@ -62,6 +93,10 @@ public function testIsAboveMinSize() unset($this->data['size']); $this->assertFalse(UploadValidation::isAboveMinSize($this->data, 200)); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(UploadValidation::isAboveMinSize($file, 200)); + $this->assertFalse(UploadValidation::isAboveMinSize($file, 250)); } public function testIsBelowMaxSize() @@ -75,5 +110,9 @@ public function testIsBelowMaxSize() unset($this->data['size']); $this->assertFalse(UploadValidation::isBelowMaxSize($this->data, 200)); + + $file = new UploadedFile(fopen('php://temp', 'rw+'), 200, UPLOAD_ERR_OK, 'sample.txt', 'text/plain'); + $this->assertTrue(UploadValidation::isBelowMaxSize($file, 200)); + $this->assertFalse(UploadValidation::isBelowMaxSize($file, 150)); } } From 4f0da6396bf78d8d67fa7bec77ac6775a622f45b Mon Sep 17 00:00:00 2001 From: ADmad Date: Thu, 16 Apr 2020 19:52:33 +0530 Subject: [PATCH 25/40] Fix CS error --- src/Database/Type/FileType.php | 4 ++-- src/File/Transformer/DefaultTransformer.php | 9 +++++++-- src/File/Transformer/TransformerInterface.php | 8 +++++++- src/File/Writer/DefaultWriter.php | 9 +++++++-- src/File/Writer/WriterInterface.php | 8 +++++++- src/Model/Behavior/UploadBehavior.php | 8 ++++++-- 6 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/Database/Type/FileType.php b/src/Database/Type/FileType.php index 22092a94..f59faa75 100644 --- a/src/Database/Type/FileType.php +++ b/src/Database/Type/FileType.php @@ -23,7 +23,7 @@ public function marshal($value) } /** - * {@inheritDoc} + * @inheritDoc */ public function toDatabase($value, DriverInterface $driver) { @@ -31,7 +31,7 @@ public function toDatabase($value, DriverInterface $driver) } /** - * {@inheritDoc} + * @inheritDoc */ public function toPHP($value, DriverInterface $driver) { diff --git a/src/File/Transformer/DefaultTransformer.php b/src/File/Transformer/DefaultTransformer.php index 75d10f24..8f6d6bff 100644 --- a/src/File/Transformer/DefaultTransformer.php +++ b/src/File/Transformer/DefaultTransformer.php @@ -53,8 +53,13 @@ class DefaultTransformer implements TransformerInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings) - { + public function __construct( + Table $table, + EntityInterface $entity, + UploadedFileInterface $data, + string $field, + array $settings + ) { $this->table = $table; $this->entity = $entity; $this->data = $data; diff --git a/src/File/Transformer/TransformerInterface.php b/src/File/Transformer/TransformerInterface.php index ea5dc232..4175eba3 100644 --- a/src/File/Transformer/TransformerInterface.php +++ b/src/File/Transformer/TransformerInterface.php @@ -18,7 +18,13 @@ interface TransformerInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, UploadedFileInterface $data, string $field, array $settings); + public function __construct( + Table $table, + EntityInterface $entity, + UploadedFileInterface $data, + string $field, + array $settings + ); /** * Creates a set of files from the initial data and returns them as key/value diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index bc70c255..5fecf65e 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -60,8 +60,13 @@ class DefaultWriter implements WriterInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, ?UploadedFileInterface $data = null, string $field, array $settings) - { + public function __construct( + Table $table, + EntityInterface $entity, + ?UploadedFileInterface $data = null, + string $field, + array $settings + ) { $this->table = $table; $this->entity = $entity; $this->data = $data; diff --git a/src/File/Writer/WriterInterface.php b/src/File/Writer/WriterInterface.php index dceab5b1..b1891950 100644 --- a/src/File/Writer/WriterInterface.php +++ b/src/File/Writer/WriterInterface.php @@ -18,7 +18,13 @@ interface WriterInterface * @param string $field the field for which data will be saved * @param array $settings the settings for the current field */ - public function __construct(Table $table, EntityInterface $entity, ?UploadedFileInterface $data = null, string $field, array $settings); + public function __construct( + Table $table, + EntityInterface $entity, + ?UploadedFileInterface $data = null, + string $field, + array $settings + ); /** * Writes a set of files to an output diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index d0a73086..3304d81f 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -197,8 +197,12 @@ public function getPathProcessor(EntityInterface $entity, $data, string $field, * @param array $settings the settings for the current field * @return \Josegonzalez\Upload\File\Writer\WriterInterface */ - public function getWriter(EntityInterface $entity, ?UploadedFileInterface $data = null, string $field, array $settings): WriterInterface - { + public function getWriter( + EntityInterface $entity, + ?UploadedFileInterface $data = null, + string $field, + array $settings + ): WriterInterface { $writerClass = Hash::get($settings, 'writer', DefaultWriter::class); return new $writerClass($this->_table, $entity, $data, $field, $settings); From e3357dfbe19188a2572b88c336345984141cb51d Mon Sep 17 00:00:00 2001 From: ADmad Date: Thu, 16 Apr 2020 19:48:09 +0530 Subject: [PATCH 26/40] Ensure transformer recieves filename generated by path processor. Closes #533. --- src/File/Transformer/DefaultTransformer.php | 5 ++- src/File/Transformer/SlugTransformer.php | 9 ++-- src/File/Transformer/TransformerInterface.php | 3 +- src/Model/Behavior/UploadBehavior.php | 17 +++++--- tests/Stub/ChildBehavior.php | 15 +++++++ .../Transformer/DefaultTransformerTest.php | 5 ++- .../File/Transformer/SlugTransformerTest.php | 4 +- .../Model/Behavior/UploadBehaviorTest.php | 42 +++++++++++++++---- 8 files changed, 78 insertions(+), 22 deletions(-) diff --git a/src/File/Transformer/DefaultTransformer.php b/src/File/Transformer/DefaultTransformer.php index 8f6d6bff..7d7c32f2 100644 --- a/src/File/Transformer/DefaultTransformer.php +++ b/src/File/Transformer/DefaultTransformer.php @@ -77,10 +77,11 @@ public function __construct( * '/tmp/path/to/file/on/disk-2' => 'file-preview.png', * ] * + * @param string $filename Filename. * @return array key/value pairs of temp files mapping to their names */ - public function transform(): array + public function transform(string $filename): array { - return [$this->data->getStream()->getMetadata('uri') => $this->data->getClientFileName()]; + return [$this->data->getStream()->getMetadata('uri') => $filename]; } } diff --git a/src/File/Transformer/SlugTransformer.php b/src/File/Transformer/SlugTransformer.php index 9f230994..f2e390f7 100644 --- a/src/File/Transformer/SlugTransformer.php +++ b/src/File/Transformer/SlugTransformer.php @@ -21,14 +21,15 @@ class SlugTransformer extends DefaultTransformer * ] * ``` * + * @param string $filename Filename. * @return array key/value pairs of temp files mapping to their names */ - public function transform(): array + public function transform(string $filename): array { - $filename = pathinfo($this->data->getClientFilename(), PATHINFO_FILENAME); - $filename = Text::slug($filename, '-'); + $ext = pathinfo($filename, PATHINFO_EXTENSION); + $filename = pathinfo($filename, PATHINFO_FILENAME); - $ext = pathinfo($this->data->getClientFilename(), PATHINFO_EXTENSION); + $filename = Text::slug($filename, '-'); if (!empty($ext)) { $filename = $filename . '.' . $ext; } diff --git a/src/File/Transformer/TransformerInterface.php b/src/File/Transformer/TransformerInterface.php index 4175eba3..442531c0 100644 --- a/src/File/Transformer/TransformerInterface.php +++ b/src/File/Transformer/TransformerInterface.php @@ -36,7 +36,8 @@ public function __construct( * '/tmp/path/to/file/on/disk-2' => 'file-preview.png', * ] * + * @param string $filename Filename. * @return array key/value pairs of temp files mapping to their names */ - public function transform(): array; + public function transform(string $filename): array; } diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 3304d81f..4bbf6283 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -112,8 +112,12 @@ public function beforeSave(EventInterface $event, EntityInterface $entity, Array $path = $this->getPathProcessor($entity, $data, $field, $settings); $basepath = $path->basepath(); $filename = $path->filename(); + $pathinfo = [ + 'basepath' => $basepath, + 'filename' => $filename, + ]; - $files = $this->constructFiles($entity, $data, $field, $settings, $basepath); + $files = $this->constructFiles($entity, $data, $field, $settings, $pathinfo); $writer = $this->getWriter($entity, $data, $field, $settings); $success = $writer->write($files); @@ -227,7 +231,7 @@ public function getWriter( * @param \Psr\Http\Message\UploadedFileInterface $data the data being submitted for a save * @param string $field the field for which data will be saved * @param array $settings the settings for the current field - * @param string $basepath a basepath where the files are written to + * @param array $pathinfo Path info. * @return array key/value pairs of temp files mapping to their names */ public function constructFiles( @@ -235,19 +239,22 @@ public function constructFiles( UploadedFileInterface $data, string $field, array $settings, - string $basepath + array $pathinfo ): array { + $basepath = $pathinfo['basepath']; + $filename = $pathinfo['filename']; + $basepath = substr($basepath, -1) == DS ? $basepath : $basepath . DS; $transformerClass = Hash::get($settings, 'transformer', DefaultTransformer::class); $results = []; if (is_subclass_of($transformerClass, TransformerInterface::class)) { $transformer = new $transformerClass($this->_table, $entity, $data, $field, $settings); - $results = $transformer->transform(); + $results = $transformer->transform($filename); foreach ($results as $key => $value) { $results[$key] = $basepath . $value; } } elseif (is_callable($transformerClass)) { - $results = $transformerClass($this->_table, $entity, $data, $field, $settings); + $results = $transformerClass($this->_table, $entity, $data, $field, $settings, $filename); foreach ($results as $key => $value) { $results[$key] = $basepath . $value; } diff --git a/tests/Stub/ChildBehavior.php b/tests/Stub/ChildBehavior.php index 2f4546bf..b8afddb5 100644 --- a/tests/Stub/ChildBehavior.php +++ b/tests/Stub/ChildBehavior.php @@ -3,9 +3,24 @@ namespace Josegonzalez\Upload\Test\Stub; +use Cake\Datasource\EntityInterface; use Josegonzalez\Upload\Model\Behavior\UploadBehavior; +use Psr\Http\Message\UploadedFileInterface; class ChildBehavior extends UploadBehavior { protected $_defaultConfig = ['key' => 'value']; + + public function constructFiles( + EntityInterface $entity, + UploadedFileInterface $data, + string $field, + array $settings, + array $pathinfo + ): array { + $files = parent::constructFiles($entity, $data, $field, $settings, $pathinfo); + $this->constructedFiles = $files; + + return $files; + } } diff --git a/tests/TestCase/File/Transformer/DefaultTransformerTest.php b/tests/TestCase/File/Transformer/DefaultTransformerTest.php index 18a68d94..4e6e5d8b 100644 --- a/tests/TestCase/File/Transformer/DefaultTransformerTest.php +++ b/tests/TestCase/File/Transformer/DefaultTransformerTest.php @@ -27,6 +27,9 @@ public function testIsProcessorInterface() public function testTransform() { - $this->assertEquals([$this->uploadedFile->getStream()->getMetadata('uri') => 'foo.txt'], $this->transformer->transform()); + $this->assertEquals( + [$this->uploadedFile->getStream()->getMetadata('uri') => 'foo.txt'], + $this->transformer->transform('foo.txt') + ); } } diff --git a/tests/TestCase/File/Transformer/SlugTransformerTest.php b/tests/TestCase/File/Transformer/SlugTransformerTest.php index e73c0948..7eba6cae 100644 --- a/tests/TestCase/File/Transformer/SlugTransformerTest.php +++ b/tests/TestCase/File/Transformer/SlugTransformerTest.php @@ -21,7 +21,7 @@ public function setUp(): void public function testTransform() { - $this->assertEquals(['php://temp' => 'foo-e-a.txt'], $this->transformer->transform()); + $this->assertEquals(['php://temp' => 'foo-e-a.txt'], $this->transformer->transform('foo é À.TXT')); } public function testTransformWithNoFileExt() @@ -30,6 +30,6 @@ public function testTransformWithNoFileExt() $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); $data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'foo é À'); $transformer = new SlugTransformer($table, $entity, $data, 'field', []); - $this->assertEquals(['php://temp' => 'foo-e-a'], $transformer->transform()); + $this->assertEquals(['php://temp' => 'foo-e-a'], $transformer->transform('foo é À')); } } diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index a8706ad1..fb719e5b 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -5,8 +5,10 @@ use ArrayObject; use Cake\Event\Event; +use Cake\ORM\Entity; use Cake\ORM\TableRegistry; use Cake\TestSuite\TestCase; +use Josegonzalez\Upload\File\Transformer\SlugTransformer; use Josegonzalez\Upload\Model\Behavior\UploadBehavior; use Josegonzalez\Upload\Test\Stub\ChildBehavior; use Laminas\Diactoros\UploadedFile; @@ -631,7 +633,7 @@ public function testConstructFiles() new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', [], - 'path' + ['basepath' => 'path', 'filename' => 'file.txt'] ); $this->assertEquals(['php://temp' => 'path/file.txt'], $files); @@ -640,7 +642,7 @@ public function testConstructFiles() new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', [], - 'some/path' + ['basepath' => 'some/path', 'filename' => 'file.txt'] ); $this->assertEquals(['php://temp' => 'some/path/file.txt'], $files); } @@ -652,7 +654,7 @@ public function testConstructFilesWithBasePathEndingDS() new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', [], - 'path/' + ['basepath' => 'path/', 'filename' => 'file.txt'] ); $this->assertEquals(['php://temp' => 'path/file.txt'], $files); @@ -661,7 +663,7 @@ public function testConstructFilesWithBasePathEndingDS() new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', [], - 'some/path/' + ['basepath' => 'some/path/', 'filename' => 'file.txt'] ); $this->assertEquals(['php://temp' => 'some/path/file.txt'], $files); } @@ -676,7 +678,7 @@ public function testConstructFilesWithCallable() new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', ['transformer' => $callable], - 'some/path' + ['basepath' => 'some/path', 'filename' => 'file.txt'] ); $this->assertEquals(['php://temp' => 'some/path/file.text'], $files); } @@ -691,7 +693,7 @@ public function testConstructFilesWithCallableAndBasePathEndingDS() new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK), 'field', ['transformer' => $callable], - 'some/path/' + ['basepath' => 'some/path', 'filename' => 'file.txt'] ); $this->assertEquals(['php://temp' => 'some/path/file.text'], $files); } @@ -704,7 +706,7 @@ public function testConstructFilesException() new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK, 'file.txt'), 'field', ['transformer' => 'UnexpectedValueException'], - 'path' + ['basepath' => 'path', 'filename' => 'file.txt'] ); } @@ -713,4 +715,30 @@ public function testGetPathProcessor() $processor = $this->behavior->getPathProcessor($this->entity, new UploadedFile(fopen('php://temp', 'rw+'), 1, UPLOAD_ERR_OK), 'field', []); $this->assertInstanceOf('Josegonzalez\Upload\File\Path\ProcessorInterface', $processor); } + + public function testNameCallback() + { + $table = TableRegistry::getTableLocator()->get('Files'); + $behavior = new ChildBehavior($table, [ + 'filename' => [ + 'nameCallback' => function ($table, $entity, $data, $field, $settings) { + return 'Awesome Filename.png'; + }, + 'transformer' => SlugTransformer::class, + ], + ]); + + $event = new Event('Model.beforeSave', $table); + $entity = new Entity([ + 'filename' => $this->dataOk['field'], + ]); + + $behavior->beforeSave($event, $entity, new ArrayObject()); + + $expected = [ + 'php://temp' => 'webroot/files/Files/filename/awesome-filename.png', + ]; + + $this->assertEquals($expected, $behavior->constructedFiles); + } } From e67af3541ae13e41ef52fc1b81c9da6883e631ce Mon Sep 17 00:00:00 2001 From: Jeff Shoemaker Date: Fri, 17 Apr 2020 06:14:34 -0600 Subject: [PATCH 27/40] Allow entity to contain an non-updated file upload. (#531) Allow entity to contain an non-updated file upload. --- src/File/Path/Basepath/DefaultTrait.php | 2 +- src/Model/Behavior/UploadBehavior.php | 5 ++--- tests/TestCase/Model/Behavior/UploadBehaviorTest.php | 10 +++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/File/Path/Basepath/DefaultTrait.php b/src/File/Path/Basepath/DefaultTrait.php index 9c1e706a..3319e8d2 100644 --- a/src/File/Path/Basepath/DefaultTrait.php +++ b/src/File/Path/Basepath/DefaultTrait.php @@ -57,7 +57,7 @@ public function basepath(): string 'Field value for substitution must be a integer, float, string or boolean: %s', $field )); - } elseif (strlen($value) < 1) { + } elseif (strlen((string)$value) < 1) { throw new LogicException(sprintf( 'Field value for substitution must be non-zero in length: %s', $field diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 3304d81f..263d1a04 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -72,8 +72,7 @@ public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObj if (!$validator->isEmptyAllowed($field, false)) { continue; } - - if ($dataArray[$field]->getError() !== UPLOAD_ERR_NO_FILE) { + if (!empty($dataArray[$field]) && $dataArray[$field]->getError() !== UPLOAD_ERR_NO_FILE) { continue; } unset($data[$field]); @@ -96,7 +95,7 @@ public function beforeSave(EventInterface $event, EntityInterface $entity, Array continue; } - if (empty($entity->get($field))) { + if (empty($entity->get($field)) || !$entity->isDirty($field)) { continue; } diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index a8706ad1..af6b6ddf 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -255,7 +255,7 @@ public function testBeforeMarshalEmptyAllowed() $this->assertEquals(new ArrayObject($this->dataError), $data); } - public function testBeforeSaveUploadError() + public function testBeforeSaveNoUpload() { $originalValue = rand(1000, 9999); @@ -277,16 +277,16 @@ public function testBeforeSaveUploadError() ->method('getOriginal') ->with('field') ->will($this->returnValue($originalValue)); - $this->entity->expects($this->once()) + $this->entity->expects($this->never()) ->method('set') ->with('field', $originalValue); - $this->entity->expects($this->once()) + $this->entity->expects($this->never()) ->method('setDirty') ->with('field', false); $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject())); } - public function testBeforeSaveWriteFail() + public function testBeforeSaveNoWrite() { $methods = array_diff($this->behaviorMethods, ['beforeSave', 'setConfig', 'getConfig']); $behavior = $this->getMockBuilder('Josegonzalez\Upload\Model\Behavior\UploadBehavior') @@ -311,7 +311,7 @@ public function testBeforeSaveWriteFail() ->method('write') ->will($this->returnValue([false])); - $this->assertFalse($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject())); + $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject())); } public function testBeforeSaveOk() From de416a9243971570dcdb0fbd0d8039de18453fe3 Mon Sep 17 00:00:00 2001 From: ADmad Date: Fri, 17 Apr 2020 17:58:34 +0530 Subject: [PATCH 28/40] Update docs --- docs/examples.rst | 36 +++++++++--------------------------- docs/index.rst | 6 ------ 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/docs/examples.rst b/docs/examples.rst index 5212375a..62a3eae6 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -35,11 +35,6 @@ Basic example $this->setDisplayField('username'); $this->setPrimaryKey('id'); - // for CakePHP 3.0.x-3.3.x, use the following lines instead of the previous: - // $this->table('users'); - // $this->displayField('username'); - // $this->primaryKey('id'); - $this->addBehavior('Josegonzalez/Upload.Upload', [ // You can configure as many upload fields as possible, // where the pattern is `field` => `config` @@ -65,9 +60,6 @@ Basic example Form->create($user, ['type' => 'file']); ?> Form->control('username'); ?> Form->control('photo', ['type' => 'file']); ?> - // for CakePHP 3.0.x-3.3.x, use the following lines instead of the previous: - // Form->input('username'); ?> - // Form->input('photo', ['type' => 'file']); ?> Form->end(); ?> Note: If you used *bake* to generate MVC structure after creating @@ -131,11 +123,6 @@ In order to prevent such situations, a field must be added to store the director $this->setDisplayField('username'); $this->setPrimaryKey('id'); - // for CakePHP 3.0.x-3.3.x, use the following lines instead of the previous: - // $this->table('users'); - // $this->displayField('username'); - // $this->primaryKey('id'); - $this->addBehavior('Josegonzalez/Upload.Upload', [ 'photo' => [ 'fields' => [ @@ -162,8 +149,8 @@ In order to prevent such situations, a field must be added to store the director ?> Form->create($user, ['type' => 'file']); ?> - Form->input('username'); ?> - Form->input('photo', ['type' => 'file']); ?> + Form->control('username'); ?> + Form->control('photo', ['type' => 'file']); ?> Form->end(); ?> Using such a setup, the behavior will use the stored path value instead of generating the path dynamically when deleting @@ -215,11 +202,6 @@ This example uses the Imagine library. It can be installed through composer: $this->setDisplayField('username'); $this->setPrimaryKey('id'); - // for CakePHP 3.0.x-3.3.x, use the following lines instead of the previous: - // $this->table('users'); - // $this->displayField('username'); - // $this->primaryKey('id'); - $this->addBehavior('Josegonzalez/Upload.Upload', [ 'photo' => [ 'fields' => [ @@ -230,8 +212,8 @@ This example uses the Imagine library. It can be installed through composer: 'nameCallback' => function ($table, $entity, $data, $field, $settings) { return strtolower($data['name']); }, - 'transformer' => function ($table, $entity, $data, $field, $settings) { - $extension = pathinfo($data['name'], PATHINFO_EXTENSION); + 'transformer' => function ($table, $entity, $data, $field, $settings, $filename) { + $extension = pathinfo($filename, PATHINFO_EXTENSION); // Store the thumbnail in a temporary file $tmp = tempnam(sys_get_temp_dir(), 'upload') . '.' . $extension; @@ -242,14 +224,14 @@ This example uses the Imagine library. It can be installed through composer: $imagine = new \Imagine\Gd\Imagine(); // Save that modified file to our temp file - $imagine->open($data['tmp_name']) + $imagine->open($this->data->getStream()->getMetadata('uri')) ->thumbnail($size, $mode) ->save($tmp); // Now return the original *and* the thumbnail return [ - $data['tmp_name'] => $data['name'], - $tmp => 'thumbnail-' . $data['name'], + $this->data->getStream()->getMetadata('uri') => $filename, + $tmp => 'thumbnail-' . $filename, ]; }, 'deleteCallback' => function ($path, $entity, $field, $settings) { @@ -277,8 +259,8 @@ This example uses the Imagine library. It can be installed through composer: */ ?> Form->create($user, ['type' => 'file']); ?> - Form->input('username'); ?> - Form->input('photo', ['type' => 'file']); ?> + Form->control('username'); ?> + Form->control('photo', ['type' => 'file']); ?> Form->end(); ?> Displaying links to files in your view diff --git a/docs/index.rst b/docs/index.rst index 034f08ca..24339604 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -7,12 +7,6 @@ Upload Plugin The Upload Plugin is an attempt to sanely upload files using techniques garnered from packages such as MeioUpload , UploadPack and PHP documentation. It uses the excellent `Flysystem ` library to handle file uploads, and can be easily integrated with any image library to handle thumbnail extraction to your exact specifications. -Requirements ------------- - -* CakePHP 3.x -* PHP 5.4+ - What does this plugin do? ------------------------- From 7cfda1b7e045ff7f2acb350ca6cdb4802ca85ee0 Mon Sep 17 00:00:00 2001 From: ADmad Date: Fri, 17 Apr 2020 18:07:51 +0530 Subject: [PATCH 29/40] Simply travis matrix --- .travis.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index cb8d6ac3..2745652a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: php php: - 7.2 - - 7.3 - 7.4 services: @@ -32,7 +31,7 @@ matrix: env: PREFER_LOWEST=1 before_script: - - if [[ $TRAVIS_PHP_VERSION != 7.3 ]]; then phpenv config-rm xdebug.ini; fi + - if [[ $TRAVIS_PHP_VERSION != 7.4 ]]; then phpenv config-rm xdebug.ini; fi - if [[ $PREFER_LOWEST != 1 ]]; then composer update --no-interaction; fi - if [[ $PREFER_LOWEST == 1 ]]; then composer update --no-interaction --prefer-lowest --prefer-stable; fi @@ -44,12 +43,12 @@ before_script: script: - | - if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.3 ]]; then + if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.4 ]]; then mkdir -p build/logs vendor/bin/phpunit --coverage-clover=build/logs/clover.xml fi - - if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION != 7.3 ]]; then vendor/bin/phpunit; fi + - if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION != 7.4 ]]; then vendor/bin/phpunit; fi - if [[ $PHPCS = 1 ]]; then vendor/bin/phpcs -n -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests; fi From 756c42a80c423f63fda2246d21feff9e1716c30d Mon Sep 17 00:00:00 2001 From: ADmad Date: Fri, 19 Jun 2020 22:52:14 +0530 Subject: [PATCH 30/40] Fix "undefined index" error. Closes #541 --- src/Model/Behavior/UploadBehavior.php | 4 +++- tests/TestCase/Model/Behavior/UploadBehaviorTest.php | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index e15128f2..a2cde4f7 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -75,7 +75,9 @@ public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObj if (!empty($dataArray[$field]) && $dataArray[$field]->getError() !== UPLOAD_ERR_NO_FILE) { continue; } - unset($data[$field]); + if (isset($data[$field])) { + unset($data[$field]); + } } } diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index 149afc0e..0c9f94e6 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -182,12 +182,12 @@ public function testInitializeAddBehaviorOptionsInterfaceConfig() public function testBeforeMarshalOk() { $validator = $this->getMockBuilder('Cake\Validation\Validator')->getMock(); - $validator->expects($this->once()) + $validator->expects($this->atLeastOnce()) ->method('isEmptyAllowed') ->will($this->returnValue(true)); $table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); - $table->expects($this->once()) + $table->expects($this->atLeastOnce()) ->method('getValidator') ->will($this->returnValue($validator)); @@ -203,6 +203,10 @@ public function testBeforeMarshalOk() $data = new ArrayObject($this->dataOk); $behavior->beforeMarshal(new Event('fake.event'), $data, new ArrayObject()); $this->assertEquals(new ArrayObject($this->dataOk), $data); + + $data = new ArrayObject(); + $behavior->beforeMarshal(new Event('fake.event'), $data, new ArrayObject()); + $this->assertEquals(new ArrayObject([]), $data); } public function testBeforeMarshalError() From d75e1e7208ec2927f7a3e4bb552594157409b84d Mon Sep 17 00:00:00 2001 From: ADmad Date: Mon, 26 Oct 2020 11:36:46 +0530 Subject: [PATCH 31/40] Fix example code. --- docs/examples.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/examples.rst b/docs/examples.rst index 62a3eae6..57f119ee 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -224,13 +224,13 @@ This example uses the Imagine library. It can be installed through composer: $imagine = new \Imagine\Gd\Imagine(); // Save that modified file to our temp file - $imagine->open($this->data->getStream()->getMetadata('uri')) + $imagine->open($data->getStream()->getMetadata('uri')) ->thumbnail($size, $mode) ->save($tmp); // Now return the original *and* the thumbnail return [ - $this->data->getStream()->getMetadata('uri') => $filename, + $data->getStream()->getMetadata('uri') => $filename, $tmp => 'thumbnail-' . $filename, ]; }, From 186c917abdb73dcf4b6955835a4800d2ecef1511 Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 27 Oct 2020 12:23:41 +0530 Subject: [PATCH 32/40] Fix CS errors --- src/File/Path/Basepath/DefaultTrait.php | 6 +++--- src/File/Writer/DefaultWriter.php | 2 +- tests/TestCase/File/Path/Basepath/DefaultTraitTest.php | 6 +++--- tests/TestCase/Validation/ImageValidationTest.php | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/File/Path/Basepath/DefaultTrait.php b/src/File/Path/Basepath/DefaultTrait.php index 3319e8d2..4a0c5c72 100644 --- a/src/File/Path/Basepath/DefaultTrait.php +++ b/src/File/Path/Basepath/DefaultTrait.php @@ -33,9 +33,9 @@ public function basepath(): string '{model}' => $this->table->getAlias(), '{table}' => $this->table->getTable(), '{field}' => $this->field, - '{year}' => date("Y"), - '{month}' => date("m"), - '{day}' => date("d"), + '{year}' => date('Y'), + '{month}' => date('m'), + '{day}' => date('d'), '{time}' => time(), '{microtime}' => microtime(true), '{DS}' => DIRECTORY_SEPARATOR, diff --git a/src/File/Writer/DefaultWriter.php b/src/File/Writer/DefaultWriter.php index 5fecf65e..d7087225 100644 --- a/src/File/Writer/DefaultWriter.php +++ b/src/File/Writer/DefaultWriter.php @@ -177,6 +177,6 @@ public function getFilesystem(string $field, array $settings = []): FilesystemIn ])); } - throw new UnexpectedValueException(sprintf("Invalid Adapter for field %s", $field)); + throw new UnexpectedValueException(sprintf('Invalid Adapter for field %s', $field)); } } diff --git a/tests/TestCase/File/Path/Basepath/DefaultTraitTest.php b/tests/TestCase/File/Path/Basepath/DefaultTraitTest.php index 92ea8a37..612d6a40 100644 --- a/tests/TestCase/File/Path/Basepath/DefaultTraitTest.php +++ b/tests/TestCase/File/Path/Basepath/DefaultTraitTest.php @@ -103,7 +103,7 @@ public function testYearWithMonthPath() $mock->data = ['name' => 'filename']; $mock->field = 'field'; - $this->assertEquals('webroot/files/' . date("Y") . '/' . date("m") . '/', $mock->basepath()); + $this->assertEquals('webroot/files/' . date('Y') . '/' . date('m') . '/', $mock->basepath()); } public function testYearWithMonthAndDayPath() @@ -115,7 +115,7 @@ public function testYearWithMonthAndDayPath() $mock->data = ['name' => 'filename']; $mock->field = 'field'; - $this->assertEquals('webroot/files/' . date("Y") . '/' . date("m") . '/' . date("d") . '/', $mock->basepath()); + $this->assertEquals('webroot/files/' . date('Y') . '/' . date('m') . '/' . date('d') . '/', $mock->basepath()); } public function testModelFieldYearWithMonthAndDayPath() @@ -130,7 +130,7 @@ public function testModelFieldYearWithMonthAndDayPath() $mock->entity->expects($this->exactly(0))->method('get')->will($this->returnValue(1)); $mock->table->expects($this->once())->method('getAlias')->will($this->returnValue('Table')); - $this->assertEquals('webroot/files/Table/field/' . date("Y") . '/' . date("m") . '/' . date("d") . '/', $mock->basepath()); + $this->assertEquals('webroot/files/Table/field/' . date('Y') . '/' . date('m') . '/' . date('d') . '/', $mock->basepath()); } public function testFieldValueMissing() diff --git a/tests/TestCase/Validation/ImageValidationTest.php b/tests/TestCase/Validation/ImageValidationTest.php index 0b6af1ea..d7762897 100644 --- a/tests/TestCase/Validation/ImageValidationTest.php +++ b/tests/TestCase/Validation/ImageValidationTest.php @@ -21,7 +21,7 @@ public function setUp(): void mkdir($this->vfs->path('/tmp')); // Write sample image with dimensions: 20x20 - $img = fopen($this->vfs->path('/tmp/tmpimage'), "wb"); + $img = fopen($this->vfs->path('/tmp/tmpimage'), 'wb'); fwrite($img, base64_decode('iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH4AMUECwX5I9GIwAAACFJREFUOMtj/P//PwM1ARMDlcGogaMGjho4auCogUPFQABpCwMlgqgSYAAAAABJRU5ErkJggg==')); fclose($img); From c9f9b99fe0547bc74dd9f19578ea46634dbc78d0 Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 27 Oct 2020 12:35:36 +0530 Subject: [PATCH 33/40] Fix errors reported by phpstan. --- .editorconfig | 5 +++- .travis.yml | 2 +- phpstan.neon | 31 +++++++++++++++---------- src/File/Path/Basepath/DefaultTrait.php | 3 +++ src/File/Path/Filename/DefaultTrait.php | 5 +++- src/Model/Behavior/UploadBehavior.php | 2 ++ 6 files changed, 33 insertions(+), 15 deletions(-) diff --git a/.editorconfig b/.editorconfig index bd0ddd7e..30202d3f 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,7 +1,7 @@ ; This file is for unifying the coding style for different editors and IDEs. ; More information at http://editorconfig.org -root = false +root = true [*] indent_style = space @@ -14,3 +14,6 @@ trim_trailing_whitespace = true [*.yml] indent_style = space indent_size = 2 + +[*.neon] +indent_style = tab diff --git a/.travis.yml b/.travis.yml index 2745652a..948c035c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,7 +52,7 @@ script: - if [[ $PHPCS = 1 ]]; then vendor/bin/phpcs -n -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests; fi - - if [[ $STATIC_ANALYSIS = 1 ]]; then vendor/bin/phpstan.phar analyse src/; fi + - if [[ $STATIC_ANALYSIS = 1 ]]; then vendor/bin/phpstan.phar analyse; fi after_success: - | diff --git a/phpstan.neon b/phpstan.neon index fe8ef2b5..4821d7b2 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,14 +1,21 @@ parameters: - level: 6 - checkMissingIterableValueType: false - checkGenericClassInNonGenericObjectType: false - ignoreErrors: - - - message: "#^Constant ROOT not found\\.$#" - count: 1 - path: src/File/Writer/DefaultWriter.php + level: 7 + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false + paths: + - src + ignoreErrors: + - + message: "#^Parameter \\#1 \\$field of method Cake\\\\Datasource\\\\EntityInterface\\:\\:get\\(\\) expects string, array\\\\|string given\\.$#" + count: 1 + path: src/File/Path/DefaultProcessor.php - - - message: "#^Cannot instantiate interface Josegonzalez\\\\Upload\\\\File\\\\Transformer\\\\TransformerInterface\\.$#" - count: 1 - path: src/Model/Behavior/UploadBehavior.php + - + message: "#^Constant ROOT not found\\.$#" + count: 1 + path: src/File/Writer/DefaultWriter.php + + - + message: "#^Cannot instantiate interface Josegonzalez\\\\Upload\\\\File\\\\Transformer\\\\TransformerInterface\\.$#" + count: 1 + path: src/Model/Behavior/UploadBehavior.php diff --git a/src/File/Path/Basepath/DefaultTrait.php b/src/File/Path/Basepath/DefaultTrait.php index 4a0c5c72..e6925278 100644 --- a/src/File/Path/Basepath/DefaultTrait.php +++ b/src/File/Path/Basepath/DefaultTrait.php @@ -6,6 +6,9 @@ use Cake\Utility\Hash; use LogicException; +/** + * @property \Cake\ORM\Table $table + */ trait DefaultTrait { /** diff --git a/src/File/Path/Filename/DefaultTrait.php b/src/File/Path/Filename/DefaultTrait.php index b5f9c8be..96828727 100644 --- a/src/File/Path/Filename/DefaultTrait.php +++ b/src/File/Path/Filename/DefaultTrait.php @@ -4,6 +4,8 @@ namespace Josegonzalez\Upload\File\Path\Filename; use Cake\Utility\Hash; +use Closure; +use ReflectionFunction; trait DefaultTrait { @@ -18,7 +20,8 @@ public function filename(): string { $processor = Hash::get($this->settings, 'nameCallback', null); if (is_callable($processor)) { - $numberOfParameters = (new \ReflectionFunction($processor))->getNumberOfParameters(); + $processor = Closure::fromCallable($processor); + $numberOfParameters = (new ReflectionFunction($processor))->getNumberOfParameters(); if ($numberOfParameters == 2) { return $processor($this->data, $this->settings); } diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index a2cde4f7..2296215c 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -50,6 +50,7 @@ public function initialize(array $config): void $this->setConfig('className', null); $schema = $this->_table->getSchema(); + /** @var string $field */ foreach (array_keys($this->getConfig()) as $field) { $schema->setColumnType($field, 'upload.file'); } @@ -68,6 +69,7 @@ public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObj { $validator = $this->_table->getValidator(); $dataArray = $data->getArrayCopy(); + /** @var string $field */ foreach (array_keys($this->getConfig(null, [])) as $field) { if (!$validator->isEmptyAllowed($field, false)) { continue; From 790b41bf6c4efc6e660ca8e51f5381f0e09da068 Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 27 Oct 2020 12:46:06 +0530 Subject: [PATCH 34/40] Remove backwards compatibility code. --- src/File/Path/Filename/DefaultTrait.php | 6 ------ tests/TestCase/File/Path/Filename/DefaultTraitTest.php | 9 --------- 2 files changed, 15 deletions(-) diff --git a/src/File/Path/Filename/DefaultTrait.php b/src/File/Path/Filename/DefaultTrait.php index 96828727..91ebfc51 100644 --- a/src/File/Path/Filename/DefaultTrait.php +++ b/src/File/Path/Filename/DefaultTrait.php @@ -20,12 +20,6 @@ public function filename(): string { $processor = Hash::get($this->settings, 'nameCallback', null); if (is_callable($processor)) { - $processor = Closure::fromCallable($processor); - $numberOfParameters = (new ReflectionFunction($processor))->getNumberOfParameters(); - if ($numberOfParameters == 2) { - return $processor($this->data, $this->settings); - } - return $processor($this->table, $this->entity, $this->data, $this->field, $this->settings); } diff --git a/tests/TestCase/File/Path/Filename/DefaultTraitTest.php b/tests/TestCase/File/Path/Filename/DefaultTraitTest.php index 11071f1e..32d55d8c 100644 --- a/tests/TestCase/File/Path/Filename/DefaultTraitTest.php +++ b/tests/TestCase/File/Path/Filename/DefaultTraitTest.php @@ -22,15 +22,6 @@ public function testFilename() $mock->data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'filename'); $this->assertEquals('filename', $mock->filename()); - $mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait'); - $mock->settings = [ - 'nameCallback' => function ($data, $settings) { - return $data->getClientFilename(); - }, - ]; - $mock->data = new UploadedFile(fopen('php://temp', 'wb+'), 150, UPLOAD_ERR_OK, 'filename'); - $this->assertEquals('filename', $mock->filename()); - $mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Filename\DefaultTrait'); $mock->entity = $this->getMockBuilder('Cake\ORM\Entity')->getMock(); $mock->table = $this->getMockBuilder('Cake\ORM\Table')->getMock(); From 2b0e781ec2cbff348f4a1d1f9d21fea013acffb2 Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 27 Oct 2020 13:47:35 +0530 Subject: [PATCH 35/40] Fix CS error --- src/File/Path/Filename/DefaultTrait.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/File/Path/Filename/DefaultTrait.php b/src/File/Path/Filename/DefaultTrait.php index 91ebfc51..379212ba 100644 --- a/src/File/Path/Filename/DefaultTrait.php +++ b/src/File/Path/Filename/DefaultTrait.php @@ -4,8 +4,6 @@ namespace Josegonzalez\Upload\File\Path\Filename; use Cake\Utility\Hash; -use Closure; -use ReflectionFunction; trait DefaultTrait { From 7fc65ea529fc854595c3da71e9dca732dbd43ef5 Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 27 Oct 2020 12:21:44 +0530 Subject: [PATCH 36/40] Skip processing in beforeSave() if value is not instance of UploadedFileInterface Refs #535 --- src/Model/Behavior/UploadBehavior.php | 9 +++++--- .../Model/Behavior/UploadBehaviorTest.php | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/Model/Behavior/UploadBehavior.php b/src/Model/Behavior/UploadBehavior.php index 2296215c..a98318b6 100644 --- a/src/Model/Behavior/UploadBehavior.php +++ b/src/Model/Behavior/UploadBehavior.php @@ -95,11 +95,15 @@ public function beforeMarshal(EventInterface $event, ArrayObject $data, ArrayObj public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) { foreach ($this->getConfig(null, []) as $field => $settings) { - if (in_array($field, $this->protectedFieldNames)) { + if ( + in_array($field, $this->protectedFieldNames, true) + || !$entity->isDirty($field) + ) { continue; } - if (empty($entity->get($field)) || !$entity->isDirty($field)) { + $data = $entity->get($field); + if (!$data instanceof UploadedFileInterface) { continue; } @@ -111,7 +115,6 @@ public function beforeSave(EventInterface $event, EntityInterface $entity, Array continue; } - $data = $entity->get($field); $path = $this->getPathProcessor($entity, $data, $field, $settings); $basepath = $path->basepath(); $filename = $path->filename(); diff --git a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php index 0c9f94e6..d4565429 100644 --- a/tests/TestCase/Model/Behavior/UploadBehaviorTest.php +++ b/tests/TestCase/Model/Behavior/UploadBehaviorTest.php @@ -383,6 +383,27 @@ public function testBeforeSaveWithProtectedFieldName() $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject())); } + public function testBeforeSaveWithFieldValueAsString() + { + $methods = array_diff($this->behaviorMethods, ['beforeSave', 'config', 'setConfig', 'getConfig']); + /** @var \Josegonzalez\Upload\Model\Behavior\UploadBehavior $behavior */ + $behavior = $this->getMockBuilder(UploadBehavior::class) + ->onlyMethods($methods) + ->setConstructorArgs([$this->table, $this->settings]) + ->getMock(); + + $this->entity->expects($this->any()) + ->method('get') + ->with('field') + ->will($this->returnValue('file.jpg')); + $this->entity->expects($this->any()) + ->method('isDirty') + ->with('field') + ->will($this->returnValue(true)); + + $this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject())); + } + public function testAfterDeleteOk() { $methods = array_diff($this->behaviorMethods, ['afterDelete', 'config', 'setConfig', 'getConfig']); From 954f5116a699cbdc3477bc67426d19b861be96e3 Mon Sep 17 00:00:00 2001 From: ADmad Date: Tue, 27 Oct 2020 17:54:13 +0530 Subject: [PATCH 37/40] Update docs --- README.md | 6 ++++-- docs/examples.rst | 38 +++++++++++++++++++++----------------- docs/index.rst | 5 ++++- docs/validation.rst | 2 +- 4 files changed, 30 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index 20edfc13..33a293a0 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,11 @@ # Upload Plugin -The Upload Plugin is an attempt to sanely upload files using techniques garnered from packages such as [MeioUpload](http://github.com/jrbasso/MeioUpload) , [UploadPack](http://github.com/szajbus/cakephp-uploadpack) and [PHP documentation](http://php.net/manual/en/features.file-upload.php). +The Upload Plugin is an attempt to easily handle file uploads with CakePHP. -See [this branch](https://github.com/FriendsOfCake/cakephp-upload/tree/2.x) for CakePHP 2.x documentation. +See [4.x branch](https://github.com/FriendsOfCake/cakephp-upload/tree/4.x) for CakePHP 3.x documentation. + +See [2.x branch](https://github.com/FriendsOfCake/cakephp-upload/tree/2.x) for CakePHP 2.x documentation. See [this blog post](http://josediazgonzalez.com/2015/12/05/uploading-files-and-images/) for a tutorial on using the 3.x version. diff --git a/docs/examples.rst b/docs/examples.rst index 57f119ee..02e2aa0a 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -23,13 +23,14 @@ Basic example In the present example, these changes would be made in: src/Model/Table/UsersTable.php */ + declare(strict_types=1); namespace App\Model\Table; use Cake\ORM\Table; class UsersTable extends Table { - public function initialize(array $config) + public function initialize(array $config): void { $this->setTable('users'); $this->setDisplayField('username'); @@ -57,17 +58,17 @@ Basic example src/Template/Users/edit.ctp */ ?> - Form->create($user, ['type' => 'file']); ?> - Form->control('username'); ?> - Form->control('photo', ['type' => 'file']); ?> - Form->end(); ?> + Form->create($user, ['type' => 'file']); ?> + Form->control('username'); ?> + Form->control('photo', ['type' => 'file']); ?> + Form->end(); ?> Note: If you used *bake* to generate MVC structure after creating the users table, you will need to remove the default scalar validation for the photos field. .. code:: php - public function validationDefault(Validator $validator) + public function validationDefault(Validator $validator): void { $validator ->integer('id') @@ -111,13 +112,14 @@ In order to prevent such situations, a field must be added to store the director In the present example, these changes would be made in: src/Model/Table/UsersTable.php */ + declare(strict_types=1); namespace App\Model\Table; use Cake\ORM\Table; class UsersTable extends Table { - public function initialize(array $config) + public function initialize(array $config): void { $this->setTable('users'); $this->setDisplayField('username'); @@ -148,10 +150,10 @@ In order to prevent such situations, a field must be added to store the director */ ?> - Form->create($user, ['type' => 'file']); ?> - Form->control('username'); ?> - Form->control('photo', ['type' => 'file']); ?> - Form->end(); ?> + Form->create($user, ['type' => 'file']); ?> + Form->control('username'); ?> + Form->control('photo', ['type' => 'file']); ?> + Form->end(); ?> Using such a setup, the behavior will use the stored path value instead of generating the path dynamically when deleting files. @@ -190,13 +192,14 @@ This example uses the Imagine library. It can be installed through composer: In the present example, these changes would be made in: src/Model/Table/UsersTable.php */ + declare(strict_types=1); namespace App\Model\Table; use Cake\ORM\Table; class UsersTable extends Table { - public function initialize(array $config) + public function initialize(array $config): void { $this->setTable('users'); $this->setDisplayField('username'); @@ -258,15 +261,16 @@ This example uses the Imagine library. It can be installed through composer: src/Template/Users/edit.ctp */ ?> - Form->create($user, ['type' => 'file']); ?> - Form->control('username'); ?> - Form->control('photo', ['type' => 'file']); ?> - Form->end(); ?> + Form->create($user, ['type' => 'file']); ?> + Form->control('username'); ?> + Form->control('photo', ['type' => 'file']); ?> + Form->end(); ?> Displaying links to files in your view -------------------------------------- -Once your files have been uploaded you can link to them using the ``HtmlHelper`` by specifying the path and using the file information from the database. +Once your files have been uploaded you can link to them using the ``HtmlHelper`` +by specifying the path and using the file information from the database. This example uses the `default behaviour configuration `__ using the model ``Example``. diff --git a/docs/index.rst b/docs/index.rst index 24339604..95e8074d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -5,7 +5,10 @@ Introduction Upload Plugin ============= -The Upload Plugin is an attempt to sanely upload files using techniques garnered from packages such as MeioUpload , UploadPack and PHP documentation. It uses the excellent `Flysystem ` library to handle file uploads, and can be easily integrated with any image library to handle thumbnail extraction to your exact specifications. +The Upload Plugin is an attempt to easily handle file uploads with CakePHP. +It uses the excellent `Flysystem ` library +to handle file uploads, and can be easily integrated with any image library to +handle thumbnail extraction to your exact specifications. What does this plugin do? ------------------------- diff --git a/docs/validation.rst b/docs/validation.rst index fff67db0..69cf7005 100644 --- a/docs/validation.rst +++ b/docs/validation.rst @@ -59,7 +59,7 @@ It might come in handy to only use a validation rule when there actually is an u ?> -More information on conditional validation can be found `here `__. +More information on conditional validation can be found `here `__. UploadValidation ---------------- From f09370ba28597662efda13ec58f5943fed592c21 Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 2 Dec 2020 17:36:24 +0530 Subject: [PATCH 38/40] Update dependencies. --- composer.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 0d2b9eb1..14a3e7bf 100644 --- a/composer.json +++ b/composer.json @@ -12,14 +12,14 @@ } ], "require": { - "cakephp/cakephp": "^4.0.2", - "league/flysystem": "*" + "cakephp/orm": "^4.0.2", + "league/flysystem": "^1.0" }, "require-dev": { + "cakephp/cakephp": "^4.0.2", "phpunit/phpunit": "~8.5.0", "league/flysystem-vfs": "*", - "cakephp/cakephp-codesniffer": "^4.0", - "phpstan/phpstan": "^0.12" + "cakephp/cakephp-codesniffer": "^4.0" }, "autoload": { "psr-4": { From 1e9ae9fb2f3e66696f2b686885a3524aa62748eb Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 2 Dec 2020 17:45:23 +0530 Subject: [PATCH 39/40] Add github actions workflow for CI --- .gitattributes | 11 +++++ .github/workflows/ci.yml | 94 ++++++++++++++++++++++++++++++++++++++++ .travis.yml | 66 ---------------------------- README.md | 4 +- 4 files changed, 107 insertions(+), 68 deletions(-) create mode 100644 .gitattributes create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..797f418b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# Remove files for archives generated using `git archive` +CONTRIBUTING.md export-ignore +.editorconfig export-ignore +.gitattributes export-ignore +.gitignore export-ignore +phpunit.xml.dist export-ignore +.scrutinizer.yml export-ignore +.stickler.yml export-ignore +tests export-ignore +docs export-ignore +.github export-ignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..3a6ef617 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,94 @@ +name: CI + +on: [push, pull_request] + +jobs: + testsuite: + runs-on: ubuntu-18.04 + strategy: + fail-fast: false + matrix: + php-version: ['7.2', '7.4'] + db-type: [sqlite, mysql, pgsql] + prefer-lowest: [''] + include: + - php-version: '7.2' + db-type: 'sqlite' + prefer-lowest: 'prefer-lowest' + + services: + postgres: + image: postgres + ports: + - 5432:5432 + env: + POSTGRES_PASSWORD: postgres + + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + + - name: Setup Service + if: matrix.db-type == 'mysql' + run: | + sudo service mysql start + mysql -h 127.0.0.1 -u root -proot -e 'CREATE DATABASE cakephp;' + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: mbstring, intl, pdo_${{ matrix.db-type }} + coverage: pcov + + - name: Composer install + run: | + if ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then + composer update --prefer-lowest --prefer-stable + else + composer install + fi + + - name: Run PHPUnit + run: | + if [[ ${{ matrix.db-type }} == 'sqlite' ]]; then export DB_URL='sqlite:///:memory:'; fi + if [[ ${{ matrix.db-type }} == 'mysql' ]]; then export DB_URL='mysql://root:root@127.0.0.1/cakephp'; fi + if [[ ${{ matrix.db-type }} == 'pgsql' ]]; then export DB_URL='postgres://postgres:postgres@127.0.0.1/postgres'; fi + + if [[ ${{ matrix.php-version }} == '7.4' && ${{ matrix.db-type }} == 'sqlite' ]]; then + vendor/bin/phpunit --coverage-clover=coverage.xml + else + vendor/bin/phpunit + fi + + - name: Code Coverage Report + if: success() && matrix.php-version == '7.4' && matrix.db-type == 'sqlite' + uses: codecov/codecov-action@v1 + + cs-stan: + name: Coding Standard & Static Analysis + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '7.4' + extension: mbstring, intl + coverage: none + tools: cs2pr, phpstan:^0.12 + + - name: Composer Install + run: composer install + + - name: Run phpcs + run: vendor/bin/phpcs --report=checkstyle --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/ | cs2pr + + - name: Run phpstan + if: success() || failure() + run: phpstan analyse diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 948c035c..00000000 --- a/.travis.yml +++ /dev/null @@ -1,66 +0,0 @@ -language: php - -php: - - 7.2 - - 7.4 - -services: - - mysql - - postgresql - -env: - matrix: - - DB=mysql db_dsn='mysql://root@127.0.0.1/cakephp_test' - - DB=pgsql db_dsn='postgres://postgres@127.0.0.1/cakephp_test' - - DB=sqlite db_dsn='sqlite:///:memory:' - - global: - - DEFAULT=1 - -matrix: - fast_finish: true - - include: - - php: 7.2 - env: PHPCS=1 DEFAULT=0 - - - php: 7.2 - env: STATIC_ANALYSIS=1 DEFAULT=0 - - - php: 7.2 - env: PREFER_LOWEST=1 - -before_script: - - if [[ $TRAVIS_PHP_VERSION != 7.4 ]]; then phpenv config-rm xdebug.ini; fi - - - if [[ $PREFER_LOWEST != 1 ]]; then composer update --no-interaction; fi - - if [[ $PREFER_LOWEST == 1 ]]; then composer update --no-interaction --prefer-lowest --prefer-stable; fi - - - if [[ $DB = 'mysql' ]]; then mysql -e 'CREATE DATABASE cakephp_test;'; fi - - if [[ $DB = 'pgsql' ]]; then psql -c 'CREATE DATABASE cakephp_test;' -U postgres; fi - - - if [[ $STATIC_ANALYSIS = 1 ]]; then composer require --dev phpstan/phpstan:^0.12; fi - -script: - - | - if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.4 ]]; then - mkdir -p build/logs - vendor/bin/phpunit --coverage-clover=build/logs/clover.xml - fi - - - if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION != 7.4 ]]; then vendor/bin/phpunit; fi - - - if [[ $PHPCS = 1 ]]; then vendor/bin/phpcs -n -p --extensions=php --standard=vendor/cakephp/cakephp-codesniffer/CakePHP ./src ./tests; fi - - - if [[ $STATIC_ANALYSIS = 1 ]]; then vendor/bin/phpstan.phar analyse; fi - -after_success: - - | - if [[ $DEFAULT = 1 && $TRAVIS_PHP_VERSION = 7.2 ]]; then - wget https://github.com/php-coveralls/php-coveralls/releases/download/v2.1.0/php-coveralls.phar - chmod +x php-coveralls.phar - ./php-coveralls.phar - fi - -notifications: - email: false diff --git a/README.md b/README.md index 33a293a0..5792bd01 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -[![Build Status](https://img.shields.io/travis/FriendsOfCake/cakephp-upload/master.svg?style=flat-square)](https://travis-ci.org/FriendsOfCake/cakephp-upload) -[![Coverage Status](https://img.shields.io/coveralls/FriendsOfCake/cakephp-upload.svg?style=flat-square)](https://coveralls.io/r/FriendsOfCake/cakephp-upload?branch=master) +[![Build Status](https://img.shields.io/github/workflow/status/FriendsOfCake/cakephp-upload/CI/master?style=flat-square)](https://github.com/FriendsOfCake/cakephp-upload/actions?query=workflow%3ACI+branch%3Amaster) +[![Coverage Status](https://img.shields.io/codecov/c/github/FriendsOfCake/cakephp-upload.svg?style=flat-square)](https://codecov.io/github/FriendsOfCake/cakephp-upload) [![Total Downloads](https://img.shields.io/packagist/dt/josegonzalez/cakephp-upload.svg?style=flat-square)](https://packagist.org/packages/josegonzalez/cakephp-upload) [![Latest Stable Version](https://img.shields.io/packagist/v/josegonzalez/cakephp-upload.svg?style=flat-square)](https://packagist.org/packages/josegonzalez/cakephp-upload) [![Documentation Status](https://readthedocs.org/projects/cakephp-upload/badge/?version=latest&style=flat-square)](https://readthedocs.org/projects/cakephp-upload/?badge=latest) From 15eabf8fe9bdaeb50de12176c6b41a7f213ca6bd Mon Sep 17 00:00:00 2001 From: ADmad Date: Wed, 2 Dec 2020 17:55:59 +0530 Subject: [PATCH 40/40] Update docs --- docs/examples.rst | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/examples.rst b/docs/examples.rst index 02e2aa0a..e6fc3e89 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -54,8 +54,8 @@ Basic example Form->create($user, ['type' => 'file']); ?> @@ -72,15 +72,15 @@ Basic example { $validator ->integer('id') - ->allowEmpty('id', 'create'); + ->allowEmptyString('id', 'create'); $validator ->scalar('username') - ->allowEmpty('username'); + ->allowEmptyString('username'); $validator // remove ->scalar('photo') - ->allowEmpty('photo'); + ->allowEmptyFile('photo'); return $validator; } @@ -145,8 +145,8 @@ In order to prevent such situations, a field must be added to store the director @@ -257,8 +257,8 @@ This example uses the Imagine library. It can be installed through composer: Form->create($user, ['type' => 'file']); ?> @@ -279,8 +279,8 @@ This example uses the `default behaviour configuration `__ u