From e59b50aa259322871c17f33a71f87c76603fa1a1 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 18:35:35 +0200 Subject: [PATCH 01/41] Upgraded laravel to ^8.0 upgraded symfony/yaml to ^5.1 replaced october\rain import with winter\storm import --- .buildpath | 29 +++++++++++++++++++ .project | 28 ++++++++++++++++++ .settings/org.eclipse.php.core.prefs | 2 ++ ....eclipse.wst.common.project.facet.core.xml | 7 +++++ composer.json | 4 +-- tests/Database/RelationsTest.php | 2 +- 6 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 .buildpath create mode 100644 .project create mode 100644 .settings/org.eclipse.php.core.prefs create mode 100644 .settings/org.eclipse.wst.common.project.facet.core.xml diff --git a/.buildpath b/.buildpath new file mode 100644 index 000000000..239d01791 --- /dev/null +++ b/.buildpath @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 000000000..e76842aea --- /dev/null +++ b/.project @@ -0,0 +1,28 @@ + + + wintercms-storm + + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + org.eclipse.wst.validation.validationbuilder + + + + + org.eclipse.dltk.core.scriptbuilder + + + + + + org.eclipse.php.core.PHPNature + org.eclipse.wst.common.project.facet.core.nature + + diff --git a/.settings/org.eclipse.php.core.prefs b/.settings/org.eclipse.php.core.prefs new file mode 100644 index 000000000..bb9e3c2a2 --- /dev/null +++ b/.settings/org.eclipse.php.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +include_path=0;/wintercms-storm diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml new file mode 100644 index 000000000..e077e20d7 --- /dev/null +++ b/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/composer.json b/composer.json index 9c81953a1..19c7adc72 100644 --- a/composer.json +++ b/composer.json @@ -39,11 +39,11 @@ "linkorb/jsmin-php": "~1.0", "wikimedia/less.php": "~3.0", "scssphp/scssphp": "~1.0", - "symfony/yaml": "^3.4", + "symfony/yaml": "^5.1", "twig/twig": "~2.0", "league/csv": "~9.1", "nesbot/carbon": "^2.0", - "laravel/framework": "~6.0", + "laravel/framework": "^8.0", "laravel/tinker": "~2.0" }, "require-dev": { diff --git a/tests/Database/RelationsTest.php b/tests/Database/RelationsTest.php index 93a1a854e..81a8914eb 100644 --- a/tests/Database/RelationsTest.php +++ b/tests/Database/RelationsTest.php @@ -262,7 +262,7 @@ protected function seedTables() } } -class Category extends \October\Rain\Database\Model +class Category extends \Winter\Storm\Database\Model { public $table = 'categories'; From 4fa71da421bef8f2432daf0cf53d55c904fa9100 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 18:37:28 +0200 Subject: [PATCH 02/41] Updated composer.json to ignore eclipse files --- .buildpath | 29 ------------------- .gitignore | 7 ++++- .project | 28 ------------------ .settings/org.eclipse.php.core.prefs | 2 -- ....eclipse.wst.common.project.facet.core.xml | 7 ----- 5 files changed, 6 insertions(+), 67 deletions(-) delete mode 100644 .buildpath delete mode 100644 .project delete mode 100644 .settings/org.eclipse.php.core.prefs delete mode 100644 .settings/org.eclipse.wst.common.project.facet.core.xml diff --git a/.buildpath b/.buildpath deleted file mode 100644 index 239d01791..000000000 --- a/.buildpath +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/.gitignore b/.gitignore index 97fa7e856..678c82384 100644 --- a/.gitignore +++ b/.gitignore @@ -9,4 +9,9 @@ composer.lock # Other files .DS_Store -php_errors.log \ No newline at end of file +php_errors.log + +#eclipse +/.buildpath +/.project +/.settings/ \ No newline at end of file diff --git a/.project b/.project deleted file mode 100644 index e76842aea..000000000 --- a/.project +++ /dev/null @@ -1,28 +0,0 @@ - - - wintercms-storm - - - - - - org.eclipse.wst.common.project.facet.core.builder - - - - - org.eclipse.wst.validation.validationbuilder - - - - - org.eclipse.dltk.core.scriptbuilder - - - - - - org.eclipse.php.core.PHPNature - org.eclipse.wst.common.project.facet.core.nature - - diff --git a/.settings/org.eclipse.php.core.prefs b/.settings/org.eclipse.php.core.prefs deleted file mode 100644 index bb9e3c2a2..000000000 --- a/.settings/org.eclipse.php.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -include_path=0;/wintercms-storm diff --git a/.settings/org.eclipse.wst.common.project.facet.core.xml b/.settings/org.eclipse.wst.common.project.facet.core.xml deleted file mode 100644 index e077e20d7..000000000 --- a/.settings/org.eclipse.wst.common.project.facet.core.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - From d570980f9ab8282e5c2fa6e8c191e967830479ae Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 18:40:24 +0200 Subject: [PATCH 03/41] Updated requirement to php 7.4 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 19c7adc72..de9c8d977 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": ">=7.2.9", + "php": ">=7.4", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", From ad9f2eaa26ae4f4cf856d86c4764f2da4b9d42fb Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 19:17:46 +0200 Subject: [PATCH 04/41] Removed Storm QueryBuilder as typehint, as this invalidates the method signature contract from parent class Illuminate Query Builder. Typehints from child classes may not change the typehint from parent classes. https://softwareengineering.stackexchange.com/a/274262/85227 --- src/Database/Query/Grammars/MySqlGrammar.php | 7 ++++--- src/Database/Query/Grammars/PostgresGrammar.php | 6 +++--- src/Database/Query/Grammars/SQLiteGrammar.php | 6 +++--- src/Database/Query/Grammars/SqlServerGrammar.php | 6 +++--- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/Database/Query/Grammars/MySqlGrammar.php b/src/Database/Query/Grammars/MySqlGrammar.php index 0b9501089..1399789fd 100644 --- a/src/Database/Query/Grammars/MySqlGrammar.php +++ b/src/Database/Query/Grammars/MySqlGrammar.php @@ -1,9 +1,10 @@ compileInsert($query, $values) . ' on duplicate key update '; diff --git a/src/Database/Query/Grammars/PostgresGrammar.php b/src/Database/Query/Grammars/PostgresGrammar.php index 2b8a167c3..a66d9c377 100644 --- a/src/Database/Query/Grammars/PostgresGrammar.php +++ b/src/Database/Query/Grammars/PostgresGrammar.php @@ -1,6 +1,6 @@ compileInsert($query, $values); diff --git a/src/Database/Query/Grammars/SQLiteGrammar.php b/src/Database/Query/Grammars/SQLiteGrammar.php index 942612e1f..c8ba85018 100644 --- a/src/Database/Query/Grammars/SQLiteGrammar.php +++ b/src/Database/Query/Grammars/SQLiteGrammar.php @@ -1,6 +1,6 @@ compileInsert($query, $values); diff --git a/src/Database/Query/Grammars/SqlServerGrammar.php b/src/Database/Query/Grammars/SqlServerGrammar.php index ac70ec53c..39c6064ca 100644 --- a/src/Database/Query/Grammars/SqlServerGrammar.php +++ b/src/Database/Query/Grammars/SqlServerGrammar.php @@ -1,6 +1,6 @@ columnize(array_keys(reset($values))); From ae9c706cb210b1b018bca3cf49d52d66edb073e0 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 19:19:40 +0200 Subject: [PATCH 05/41] Removed typehint for setKeySForSaveQuery as that invalidates the parent method signature --- src/Database/Pivot.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Pivot.php b/src/Database/Pivot.php index 5172b7df2..665c402ef 100644 --- a/src/Database/Pivot.php +++ b/src/Database/Pivot.php @@ -68,10 +68,10 @@ public function __construct(ModelBase $parent, $attributes, $table, $exists = fa /** * Set the keys for a save update query. * - * @param \Illuminate\Database\Eloquent\Builder + * @param \Illuminate\Database\Eloquent\Builder $query * @return \Illuminate\Database\Eloquent\Builder */ - protected function setKeysForSaveQuery(BuilderBase $query) + protected function setKeysForSaveQuery($query) { $query->where($this->foreignKey, $this->getAttribute($this->foreignKey)); From bb35db7fa5c9e40ca4b185f6e7a882c22a52a699 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 19:22:06 +0200 Subject: [PATCH 06/41] Fixed import path, should have been Query instead of Eloquent --- src/Database/Query/Grammars/PostgresGrammar.php | 2 +- src/Database/Query/Grammars/SQLiteGrammar.php | 2 +- src/Database/Query/Grammars/SqlServerGrammar.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Database/Query/Grammars/PostgresGrammar.php b/src/Database/Query/Grammars/PostgresGrammar.php index a66d9c377..a3d2fd388 100644 --- a/src/Database/Query/Grammars/PostgresGrammar.php +++ b/src/Database/Query/Grammars/PostgresGrammar.php @@ -1,6 +1,6 @@ Date: Sun, 25 Apr 2021 19:22:42 +0200 Subject: [PATCH 07/41] Fixed import path, should have been Query instead of Eloquent --- src/Database/Query/Grammars/MySqlGrammar.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Database/Query/Grammars/MySqlGrammar.php b/src/Database/Query/Grammars/MySqlGrammar.php index 1399789fd..5c667c58e 100644 --- a/src/Database/Query/Grammars/MySqlGrammar.php +++ b/src/Database/Query/Grammars/MySqlGrammar.php @@ -1,6 +1,6 @@ Date: Sun, 25 Apr 2021 19:25:23 +0200 Subject: [PATCH 08/41] Added default value null to to make the method signature compatible with the parent class --- src/Events/Dispatcher.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index 1d55250ca..1a742b9e7 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -30,7 +30,7 @@ class Dispatcher extends BaseDispatcher * @param int $priority * @return void */ - public function listen($events, $listener, $priority = 0) + public function listen($events, $listener = null, $priority = 0) { foreach ((array) $events as $event) { if (Str::contains($event, '*')) { From c146ccf5831346ecfc796f2250cceefa79b0df90 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 19:28:26 +0200 Subject: [PATCH 09/41] Changed Exception to Throwable to make the methods compatible with parent class --- src/Foundation/Exception/Handler.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Foundation/Exception/Handler.php b/src/Foundation/Exception/Handler.php index e14052fef..1355793cf 100644 --- a/src/Foundation/Exception/Handler.php +++ b/src/Foundation/Exception/Handler.php @@ -38,10 +38,10 @@ class Handler extends ExceptionHandler * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * - * @param \Exception $exception + * @param \Throwable $exception * @return void */ - public function report(Exception $exception) + public function report(\Throwable $exception) { /** * @event exception.beforeReport @@ -84,10 +84,10 @@ public function report(Exception $exception) * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request - * @param \Exception $exception + * @param \Throwable $exception * @return \Illuminate\Http\Response */ - public function render($request, Exception $exception) + public function render($request, Throwable $exception) { $statusCode = $this->getStatusCode($exception); $response = $this->callCustomHandlers($exception); From 639e6fe404b3a2f133c1bf3266603f2cb400c64c Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 19:34:27 +0200 Subject: [PATCH 10/41] Transport manager was changed in Mail Manager in laravel 7. --- src/Mail/TransportManager.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mail/TransportManager.php b/src/Mail/TransportManager.php index 800542061..a380415e8 100644 --- a/src/Mail/TransportManager.php +++ b/src/Mail/TransportManager.php @@ -1,6 +1,6 @@ Date: Sun, 25 Apr 2021 19:38:47 +0200 Subject: [PATCH 11/41] Added a todo note --- src/Mail/TransportManager.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Mail/TransportManager.php b/src/Mail/TransportManager.php index a380415e8..ea794f797 100644 --- a/src/Mail/TransportManager.php +++ b/src/Mail/TransportManager.php @@ -4,6 +4,10 @@ use Winter\Storm\Mail\Transport\MandrillTransport; use Winter\Storm\Mail\Transport\SparkPostTransport; +/** + * @TODO check if this needs to be changed based on the change from TransportManager to MailManager + * See https://laravel.com/docs/7.x/releases#laravel-7 "Multiple Mail Drivers" + */ class TransportManager extends BaseTransportManager { /** From d5ec7d9ddc62eabba1623163e8b9bb6301882dd9 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 20:17:08 +0200 Subject: [PATCH 12/41] Changed the use of the encrypter variable as it is a static variable in the parent class. --- src/Database/Traits/Encryptable.php | 9 ++++++--- tests/Database/Traits/EncryptableTest.php | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Database/Traits/Encryptable.php b/src/Database/Traits/Encryptable.php index 4218243f5..419a57d64 100644 --- a/src/Database/Traits/Encryptable.php +++ b/src/Database/Traits/Encryptable.php @@ -14,7 +14,7 @@ trait Encryptable /** * @var \Illuminate\Contracts\Encryption\Encrypter Encrypter instance. */ - protected $encrypter; + protected $encrypterInstance; /** * @var array List of original attribute values before they were encrypted. @@ -108,7 +108,10 @@ public function getOriginalEncryptableValue($attribute) */ public function getEncrypter() { - return (!is_null($this->encrypter)) ? $this->encrypter : App::make('encrypter'); + if(is_null(self::$encrypter)) { + $this->setEncrypter(App::make('encrypter')); + } + return self::$encrypter; } /** @@ -119,6 +122,6 @@ public function getEncrypter() */ public function setEncrypter(\Illuminate\Contracts\Encryption\Encrypter $encrypter) { - $this->encrypter = $encrypter; + parent::encryptUsing($encrypter); } } diff --git a/tests/Database/Traits/EncryptableTest.php b/tests/Database/Traits/EncryptableTest.php index c68c849ae..109796cf8 100644 --- a/tests/Database/Traits/EncryptableTest.php +++ b/tests/Database/Traits/EncryptableTest.php @@ -22,7 +22,7 @@ public function setUp(): void public function testEncryptableTrait() { $testModel = new TestModelEncryptable(); - $testModel->setEncrypter($this->encrypter); + $testModel->encryptUsing($this->encrypter); $testModel->fill(['secret' => 'test']); $this->assertEquals('test', $testModel->secret); From db15860a5340ca0f973664459c28d8111774c193 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 20:30:47 +0200 Subject: [PATCH 13/41] added a name to the Mailer constructor Moved getDatabasename to the setMethods() space Removed the variable from the Encryptable trait --- tests/.phpunit.result.cache | 1 + tests/Database/QueryBuilderTest.php | 4 +--- tests/Mail/MailerTest.php | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) create mode 100644 tests/.phpunit.result.cache diff --git a/tests/.phpunit.result.cache b/tests/.phpunit.result.cache new file mode 100644 index 000000000..6d57ab20b --- /dev/null +++ b/tests/.phpunit.result.cache @@ -0,0 +1 @@ +C:37:"PHPUnit\Runner\DefaultTestResultCache":14023:{a:2:{s:7:"defects";a:1:{s:49:"PathResolverTest::testWithOpenBaseDirRestrictions";i:1;}s:5:"times";a:270:{s:38:"StylesheetMinifyTest::testSpaceRemoval";d:0.002;s:44:"StylesheetMinifyTest::testEmptyClassPreserve";d:0;s:52:"StylesheetMinifyTest::testSpecialCommentPreservation";d:0;s:40:"StylesheetMinifyTest::testCommentRemoval";d:0;s:50:"StylesheetMinifyTest::testCommentPreservationInVar";d:0;s:47:"StylesheetMinifyTest::testUnitPreservationInVar";d:0;s:52:"StylesheetMinifyTest::testAttributeSelectorsWithLess";d:0;s:29:"ConfigTest::testGetFileConfig";d:0;s:34:"ConfigTest::testGetNamespaceConfig";d:0;s:41:"ConfigTest::testGetAliasedNamespaceConfig";d:0;s:28:"ConfigWriterTest::testToFile";d:0.005;s:31:"ConfigWriterTest::testToContent";d:0.002;s:22:"ResizerTest::testReset";d:0.013;s:26:"ResizerTest::testResize0x0";d:0.008;s:27:"ResizerTest::testResize20x0";d:0.001;s:27:"ResizerTest::testResize0x20";d:0.001;s:37:"ResizerTest::testResizeAutoPortrait50";d:0.002;s:38:"ResizerTest::testResizeAutoLandscape25";d:0.001;s:38:"ResizerTest::testResizeAutoSquare25x50";d:0.003;s:38:"ResizerTest::testResizeAutoSquare50x25";d:0.003;s:38:"ResizerTest::testResizeAutoSquare50x50";d:0.003;s:39:"ResizerTest::testResizeAutoLandscape1x1";d:0.008;s:39:"ResizerTest::testResizeAutoLandscape1x5";d:0.001;s:40:"ResizerTest::testResizeAutoLandscape25x1";d:0.001;s:33:"ResizerTest::testResizeExact10x15";d:0.001;s:36:"ResizerTest::testResizeLandscape10x1";d:0.001;s:35:"ResizerTest::testResizePortrait1x10";d:0.001;s:47:"ResizerTest::testResizeSaveBackgroundColor32x32";d:0.002;s:35:"ResizerTest::testResizeIndex300x255";d:0.068;s:40:"ResizerTest::testResizeFitLandscape30x30";d:0.001;s:39:"ResizerTest::testResizeFitPortrait30x30";d:0.001;s:37:"ResizerTest::testResizeFitSquare50x50";d:0.003;s:43:"ResizerTest::testResizeAutoExifRotated30x30";d:0.001;s:24:"ResizerTest::testSharpen";d:0.001;s:26:"ResizerTest::testCrop10x15";d:0.001;s:39:"PurgeableTest::testDirectImplementation";d:0;s:54:"PurgeableTest::testDirectImplementationWithoutProperty";d:0;s:40:"PurgeableTest::testDynamicImplementation";d:0;s:55:"PurgeableTest::testDynamicImplementationWithoutProperty";d:0;s:52:"HasRelationshipsTest::testGetRelationTypeDefinitions";d:0;s:59:"HasRelationshipsTest::testDynamicGetRelationTypeDefinitions";d:0;s:51:"HasRelationshipsTest::testGetRelationTypeDefinition";d:0;s:58:"HasRelationshipsTest::testDynamicGetRelationTypeDefinition";d:0;s:33:"DongleTest::testSqliteParseConcat";d:0;s:38:"DongleTest::testSqliteParseGroupConcat";d:0;s:37:"DongleTest::testPgsqlParseGroupConcat";d:0;s:38:"DongleTest::testSqlSrvParseGroupConcat";d:0;s:44:"DongleTest::testSqliteParseBooleanExpression";d:0;s:33:"DongleTest::testSqlSrvParseIfNull";d:0;s:32:"DongleTest::testPgSrvParseIfNull";d:0;s:23:"ModelTest::testAddCasts";d:0.015;s:24:"ModelTest::testIsGuarded";d:0.002;s:50:"ModelTest::testMassAssignmentOnFieldsNotInDatabase";d:0.005;s:34:"QueryBuilderTest::testSelectConcat";d:0.005;s:28:"QueryBuilderTest::testUpsert";d:0.001;s:45:"QueryBuilderTest::testUpsertWithUpdateColumns";d:0;s:37:"RelationsTest::testBelongsToManyCount";d:0.013;s:39:"RelationsTest::testBelongsToManySyncAll";d:0.011;s:40:"RelationsTest::testBelongsToManySyncTags";d:0.012;s:38:"RelationsTest::testBelongsToManyDetach";d:0.01;s:44:"RelationsTest::testBelongsToManyDetachOneTag";d:0.01;s:50:"RelationsTest::testBelongsToManyDetachAllWithScope";d:0.01;s:28:"RelationsTest::testPivotData";d:0.011;s:24:"RelationsTest::testTerms";d:0.015;s:42:"RelationsTest::testUndefinedMorphsRelation";d:0.009;s:40:"RelationsTest::testDefinedMorphsRelation";d:0.009;s:45:"SortableTest::testOrderByIsAutomaticallyAdded";d:0.002;s:40:"SortableTest::testOrderByCanBeOverridden";d:0.002;s:37:"EncryptableTest::testEncryptableTrait";d:0.003;s:33:"PurgeableTraitTest::testPurgeable";d:0.004;s:33:"SluggableTest::testSlugGeneration";d:0.008;s:43:"SluggableTest::testSlugGenerationSoftDelete";d:0.006;s:48:"SluggableTest::testSlugGenerationSoftDeleteAllow";d:0.005;s:49:"SluggableTest::testSlugGenerationWithSoftDeletion";d:0.011;s:47:"SluggableTest::testSlugGenerationWithHardDelete";d:0.012;s:26:"ValidationTest::testUnique";d:0;s:35:"ValidationTest::testArrayFieldNames";d:0;s:45:"UpdaterTest::testClassNameGetsParsedCorrectly";d:0;s:44:"ExtendableTest::testExtendingExtendableClass";d:0;s:50:"ExtendableTest::testSettingDeclaredPropertyOnClass";d:0;s:52:"ExtendableTest::testSettingUndeclaredPropertyOnClass";d:0;s:53:"ExtendableTest::testSettingDeclaredPropertyOnBehavior";d:0;s:42:"ExtendableTest::testDynamicPropertyOnClass";d:0;s:45:"ExtendableTest::testDynamicallyExtendingClass";d:0;s:40:"ExtendableTest::testDynamicMethodOnClass";d:0;s:49:"ExtendableTest::testDynamicExtendAndMethodOnClass";d:0;s:41:"ExtendableTest::testDynamicClosureOnClass";d:0;s:42:"ExtendableTest::testDynamicCallableOnClass";d:0;s:39:"ExtendableTest::testCallingStaticMethod";d:0;s:48:"ExtendableTest::testCallingUndefinedStaticMethod";d:0;s:46:"ExtendableTest::testAccessingProtectedProperty";d:0;s:44:"ExtendableTest::testAccessingProtectedMethod";d:0;s:50:"ExtendableTest::testAccessingProtectedStaticMethod";d:0;s:41:"ExtendableTest::testInvalidImplementValue";d:0;s:37:"ExtendableTest::testSoftImplementFake";d:0;s:37:"ExtendableTest::testSoftImplementReal";d:0;s:38:"ExtendableTest::testSoftImplementCombo";d:0;s:31:"ExtendableTest::testDotNotation";d:0;s:32:"ExtendableTest::testMethodExists";d:0;s:35:"ExtendableTest::testMethodNotExists";d:0;s:39:"ExtendableTest::testDynamicMethodExists";d:0;s:35:"ExtendableTest::testGetClassMethods";d:0;s:36:"ExtensionTest::testExtendingBehavior";d:0;s:33:"PathResolverTest::testDirectPaths";d:0;s:35:"PathResolverTest::testRelativePaths";d:0;s:47:"PathResolverTest::testRelativeToWorkingDirPaths";d:0;s:38:"PathResolverTest::testAbsoluteSymlinks";d:0;s:38:"PathResolverTest::testRelativeSymlinks";d:0;s:37:"PathResolverTest::testWithinDirectory";d:0.001;s:49:"PathResolverTest::testWithOpenBaseDirRestrictions";d:0;s:32:"ApplicationTest::testPathMethods";d:0.001;s:35:"ApplicationTest::testSetPathMethods";d:0;s:40:"CheckForTrustedHostTest::testTrustedHost";d:0.002;s:52:"CheckForTrustedHostTest::testTrustedHostWwwSubdomain";d:0;s:59:"CheckForTrustedHostTest::testTrustedHostWwwSubdomainFailure";d:0;s:48:"CheckForTrustedHostTest::testTrustedHostWwwRegex";d:0;s:42:"CheckForTrustedHostTest::testTrustedIpHost";d:0;s:46:"CheckForTrustedHostTest::testNoTrustedHostsSet";d:0;s:60:"CheckForTrustedHostTest::testThrowExceptionForUntrustedHosts";d:0;s:65:"CheckForTrustedHostTest::testThrowExceptionForUntrustedServerName";d:0;s:65:"CheckForTrustedHostTest::testThrowExceptionForUntrustedServerAddr";d:0;s:45:"CheckForTrustedHostTest::testRegexTrustedHost";d:0;s:49:"CheckForTrustedHostTest::testRegexFailTrustedHost";d:0;s:45:"CheckForTrustedHostTest::testArrayTrustedHost";d:0;s:49:"CheckForTrustedHostTest::testArrayFailTrustedHost";d:0;s:37:"DatasourceResolverTest::testConstruct";d:0;s:45:"DatasourceResolverTest::testDefaultDatasource";d:0;s:29:"HalcyonModelTest::testFindAll";d:0.001;s:30:"HalcyonModelTest::testFindPage";d:0;s:30:"HalcyonModelTest::testFindMenu";d:0;s:41:"HalcyonModelTest::testOtherDatasourcePage";d:0;s:32:"HalcyonModelTest::testCreatePage";d:0.001;s:32:"HalcyonModelTest::testCreateMenu";d:0.001;s:47:"HalcyonModelTest::testCreatePageInDirectoryPass";d:0.001;s:47:"HalcyonModelTest::testCreatePageInDirectoryFail";d:0;s:32:"HalcyonModelTest::testUpdatePage";d:0.006;s:42:"HalcyonModelTest::testUpdatePageRenameFile";d:0.002;s:46:"HalcyonModelTest::testUpdatePageRenameFileCase";d:0.002;s:50:"HalcyonModelTest::testUpdateContentRenameExtension";d:0.002;s:42:"HalcyonModelTest::testUpdatePageFileExists";d:0.001;s:32:"HalcyonModelTest::testDeletePage";d:0.001;s:40:"HalcyonModelTest::testPageWithValidation";d:0.001;s:50:"HalcyonModelTest::testPageWithNestedValidationFail";d:0;s:50:"HalcyonModelTest::testPageWithNestedValidationPass";d:0.001;s:43:"HalcyonModelTest::testPageQueryListFileName";d:0.001;s:39:"HalcyonModelTest::testAddDynamicPoperty";d:0.002;s:85:"MemoryRepositoryTest::testItemsAreRetrievedFromMemoryCacheBeforeCheckingExternalCache";d:0;s:99:"MemoryRepositoryTest::testItemsCanBeRetrievedFromExternalCacheAndRetrievedFromMemoryCacheAfterwards";d:0;s:51:"MemoryRepositoryTest::testItemsArePutIntoBothCaches";d:0;s:63:"MemoryRepositoryTest::testMemoryCacheCanStoreAndGetFalseyValues";d:0;s:73:"MemoryRepositoryTest::testBothCachesAreIncrementedAndDecrementedCorrectly";d:0;s:46:"MemoryRepositoryTest::testBothCachesForgetKeys";d:0;s:55:"MemoryRepositoryTest::testBothCachesAreFlushedCorrectly";d:0;s:28:"SectionParserTest::testParse";d:0;s:34:"SectionParserTest::testParseOffset";d:0;s:40:"ValidationTraitTest::testArrayFieldNames";d:0;s:30:"BlockBuilderTest::testPutBlock";d:0;s:30:"BlockBuilderTest::testSetBlock";d:0;s:33:"BlockBuilderTest::testAppendBlock";d:0;s:38:"BlockBuilderTest::testPlaceholderBlock";d:0;s:33:"BlockBuilderTest::testResetBlocks";d:0;s:34:"BlockBuilderTest::testNestedBlocks";d:0;s:42:"BlockBuilderTest::testContainBetweenBlocks";d:0;s:26:"HtmlBuilderTest::testStrip";d:0;s:26:"HtmlBuilderTest::testLimit";d:0;s:34:"HtmlBuilderTest::testLimitEncoding";d:0;s:26:"HtmlBuilderTest::testClean";d:0;s:28:"HtmlHelperTest::testNameToId";d:0;s:31:"HtmlHelperTest::testNameToArray";d:0;s:33:"MailerTest::testProcessRecipients";d:0;s:36:"HttpTest::testSetOptionsViaConstants";d:0.001;s:34:"HttpTest::testSetOptionsViaStrings";d:0;s:35:"HttpTest::testSetOptionsViaIntegers";d:0;s:39:"HttpTest::testSetInvalidOptionViaString";d:0;s:40:"HttpTest::testSetInvalidOptionViaInteger";d:0;s:43:"HttpTest::testSetOptionsViaArrayOfConstants";d:0;s:42:"HttpTest::testSetOptionsViaArrayOfIntegers";d:0;s:41:"HttpTest::testSetOptionsViaArrayOfStrings";d:0;s:47:"HttpTest::testSetInvalidOptionViaArrayOfStrings";d:0;s:48:"HttpTest::testSetInvalidOptionViaArrayOfIntegers";d:0;s:28:"HttpTest::testSetRequestData";d:0;s:33:"HttpTest::testSetRequestDataArray";d:0;s:27:"HttpTest::testSetPostFields";d:0;s:43:"HttpTest::testRequestDataOverridePostFields";d:0;s:33:"BracketTest::testParseCombination";d:0;s:31:"BracketTest::testParseSingleKey";d:0;s:32:"BracketTest::testParseLoopingKey";d:0;s:33:"BracketTest::testParseWithFilters";d:0;s:18:"IniTest::testBasic";d:0;s:18:"IniTest::testArray";d:0;s:19:"IniTest::testObject";d:0;s:21:"IniTest::testComments";d:0;s:20:"IniTest::testComplex";d:0;s:29:"IniTest::testMultilinesValues";d:0;s:19:"IniTest::testRender";d:0;s:32:"SyntaxFieldParserTest::testParse";d:0;s:42:"SyntaxFieldParserTest::testParseWithPrefix";d:0;s:53:"SyntaxFieldParserTest::testParseJsTriggerApiAttribute";d:0;s:48:"SyntaxFieldParserTest::testParseDropdownAndRadio";d:0;s:43:"SyntaxFieldParserTest::testParseColorPicker";d:0;s:40:"SyntaxFieldParserTest::testParseRepeater";d:0;s:37:"SyntaxFieldParserTest::testProcessTag";d:0;s:43:"SyntaxFieldParserTest::testProcessTagsRegex";d:0;s:45:"SyntaxFieldParserTest::testProcessParamsRegex";d:0;s:33:"SyntaxParserTest::testParseToTwig";d:0;s:41:"SyntaxParserTest::testParseRepeaterToTwig";d:0;s:33:"SyntaxParserTest::testParseToView";d:0;s:41:"SyntaxParserTest::testParseRepeaterToView";d:0;s:33:"SyntaxParserTest::testParseToEdit";d:0;s:35:"SyntaxParserTest::testParseToRender";d:0;s:43:"SyntaxParserTest::testParseRepeaterToRender";d:0;s:35:"SyntaxParserTest::testParseVariable";d:0;s:41:"SyntaxParserTest::testParseVariableToEdit";d:0;s:49:"SyntaxParserTest::testParseDropDownVariableToEdit";d:0;s:68:"SyntaxParserTest::testParseDropDownVariableToEditInvalidKeyException";d:0;s:77:"SyntaxParserTest::testParseDropDownVariableToEditInvalidStaticMethodException";d:0;s:35:"YamlTest::testParseWithoutProcessor";d:0.003;s:35:"YamlTest::testParseWithPreProcessor";d:0;s:46:"YamlTest::testParseWithPreProcessorTemporarily";d:0;s:36:"YamlTest::testParseWithPostProcessor";d:0;s:39:"RouterHelperTest::testSegmentIsOptional";d:0;s:41:"RouterHelperTest::testParameterNameMethod";d:0;s:35:"RouterHelperTest::testSegmentRegexp";d:0;s:34:"RouterHelperTest::testDefaultValue";d:0;s:39:"RouterHelperTest::testReplaceParameters";d:0;s:26:"RouterTest::testResolveUrl";d:0;s:21:"RouterTest::testMatch";d:0;s:19:"RouterTest::testUrl";d:0;s:33:"ScaffoldBaseTest::testProcessVars";d:0.001;s:21:"ArrTest::testArrClass";d:0;s:19:"ArrTest::testHelper";d:0;s:33:"ClassLoaderTest::testClassesExist";d:0;s:28:"ClassLoaderTest::testAliases";d:0;s:37:"ClassLoaderTest::testNamespaceAliases";d:0;s:28:"CountableTest::testCountable";d:0;s:21:"EmitterTest::testBind";d:0;s:25:"EmitterTest::testBindOnce";d:0;s:28:"EmitterTest::testUnbindEvent";d:0;s:26:"EmitterTest::testFireEvent";d:0;s:32:"EmitterTest::testFireEventResult";d:0;s:29:"EmitterTest::testBindPriority";d:0;s:23:"EventFakeTest::testFire";d:0;s:27:"HelpersTest::testConfigPath";d:0.005;s:28:"HelpersTest::testPluginsPath";d:0;s:27:"HelpersTest::testThemesPath";d:0;s:25:"HelpersTest::testTempPath";d:0;s:28:"HelpersTest::testUploadsPath";d:0;s:26:"HelpersTest::testMediaPath";d:0;s:22:"MailFakeTest::testSend";d:0;s:23:"MailFakeTest::testQueue";d:0;s:35:"MailFakeTest::testIndexedArrayViews";d:0;s:33:"MailFakeTest::testNamedArrayViews";d:0;s:42:"MailFakeTest::testIndexedArrayViews_Queued";d:0;s:40:"MailFakeTest::testNamedArrayViews_Queued";d:0;s:31:"UrlGeneratorTest::testSimpleUrl";d:0;s:32:"UrlGeneratorTest::testComplexUrl";d:0;s:34:"UrlGeneratorTest::testReplacements";d:0;s:34:"UrlGeneratorTest::testJoinSegments";d:0;s:35:"UrlGeneratorTest::testStripSegments";d:0;s:39:"TranslatorTest::testSimilarWordsParsing";d:0;s:26:"TranslatorTest::testChoice";d:0.001;s:35:"TranslatorTest::testChoiceSublocale";d:0;s:50:"TranslatorTest::testOverrideWithBeforeResolveEvent";d:0.001;s:37:"TranslatorTest::testNamespaceAliasing";d:0;s:46:"TranslatorTest::testMixedCaseNamespaceAliasing";d:0;s:38:"EmailValidationTest::testDefaultFilter";d:0.001;s:34:"EmailValidationTest::testRFCFilter";d:0.001;s:30:"RuleObjectTest::testRuleObject";d:0;s:36:"RuleObjectTest::testRuleObjectPasses";d:0;s:47:"RuleObjectTest::testRuleObjectTranslatedMessage";d:0;}}} \ No newline at end of file diff --git a/tests/Database/QueryBuilderTest.php b/tests/Database/QueryBuilderTest.php index 67554578e..ed39a11ad 100644 --- a/tests/Database/QueryBuilderTest.php +++ b/tests/Database/QueryBuilderTest.php @@ -210,9 +210,7 @@ protected function getConnection($connection = null) 'rollBack', 'transactionLevel', 'pretend', - ]) - ->addMethods([ - 'getDatabaseName', + 'getDatabaseName' ]) ->getMock(); diff --git a/tests/Mail/MailerTest.php b/tests/Mail/MailerTest.php index a12de01f1..d166fc3c5 100644 --- a/tests/Mail/MailerTest.php +++ b/tests/Mail/MailerTest.php @@ -101,7 +101,7 @@ public function testProcessRecipients() protected function makeMailer() { - return new Mailer(new FactoryMailerTest, new SwiftMailerTest, new DispatcherMailerTest); + return new Mailer("TestMailer", new FactoryMailerTest, new SwiftMailerTest, new DispatcherMailerTest); } } From c0bd7667a32bfe9754988dcb8575f394f50b0548 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 20:32:42 +0200 Subject: [PATCH 14/41] Removed variable --- src/Database/Traits/Encryptable.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Database/Traits/Encryptable.php b/src/Database/Traits/Encryptable.php index 419a57d64..c6f73fb95 100644 --- a/src/Database/Traits/Encryptable.php +++ b/src/Database/Traits/Encryptable.php @@ -11,11 +11,6 @@ trait Encryptable * protected $encryptable = []; */ - /** - * @var \Illuminate\Contracts\Encryption\Encrypter Encrypter instance. - */ - protected $encrypterInstance; - /** * @var array List of original attribute values before they were encrypted. */ From 18db743c69e16c6dcbaf4a2cd471f23cf7251978 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 25 Apr 2021 20:37:48 +0200 Subject: [PATCH 15/41] Resolving merge conficts --- composer.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/composer.json b/composer.json index e644d5ab0..de9c8d977 100644 --- a/composer.json +++ b/composer.json @@ -39,11 +39,7 @@ "linkorb/jsmin-php": "~1.0", "wikimedia/less.php": "~3.0", "scssphp/scssphp": "~1.0", -<<<<<<< HEAD "symfony/yaml": "^5.1", -======= - "symfony/yaml": "^4.4", ->>>>>>> 553365b50dba7042a578e4e7bb6b8094787416db "twig/twig": "~2.0", "league/csv": "~9.1", "nesbot/carbon": "^2.0", From 4999eda47d1d6cc2758a57fe7ab06246192737f9 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 26 Apr 2021 19:31:57 +0200 Subject: [PATCH 16/41] Set php version to 7.3 as laravel 8 only requires that. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index de9c8d977..a9a614516 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": ">=7.4", + "php": ">=7.3", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", From a10f1a8bbf74f2a05556978601839fe405a414a9 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 26 Apr 2021 19:34:02 +0200 Subject: [PATCH 17/41] Fixed code style issues --- src/Database/Query/Grammars/MySqlGrammar.php | 1 - src/Database/Traits/Encryptable.php | 2 +- src/Events/Dispatcher.php | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Database/Query/Grammars/MySqlGrammar.php b/src/Database/Query/Grammars/MySqlGrammar.php index 5c667c58e..b3ef61b6e 100644 --- a/src/Database/Query/Grammars/MySqlGrammar.php +++ b/src/Database/Query/Grammars/MySqlGrammar.php @@ -4,7 +4,6 @@ use Illuminate\Database\Query\Grammars\MySqlGrammar as BaseMysqlGrammer; use Winter\Storm\Database\Query\Grammars\Concerns\SelectConcatenations; - class MySqlGrammar extends BaseMysqlGrammer { use SelectConcatenations; diff --git a/src/Database/Traits/Encryptable.php b/src/Database/Traits/Encryptable.php index c6f73fb95..982378a14 100644 --- a/src/Database/Traits/Encryptable.php +++ b/src/Database/Traits/Encryptable.php @@ -103,7 +103,7 @@ public function getOriginalEncryptableValue($attribute) */ public function getEncrypter() { - if(is_null(self::$encrypter)) { + if (is_null(self::$encrypter)) { $this->setEncrypter(App::make('encrypter')); } return self::$encrypter; diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index 1a742b9e7..55ce6a39b 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -30,7 +30,7 @@ class Dispatcher extends BaseDispatcher * @param int $priority * @return void */ - public function listen($events, $listener = null, $priority = 0) + public function listen($events, $listener = null, $priority = 0) { foreach ((array) $events as $event) { if (Str::contains($event, '*')) { From 6286f1577b3aa69f9fd50751aafdd8608af31dc5 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 26 Apr 2021 19:53:28 +0200 Subject: [PATCH 18/41] Removed backports of compileUpsert in SQL grammars --- .editorconfig | 7 --- src/Database/Query/Grammars/MySqlGrammar.php | 23 ---------- .../Query/Grammars/PostgresGrammar.php | 25 ----------- src/Database/Query/Grammars/SQLiteGrammar.php | 25 ----------- .../Query/Grammars/SqlServerGrammar.php | 43 ------------------- 5 files changed, 123 deletions(-) delete mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index b9afb3d3b..000000000 --- a/.editorconfig +++ /dev/null @@ -1,7 +0,0 @@ -[*] -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true -indent_style = space -indent_size = 4 diff --git a/src/Database/Query/Grammars/MySqlGrammar.php b/src/Database/Query/Grammars/MySqlGrammar.php index b3ef61b6e..5964e8b8f 100644 --- a/src/Database/Query/Grammars/MySqlGrammar.php +++ b/src/Database/Query/Grammars/MySqlGrammar.php @@ -1,32 +1,9 @@ compileInsert($query, $values) . ' on duplicate key update '; - - $columns = collect($update)->map(function ($value, $key) { - return is_numeric($key) - ? $this->wrap($value) . ' = values(' . $this->wrap($value) . ')' - : $this->wrap($key) . ' = ' . $this->parameter($value); - })->implode(', '); - - return $sql . $columns; - } } diff --git a/src/Database/Query/Grammars/PostgresGrammar.php b/src/Database/Query/Grammars/PostgresGrammar.php index a3d2fd388..58ad779ec 100644 --- a/src/Database/Query/Grammars/PostgresGrammar.php +++ b/src/Database/Query/Grammars/PostgresGrammar.php @@ -1,34 +1,9 @@ compileInsert($query, $values); - - $sql .= ' on conflict (' . $this->columnize($uniqueBy) . ') do update set '; - - $columns = collect($update)->map(function ($value, $key) { - return is_numeric($key) - ? $this->wrap($value) . ' = ' . $this->wrapValue('excluded') . '.' . $this->wrap($value) - : $this->wrap($key) . ' = ' . $this->parameter($value); - })->implode(', '); - - return $sql . $columns; - } } diff --git a/src/Database/Query/Grammars/SQLiteGrammar.php b/src/Database/Query/Grammars/SQLiteGrammar.php index 987823431..4cf7fb76f 100644 --- a/src/Database/Query/Grammars/SQLiteGrammar.php +++ b/src/Database/Query/Grammars/SQLiteGrammar.php @@ -1,6 +1,5 @@ wrap($as); } - - /** - * Compile an "upsert" statement into SQL. - * - * @param \Illuminate\Database\Eloquent\Builder $query - * @param array $values - * @param array $uniqueBy - * @param array $update - * @return string - */ - public function compileUpsert(Builder $query, array $values, array $uniqueBy, array $update) - { - $sql = $this->compileInsert($query, $values); - - $sql .= ' on conflict (' . $this->columnize($uniqueBy) . ') do update set '; - - $columns = collect($update)->map(function ($value, $key) { - return is_numeric($key) - ? $this->wrap($value) . ' = ' . $this->wrapValue('excluded') . '.' . $this->wrap($value) - : $this->wrap($key) . ' = ' . $this->parameter($value); - })->implode(', '); - - return $sql . $columns; - } } diff --git a/src/Database/Query/Grammars/SqlServerGrammar.php b/src/Database/Query/Grammars/SqlServerGrammar.php index 8e654cf79..17cb26c97 100644 --- a/src/Database/Query/Grammars/SqlServerGrammar.php +++ b/src/Database/Query/Grammars/SqlServerGrammar.php @@ -1,52 +1,9 @@ columnize(array_keys(reset($values))); - - $sql = 'merge ' . $this->wrapTable($query->from) . ' '; - - $parameters = collect($values)->map(function ($record) { - return '(' . $this->parameterize($record) . ')'; - })->implode(', '); - - $sql .= 'using (values ' . $parameters . ') ' . $this->wrapTable('laravel_source') . ' (' . $columns . ') '; - - $on = collect($uniqueBy)->map(function ($column) use ($query) { - return $this->wrap('laravel_source.' . $column) . ' = ' . $this->wrap($query->from . '.' . $column); - })->implode(' and '); - - $sql .= 'on ' . $on . ' '; - - if ($update) { - $update = collect($update)->map(function ($value, $key) { - return is_numeric($key) - ? $this->wrap($value) . ' = ' . $this->wrap('laravel_source.' . $value) - : $this->wrap($key) . ' = ' . $this->parameter($value); - })->implode(', '); - - $sql .= 'when matched then update set ' . $update . ' '; - } - - $sql .= 'when not matched then insert (' . $columns . ') values (' . $columns . ')'; - - return $sql; - } } From fe6b88319f5b29b72351a918d2d19647ab39ac7a Mon Sep 17 00:00:00 2001 From: = Date: Mon, 26 Apr 2021 20:00:55 +0200 Subject: [PATCH 19/41] Removed phpunit result cache and added it to the gitignore --- .gitignore | 6 +++++- tests/.phpunit.result.cache | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) delete mode 100644 tests/.phpunit.result.cache diff --git a/.gitignore b/.gitignore index 678c82384..87a01f2d4 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,10 @@ composer.lock php_errors.log #eclipse +/.editorconfig /.buildpath /.project -/.settings/ \ No newline at end of file +/.settings/ + +#phpunit +tests/.phpunit.result.cache diff --git a/tests/.phpunit.result.cache b/tests/.phpunit.result.cache deleted file mode 100644 index 6d57ab20b..000000000 --- a/tests/.phpunit.result.cache +++ /dev/null @@ -1 +0,0 @@ -C:37:"PHPUnit\Runner\DefaultTestResultCache":14023:{a:2:{s:7:"defects";a:1:{s:49:"PathResolverTest::testWithOpenBaseDirRestrictions";i:1;}s:5:"times";a:270:{s:38:"StylesheetMinifyTest::testSpaceRemoval";d:0.002;s:44:"StylesheetMinifyTest::testEmptyClassPreserve";d:0;s:52:"StylesheetMinifyTest::testSpecialCommentPreservation";d:0;s:40:"StylesheetMinifyTest::testCommentRemoval";d:0;s:50:"StylesheetMinifyTest::testCommentPreservationInVar";d:0;s:47:"StylesheetMinifyTest::testUnitPreservationInVar";d:0;s:52:"StylesheetMinifyTest::testAttributeSelectorsWithLess";d:0;s:29:"ConfigTest::testGetFileConfig";d:0;s:34:"ConfigTest::testGetNamespaceConfig";d:0;s:41:"ConfigTest::testGetAliasedNamespaceConfig";d:0;s:28:"ConfigWriterTest::testToFile";d:0.005;s:31:"ConfigWriterTest::testToContent";d:0.002;s:22:"ResizerTest::testReset";d:0.013;s:26:"ResizerTest::testResize0x0";d:0.008;s:27:"ResizerTest::testResize20x0";d:0.001;s:27:"ResizerTest::testResize0x20";d:0.001;s:37:"ResizerTest::testResizeAutoPortrait50";d:0.002;s:38:"ResizerTest::testResizeAutoLandscape25";d:0.001;s:38:"ResizerTest::testResizeAutoSquare25x50";d:0.003;s:38:"ResizerTest::testResizeAutoSquare50x25";d:0.003;s:38:"ResizerTest::testResizeAutoSquare50x50";d:0.003;s:39:"ResizerTest::testResizeAutoLandscape1x1";d:0.008;s:39:"ResizerTest::testResizeAutoLandscape1x5";d:0.001;s:40:"ResizerTest::testResizeAutoLandscape25x1";d:0.001;s:33:"ResizerTest::testResizeExact10x15";d:0.001;s:36:"ResizerTest::testResizeLandscape10x1";d:0.001;s:35:"ResizerTest::testResizePortrait1x10";d:0.001;s:47:"ResizerTest::testResizeSaveBackgroundColor32x32";d:0.002;s:35:"ResizerTest::testResizeIndex300x255";d:0.068;s:40:"ResizerTest::testResizeFitLandscape30x30";d:0.001;s:39:"ResizerTest::testResizeFitPortrait30x30";d:0.001;s:37:"ResizerTest::testResizeFitSquare50x50";d:0.003;s:43:"ResizerTest::testResizeAutoExifRotated30x30";d:0.001;s:24:"ResizerTest::testSharpen";d:0.001;s:26:"ResizerTest::testCrop10x15";d:0.001;s:39:"PurgeableTest::testDirectImplementation";d:0;s:54:"PurgeableTest::testDirectImplementationWithoutProperty";d:0;s:40:"PurgeableTest::testDynamicImplementation";d:0;s:55:"PurgeableTest::testDynamicImplementationWithoutProperty";d:0;s:52:"HasRelationshipsTest::testGetRelationTypeDefinitions";d:0;s:59:"HasRelationshipsTest::testDynamicGetRelationTypeDefinitions";d:0;s:51:"HasRelationshipsTest::testGetRelationTypeDefinition";d:0;s:58:"HasRelationshipsTest::testDynamicGetRelationTypeDefinition";d:0;s:33:"DongleTest::testSqliteParseConcat";d:0;s:38:"DongleTest::testSqliteParseGroupConcat";d:0;s:37:"DongleTest::testPgsqlParseGroupConcat";d:0;s:38:"DongleTest::testSqlSrvParseGroupConcat";d:0;s:44:"DongleTest::testSqliteParseBooleanExpression";d:0;s:33:"DongleTest::testSqlSrvParseIfNull";d:0;s:32:"DongleTest::testPgSrvParseIfNull";d:0;s:23:"ModelTest::testAddCasts";d:0.015;s:24:"ModelTest::testIsGuarded";d:0.002;s:50:"ModelTest::testMassAssignmentOnFieldsNotInDatabase";d:0.005;s:34:"QueryBuilderTest::testSelectConcat";d:0.005;s:28:"QueryBuilderTest::testUpsert";d:0.001;s:45:"QueryBuilderTest::testUpsertWithUpdateColumns";d:0;s:37:"RelationsTest::testBelongsToManyCount";d:0.013;s:39:"RelationsTest::testBelongsToManySyncAll";d:0.011;s:40:"RelationsTest::testBelongsToManySyncTags";d:0.012;s:38:"RelationsTest::testBelongsToManyDetach";d:0.01;s:44:"RelationsTest::testBelongsToManyDetachOneTag";d:0.01;s:50:"RelationsTest::testBelongsToManyDetachAllWithScope";d:0.01;s:28:"RelationsTest::testPivotData";d:0.011;s:24:"RelationsTest::testTerms";d:0.015;s:42:"RelationsTest::testUndefinedMorphsRelation";d:0.009;s:40:"RelationsTest::testDefinedMorphsRelation";d:0.009;s:45:"SortableTest::testOrderByIsAutomaticallyAdded";d:0.002;s:40:"SortableTest::testOrderByCanBeOverridden";d:0.002;s:37:"EncryptableTest::testEncryptableTrait";d:0.003;s:33:"PurgeableTraitTest::testPurgeable";d:0.004;s:33:"SluggableTest::testSlugGeneration";d:0.008;s:43:"SluggableTest::testSlugGenerationSoftDelete";d:0.006;s:48:"SluggableTest::testSlugGenerationSoftDeleteAllow";d:0.005;s:49:"SluggableTest::testSlugGenerationWithSoftDeletion";d:0.011;s:47:"SluggableTest::testSlugGenerationWithHardDelete";d:0.012;s:26:"ValidationTest::testUnique";d:0;s:35:"ValidationTest::testArrayFieldNames";d:0;s:45:"UpdaterTest::testClassNameGetsParsedCorrectly";d:0;s:44:"ExtendableTest::testExtendingExtendableClass";d:0;s:50:"ExtendableTest::testSettingDeclaredPropertyOnClass";d:0;s:52:"ExtendableTest::testSettingUndeclaredPropertyOnClass";d:0;s:53:"ExtendableTest::testSettingDeclaredPropertyOnBehavior";d:0;s:42:"ExtendableTest::testDynamicPropertyOnClass";d:0;s:45:"ExtendableTest::testDynamicallyExtendingClass";d:0;s:40:"ExtendableTest::testDynamicMethodOnClass";d:0;s:49:"ExtendableTest::testDynamicExtendAndMethodOnClass";d:0;s:41:"ExtendableTest::testDynamicClosureOnClass";d:0;s:42:"ExtendableTest::testDynamicCallableOnClass";d:0;s:39:"ExtendableTest::testCallingStaticMethod";d:0;s:48:"ExtendableTest::testCallingUndefinedStaticMethod";d:0;s:46:"ExtendableTest::testAccessingProtectedProperty";d:0;s:44:"ExtendableTest::testAccessingProtectedMethod";d:0;s:50:"ExtendableTest::testAccessingProtectedStaticMethod";d:0;s:41:"ExtendableTest::testInvalidImplementValue";d:0;s:37:"ExtendableTest::testSoftImplementFake";d:0;s:37:"ExtendableTest::testSoftImplementReal";d:0;s:38:"ExtendableTest::testSoftImplementCombo";d:0;s:31:"ExtendableTest::testDotNotation";d:0;s:32:"ExtendableTest::testMethodExists";d:0;s:35:"ExtendableTest::testMethodNotExists";d:0;s:39:"ExtendableTest::testDynamicMethodExists";d:0;s:35:"ExtendableTest::testGetClassMethods";d:0;s:36:"ExtensionTest::testExtendingBehavior";d:0;s:33:"PathResolverTest::testDirectPaths";d:0;s:35:"PathResolverTest::testRelativePaths";d:0;s:47:"PathResolverTest::testRelativeToWorkingDirPaths";d:0;s:38:"PathResolverTest::testAbsoluteSymlinks";d:0;s:38:"PathResolverTest::testRelativeSymlinks";d:0;s:37:"PathResolverTest::testWithinDirectory";d:0.001;s:49:"PathResolverTest::testWithOpenBaseDirRestrictions";d:0;s:32:"ApplicationTest::testPathMethods";d:0.001;s:35:"ApplicationTest::testSetPathMethods";d:0;s:40:"CheckForTrustedHostTest::testTrustedHost";d:0.002;s:52:"CheckForTrustedHostTest::testTrustedHostWwwSubdomain";d:0;s:59:"CheckForTrustedHostTest::testTrustedHostWwwSubdomainFailure";d:0;s:48:"CheckForTrustedHostTest::testTrustedHostWwwRegex";d:0;s:42:"CheckForTrustedHostTest::testTrustedIpHost";d:0;s:46:"CheckForTrustedHostTest::testNoTrustedHostsSet";d:0;s:60:"CheckForTrustedHostTest::testThrowExceptionForUntrustedHosts";d:0;s:65:"CheckForTrustedHostTest::testThrowExceptionForUntrustedServerName";d:0;s:65:"CheckForTrustedHostTest::testThrowExceptionForUntrustedServerAddr";d:0;s:45:"CheckForTrustedHostTest::testRegexTrustedHost";d:0;s:49:"CheckForTrustedHostTest::testRegexFailTrustedHost";d:0;s:45:"CheckForTrustedHostTest::testArrayTrustedHost";d:0;s:49:"CheckForTrustedHostTest::testArrayFailTrustedHost";d:0;s:37:"DatasourceResolverTest::testConstruct";d:0;s:45:"DatasourceResolverTest::testDefaultDatasource";d:0;s:29:"HalcyonModelTest::testFindAll";d:0.001;s:30:"HalcyonModelTest::testFindPage";d:0;s:30:"HalcyonModelTest::testFindMenu";d:0;s:41:"HalcyonModelTest::testOtherDatasourcePage";d:0;s:32:"HalcyonModelTest::testCreatePage";d:0.001;s:32:"HalcyonModelTest::testCreateMenu";d:0.001;s:47:"HalcyonModelTest::testCreatePageInDirectoryPass";d:0.001;s:47:"HalcyonModelTest::testCreatePageInDirectoryFail";d:0;s:32:"HalcyonModelTest::testUpdatePage";d:0.006;s:42:"HalcyonModelTest::testUpdatePageRenameFile";d:0.002;s:46:"HalcyonModelTest::testUpdatePageRenameFileCase";d:0.002;s:50:"HalcyonModelTest::testUpdateContentRenameExtension";d:0.002;s:42:"HalcyonModelTest::testUpdatePageFileExists";d:0.001;s:32:"HalcyonModelTest::testDeletePage";d:0.001;s:40:"HalcyonModelTest::testPageWithValidation";d:0.001;s:50:"HalcyonModelTest::testPageWithNestedValidationFail";d:0;s:50:"HalcyonModelTest::testPageWithNestedValidationPass";d:0.001;s:43:"HalcyonModelTest::testPageQueryListFileName";d:0.001;s:39:"HalcyonModelTest::testAddDynamicPoperty";d:0.002;s:85:"MemoryRepositoryTest::testItemsAreRetrievedFromMemoryCacheBeforeCheckingExternalCache";d:0;s:99:"MemoryRepositoryTest::testItemsCanBeRetrievedFromExternalCacheAndRetrievedFromMemoryCacheAfterwards";d:0;s:51:"MemoryRepositoryTest::testItemsArePutIntoBothCaches";d:0;s:63:"MemoryRepositoryTest::testMemoryCacheCanStoreAndGetFalseyValues";d:0;s:73:"MemoryRepositoryTest::testBothCachesAreIncrementedAndDecrementedCorrectly";d:0;s:46:"MemoryRepositoryTest::testBothCachesForgetKeys";d:0;s:55:"MemoryRepositoryTest::testBothCachesAreFlushedCorrectly";d:0;s:28:"SectionParserTest::testParse";d:0;s:34:"SectionParserTest::testParseOffset";d:0;s:40:"ValidationTraitTest::testArrayFieldNames";d:0;s:30:"BlockBuilderTest::testPutBlock";d:0;s:30:"BlockBuilderTest::testSetBlock";d:0;s:33:"BlockBuilderTest::testAppendBlock";d:0;s:38:"BlockBuilderTest::testPlaceholderBlock";d:0;s:33:"BlockBuilderTest::testResetBlocks";d:0;s:34:"BlockBuilderTest::testNestedBlocks";d:0;s:42:"BlockBuilderTest::testContainBetweenBlocks";d:0;s:26:"HtmlBuilderTest::testStrip";d:0;s:26:"HtmlBuilderTest::testLimit";d:0;s:34:"HtmlBuilderTest::testLimitEncoding";d:0;s:26:"HtmlBuilderTest::testClean";d:0;s:28:"HtmlHelperTest::testNameToId";d:0;s:31:"HtmlHelperTest::testNameToArray";d:0;s:33:"MailerTest::testProcessRecipients";d:0;s:36:"HttpTest::testSetOptionsViaConstants";d:0.001;s:34:"HttpTest::testSetOptionsViaStrings";d:0;s:35:"HttpTest::testSetOptionsViaIntegers";d:0;s:39:"HttpTest::testSetInvalidOptionViaString";d:0;s:40:"HttpTest::testSetInvalidOptionViaInteger";d:0;s:43:"HttpTest::testSetOptionsViaArrayOfConstants";d:0;s:42:"HttpTest::testSetOptionsViaArrayOfIntegers";d:0;s:41:"HttpTest::testSetOptionsViaArrayOfStrings";d:0;s:47:"HttpTest::testSetInvalidOptionViaArrayOfStrings";d:0;s:48:"HttpTest::testSetInvalidOptionViaArrayOfIntegers";d:0;s:28:"HttpTest::testSetRequestData";d:0;s:33:"HttpTest::testSetRequestDataArray";d:0;s:27:"HttpTest::testSetPostFields";d:0;s:43:"HttpTest::testRequestDataOverridePostFields";d:0;s:33:"BracketTest::testParseCombination";d:0;s:31:"BracketTest::testParseSingleKey";d:0;s:32:"BracketTest::testParseLoopingKey";d:0;s:33:"BracketTest::testParseWithFilters";d:0;s:18:"IniTest::testBasic";d:0;s:18:"IniTest::testArray";d:0;s:19:"IniTest::testObject";d:0;s:21:"IniTest::testComments";d:0;s:20:"IniTest::testComplex";d:0;s:29:"IniTest::testMultilinesValues";d:0;s:19:"IniTest::testRender";d:0;s:32:"SyntaxFieldParserTest::testParse";d:0;s:42:"SyntaxFieldParserTest::testParseWithPrefix";d:0;s:53:"SyntaxFieldParserTest::testParseJsTriggerApiAttribute";d:0;s:48:"SyntaxFieldParserTest::testParseDropdownAndRadio";d:0;s:43:"SyntaxFieldParserTest::testParseColorPicker";d:0;s:40:"SyntaxFieldParserTest::testParseRepeater";d:0;s:37:"SyntaxFieldParserTest::testProcessTag";d:0;s:43:"SyntaxFieldParserTest::testProcessTagsRegex";d:0;s:45:"SyntaxFieldParserTest::testProcessParamsRegex";d:0;s:33:"SyntaxParserTest::testParseToTwig";d:0;s:41:"SyntaxParserTest::testParseRepeaterToTwig";d:0;s:33:"SyntaxParserTest::testParseToView";d:0;s:41:"SyntaxParserTest::testParseRepeaterToView";d:0;s:33:"SyntaxParserTest::testParseToEdit";d:0;s:35:"SyntaxParserTest::testParseToRender";d:0;s:43:"SyntaxParserTest::testParseRepeaterToRender";d:0;s:35:"SyntaxParserTest::testParseVariable";d:0;s:41:"SyntaxParserTest::testParseVariableToEdit";d:0;s:49:"SyntaxParserTest::testParseDropDownVariableToEdit";d:0;s:68:"SyntaxParserTest::testParseDropDownVariableToEditInvalidKeyException";d:0;s:77:"SyntaxParserTest::testParseDropDownVariableToEditInvalidStaticMethodException";d:0;s:35:"YamlTest::testParseWithoutProcessor";d:0.003;s:35:"YamlTest::testParseWithPreProcessor";d:0;s:46:"YamlTest::testParseWithPreProcessorTemporarily";d:0;s:36:"YamlTest::testParseWithPostProcessor";d:0;s:39:"RouterHelperTest::testSegmentIsOptional";d:0;s:41:"RouterHelperTest::testParameterNameMethod";d:0;s:35:"RouterHelperTest::testSegmentRegexp";d:0;s:34:"RouterHelperTest::testDefaultValue";d:0;s:39:"RouterHelperTest::testReplaceParameters";d:0;s:26:"RouterTest::testResolveUrl";d:0;s:21:"RouterTest::testMatch";d:0;s:19:"RouterTest::testUrl";d:0;s:33:"ScaffoldBaseTest::testProcessVars";d:0.001;s:21:"ArrTest::testArrClass";d:0;s:19:"ArrTest::testHelper";d:0;s:33:"ClassLoaderTest::testClassesExist";d:0;s:28:"ClassLoaderTest::testAliases";d:0;s:37:"ClassLoaderTest::testNamespaceAliases";d:0;s:28:"CountableTest::testCountable";d:0;s:21:"EmitterTest::testBind";d:0;s:25:"EmitterTest::testBindOnce";d:0;s:28:"EmitterTest::testUnbindEvent";d:0;s:26:"EmitterTest::testFireEvent";d:0;s:32:"EmitterTest::testFireEventResult";d:0;s:29:"EmitterTest::testBindPriority";d:0;s:23:"EventFakeTest::testFire";d:0;s:27:"HelpersTest::testConfigPath";d:0.005;s:28:"HelpersTest::testPluginsPath";d:0;s:27:"HelpersTest::testThemesPath";d:0;s:25:"HelpersTest::testTempPath";d:0;s:28:"HelpersTest::testUploadsPath";d:0;s:26:"HelpersTest::testMediaPath";d:0;s:22:"MailFakeTest::testSend";d:0;s:23:"MailFakeTest::testQueue";d:0;s:35:"MailFakeTest::testIndexedArrayViews";d:0;s:33:"MailFakeTest::testNamedArrayViews";d:0;s:42:"MailFakeTest::testIndexedArrayViews_Queued";d:0;s:40:"MailFakeTest::testNamedArrayViews_Queued";d:0;s:31:"UrlGeneratorTest::testSimpleUrl";d:0;s:32:"UrlGeneratorTest::testComplexUrl";d:0;s:34:"UrlGeneratorTest::testReplacements";d:0;s:34:"UrlGeneratorTest::testJoinSegments";d:0;s:35:"UrlGeneratorTest::testStripSegments";d:0;s:39:"TranslatorTest::testSimilarWordsParsing";d:0;s:26:"TranslatorTest::testChoice";d:0.001;s:35:"TranslatorTest::testChoiceSublocale";d:0;s:50:"TranslatorTest::testOverrideWithBeforeResolveEvent";d:0.001;s:37:"TranslatorTest::testNamespaceAliasing";d:0;s:46:"TranslatorTest::testMixedCaseNamespaceAliasing";d:0;s:38:"EmailValidationTest::testDefaultFilter";d:0.001;s:34:"EmailValidationTest::testRFCFilter";d:0.001;s:30:"RuleObjectTest::testRuleObject";d:0;s:36:"RuleObjectTest::testRuleObjectPasses";d:0;s:47:"RuleObjectTest::testRuleObjectTranslatedMessage";d:0;}}} \ No newline at end of file From 2be2479176eacd50866e9f7bd37e547ccebd03af Mon Sep 17 00:00:00 2001 From: = Date: Mon, 26 Apr 2021 20:18:09 +0200 Subject: [PATCH 20/41] Fixed unit tests, as the compare compiled queries were missing a semicolon --- tests/Database/QueryBuilderTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Database/QueryBuilderTest.php b/tests/Database/QueryBuilderTest.php index ed39a11ad..56d67aedd 100644 --- a/tests/Database/QueryBuilderTest.php +++ b/tests/Database/QueryBuilderTest.php @@ -131,7 +131,7 @@ public function testUpsert() $builder->getConnection() ->expects($this->once()) ->method('affectingStatement') - ->with('merge [users] using (values (?, ?), (?, ?)) [laravel_source] ([email], [name]) on [laravel_source].[email] = [users].[email] when matched then update set [email] = [laravel_source].[email], [name] = [laravel_source].[name] when not matched then insert ([email], [name]) values ([email], [name])', ['foo', 'bar', 'foo2', 'bar2']) + ->with('merge [users] using (values (?, ?), (?, ?)) [laravel_source] ([email], [name]) on [laravel_source].[email] = [users].[email] when matched then update set [email] = [laravel_source].[email], [name] = [laravel_source].[name] when not matched then insert ([email], [name]) values ([email], [name]);', ['foo', 'bar', 'foo2', 'bar2']) ->willReturn(2); $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email'); $this->assertEquals(2, $result); @@ -174,7 +174,7 @@ public function testUpsertWithUpdateColumns() $builder->getConnection() ->expects($this->once()) ->method('affectingStatement') - ->with('merge [users] using (values (?, ?), (?, ?)) [laravel_source] ([email], [name]) on [laravel_source].[email] = [users].[email] when matched then update set [name] = [laravel_source].[name] when not matched then insert ([email], [name]) values ([email], [name])', ['foo', 'bar', 'foo2', 'bar2']) + ->with('merge [users] using (values (?, ?), (?, ?)) [laravel_source] ([email], [name]) on [laravel_source].[email] = [users].[email] when matched then update set [name] = [laravel_source].[name] when not matched then insert ([email], [name]) values ([email], [name]);', ['foo', 'bar', 'foo2', 'bar2']) ->willReturn(2); $result = $builder->from('users')->upsert([['email' => 'foo', 'name' => 'bar'], ['name' => 'bar2', 'email' => 'foo2']], 'email', ['name']); $this->assertEquals(2, $result); From 8f288e442bdee62c232244ee1e5c676edc60b3bb Mon Sep 17 00:00:00 2001 From: = Date: Mon, 26 Apr 2021 20:45:49 +0200 Subject: [PATCH 21/41] Removed php 7.2 runner from github workflow --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 888641921..2167f671c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: max-parallel: 6 matrix: operatingSystem: [ubuntu-latest, windows-latest] - phpVersion: ['7.2', '7.3', '7.4', '8.0'] + phpVersion: ['7.3', '7.4', '8.0'] fail-fast: false runs-on: ${{ matrix.operatingSystem }} name: ${{ matrix.operatingSystem }} / PHP ${{ matrix.phpVersion }} From 421d088b53aa88e78cb67370ac7e78c2a06c170d Mon Sep 17 00:00:00 2001 From: = Date: Mon, 26 Apr 2021 21:57:13 +0200 Subject: [PATCH 22/41] Added a unit test for version.yaml interpretation --- tests/Parse/YamlTest.php | 14 ++++++++++++++ tests/fixtures/yaml/version_test.yaml | 5 +++++ 2 files changed, 19 insertions(+) create mode 100644 tests/fixtures/yaml/version_test.yaml diff --git a/tests/Parse/YamlTest.php b/tests/Parse/YamlTest.php index 098af0b43..a5156977e 100644 --- a/tests/Parse/YamlTest.php +++ b/tests/Parse/YamlTest.php @@ -148,6 +148,20 @@ public function testSymfony3YamlFileWithProcessor() ], ], $yaml); } + + public function testVersionYaml() + { + $parser = new YamlParser; + $yaml = $parser->parse(file_get_contents(dirname(__DIR__) . '/fixtures/yaml/version_test.yaml')); + $this->assertEquals([ + '1.1.0' => 'Update test', + '1.1.1' => [ + 'Version with multipe tasks', + 'migration.php', + ], + '1.1.2' => 'Important update' + ], $yaml); + } } /** diff --git a/tests/fixtures/yaml/version_test.yaml b/tests/fixtures/yaml/version_test.yaml new file mode 100644 index 000000000..9263c7283 --- /dev/null +++ b/tests/fixtures/yaml/version_test.yaml @@ -0,0 +1,5 @@ +1.1.0: Update test +1.1.1: + - Version with multipe tasks + - migration.php +1.1.2: Important update From 96503161272376034e60133e44fbf7f296f1b811 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 27 Apr 2021 01:12:34 +0200 Subject: [PATCH 23/41] bring back the editorconfig. removed by accident --- .editorconfig | 7 +++++++ .gitignore | 1 - 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..75ed0f9c1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 87a01f2d4..09358ced8 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,6 @@ composer.lock php_errors.log #eclipse -/.editorconfig /.buildpath /.project /.settings/ From e81f03b9b3450a6dc824c6bc6647544ddedce851 Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Thu, 29 Apr 2021 00:22:28 -0600 Subject: [PATCH 24/41] Update .editorconfig --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 75ed0f9c1..b9afb3d3b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,4 +4,4 @@ charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true indent_style = space -indent_size = 4 \ No newline at end of file +indent_size = 4 From d646c0b173339cee8afc843d02c6c6efb571953e Mon Sep 17 00:00:00 2001 From: = Date: Thu, 29 Apr 2021 21:41:02 +0200 Subject: [PATCH 25/41] Removed Yaml version test as per https://github.com/wintercms/storm/pull/26#discussion_r622768675 --- tests/Parse/YamlTest.php | 14 -------------- tests/fixtures/yaml/version_test.yaml | 5 ----- 2 files changed, 19 deletions(-) delete mode 100644 tests/fixtures/yaml/version_test.yaml diff --git a/tests/Parse/YamlTest.php b/tests/Parse/YamlTest.php index a5156977e..098af0b43 100644 --- a/tests/Parse/YamlTest.php +++ b/tests/Parse/YamlTest.php @@ -148,20 +148,6 @@ public function testSymfony3YamlFileWithProcessor() ], ], $yaml); } - - public function testVersionYaml() - { - $parser = new YamlParser; - $yaml = $parser->parse(file_get_contents(dirname(__DIR__) . '/fixtures/yaml/version_test.yaml')); - $this->assertEquals([ - '1.1.0' => 'Update test', - '1.1.1' => [ - 'Version with multipe tasks', - 'migration.php', - ], - '1.1.2' => 'Important update' - ], $yaml); - } } /** diff --git a/tests/fixtures/yaml/version_test.yaml b/tests/fixtures/yaml/version_test.yaml deleted file mode 100644 index 9263c7283..000000000 --- a/tests/fixtures/yaml/version_test.yaml +++ /dev/null @@ -1,5 +0,0 @@ -1.1.0: Update test -1.1.1: - - Version with multipe tasks - - migration.php -1.1.2: Important update From f7d1a37719fea24382f6f0e6778d6d233ebf6b08 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 29 Apr 2021 21:42:36 +0200 Subject: [PATCH 26/41] Removing 7.3 support as per https://github.com/wintercms/storm/pull/26#discussion_r622763866 --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2167f671c..c4a44076a 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: max-parallel: 6 matrix: operatingSystem: [ubuntu-latest, windows-latest] - phpVersion: ['7.3', '7.4', '8.0'] + phpVersion: ['7.4', '8.0'] fail-fast: false runs-on: ${{ matrix.operatingSystem }} name: ${{ matrix.operatingSystem }} / PHP ${{ matrix.phpVersion }} From 5a75f0a92dfb1a80dd232dfe0955c2bca7057a6c Mon Sep 17 00:00:00 2001 From: = Date: Thu, 29 Apr 2021 22:04:24 +0200 Subject: [PATCH 27/41] Reverted to original --- src/Database/Traits/Encryptable.php | 12 +++++++----- tests/Database/Traits/EncryptableTest.php | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Database/Traits/Encryptable.php b/src/Database/Traits/Encryptable.php index 982378a14..4218243f5 100644 --- a/src/Database/Traits/Encryptable.php +++ b/src/Database/Traits/Encryptable.php @@ -11,6 +11,11 @@ trait Encryptable * protected $encryptable = []; */ + /** + * @var \Illuminate\Contracts\Encryption\Encrypter Encrypter instance. + */ + protected $encrypter; + /** * @var array List of original attribute values before they were encrypted. */ @@ -103,10 +108,7 @@ public function getOriginalEncryptableValue($attribute) */ public function getEncrypter() { - if (is_null(self::$encrypter)) { - $this->setEncrypter(App::make('encrypter')); - } - return self::$encrypter; + return (!is_null($this->encrypter)) ? $this->encrypter : App::make('encrypter'); } /** @@ -117,6 +119,6 @@ public function getEncrypter() */ public function setEncrypter(\Illuminate\Contracts\Encryption\Encrypter $encrypter) { - parent::encryptUsing($encrypter); + $this->encrypter = $encrypter; } } diff --git a/tests/Database/Traits/EncryptableTest.php b/tests/Database/Traits/EncryptableTest.php index 109796cf8..c68c849ae 100644 --- a/tests/Database/Traits/EncryptableTest.php +++ b/tests/Database/Traits/EncryptableTest.php @@ -22,7 +22,7 @@ public function setUp(): void public function testEncryptableTrait() { $testModel = new TestModelEncryptable(); - $testModel->encryptUsing($this->encrypter); + $testModel->setEncrypter($this->encrypter); $testModel->fill(['secret' => 'test']); $this->assertEquals('test', $testModel->secret); From 0d38c6b9e28c0f8cb9b7e6d260a691bbb162d5ce Mon Sep 17 00:00:00 2001 From: = Date: Thu, 29 Apr 2021 22:06:25 +0200 Subject: [PATCH 28/41] Renamed to to to conflict with the static variable in Eloquent\Model > PHP Fatal error: Illuminate\Database\Eloquent\Model and Winter\Storm\Database\Traits\Encryptable define the same property () in the composition of TestModelEncryptable. However, the definition differs and is considered incompatible. --- src/Database/Traits/Encryptable.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Database/Traits/Encryptable.php b/src/Database/Traits/Encryptable.php index 4218243f5..7e1844dc4 100644 --- a/src/Database/Traits/Encryptable.php +++ b/src/Database/Traits/Encryptable.php @@ -14,7 +14,7 @@ trait Encryptable /** * @var \Illuminate\Contracts\Encryption\Encrypter Encrypter instance. */ - protected $encrypter; + protected $encrypterInstance; /** * @var array List of original attribute values before they were encrypted. @@ -108,7 +108,7 @@ public function getOriginalEncryptableValue($attribute) */ public function getEncrypter() { - return (!is_null($this->encrypter)) ? $this->encrypter : App::make('encrypter'); + return (!is_null($this->encrypterInstance)) ? $this->encrypterInstance : App::make('encrypter'); } /** @@ -119,6 +119,6 @@ public function getEncrypter() */ public function setEncrypter(\Illuminate\Contracts\Encryption\Encrypter $encrypter) { - $this->encrypter = $encrypter; + $this->encrypterInstance = $encrypter; } } From 488952dbc6ede08ff93dfd4c06a6fb738817dbad Mon Sep 17 00:00:00 2001 From: = Date: Thu, 29 Apr 2021 22:14:04 +0200 Subject: [PATCH 29/41] Removed Throwable and Exception imports, added root namespace in front of relevant references. --- src/Foundation/Exception/Handler.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/Foundation/Exception/Handler.php b/src/Foundation/Exception/Handler.php index 1355793cf..8485bfef6 100644 --- a/src/Foundation/Exception/Handler.php +++ b/src/Foundation/Exception/Handler.php @@ -3,8 +3,6 @@ use Log; use Closure; use Response; -use Exception; -use Throwable; use ReflectionClass; use ReflectionFunction; use Winter\Storm\Exception\AjaxException; @@ -87,7 +85,7 @@ public function report(\Throwable $exception) * @param \Throwable $exception * @return \Illuminate\Http\Response */ - public function render($request, Throwable $exception) + public function render($request, \Throwable $exception) { $statusCode = $this->getStatusCode($exception); $response = $this->callCustomHandlers($exception); @@ -178,7 +176,7 @@ protected function callCustomHandlers($exception, $fromConsole = false) try { $response = $handler($exception, $code, $fromConsole); } - catch (Exception $e) { + catch (\Exception $e) { $response = $this->convertExceptionToResponse($e); } // If this handler returns a "non-null" response, we will return it so it will @@ -218,7 +216,7 @@ protected function hints(ReflectionFunction $reflection, $exception) try { return (new ReflectionClass($expected->getType()->getName())) ->isInstance($exception); - } catch (Throwable $t) { + } catch (\Throwable $t) { return false; } } From 43f521eed5d89a63990420b564bd39d952ba96b7 Mon Sep 17 00:00:00 2001 From: = Date: Fri, 30 Apr 2021 00:48:38 +0200 Subject: [PATCH 30/41] Added unit test for dispatcher on changed events that are accepted on the listen() method. Modified Dispatcher so it accepts closures and QueuedClosures and passes handling off to the parent class --- src/Events/Dispatcher.php | 6 +++ tests/Events/DispatcherTest.php | 69 +++++++++++++++++++++++++++++ tests/fixtures/events/EventTest.php | 5 +++ 3 files changed, 80 insertions(+) create mode 100644 tests/Events/DispatcherTest.php create mode 100644 tests/fixtures/events/EventTest.php diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index 55ce6a39b..4a90c0b4a 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -1,10 +1,12 @@ setupWildcardListen($event, $listener); diff --git a/tests/Events/DispatcherTest.php b/tests/Events/DispatcherTest.php new file mode 100644 index 000000000..5ed9055a9 --- /dev/null +++ b/tests/Events/DispatcherTest.php @@ -0,0 +1,69 @@ +listen('test.test', function() use (&$magic_value) { + $magic_value = true; + }); + $dispatcher->fire('test.test'); + $this->assertTrue($magic_value); + } + + /** + * Test closure usage + */ + public function testTypedClosureListen() + { + $magic_value = false; + $dispatcher = new Dispatcher(); + $dispatcher->listen(function(EventTest $event) use (&$magic_value) { + $magic_value = true; + }); + $dispatcher->dispatch('test.test'); + $this->assertFalse($magic_value); + $dispatcher->dispatch(new EventTest); + $this->assertTrue($magic_value); + } + + /** + * Test wether the dispatcher accepts a QueuedClosure + * TODO: Figure out how to test successful execution of event closure on a triggered event. + */ + public function testQueuedClosureListen() + { + $dispatcher = new Dispatcher(); + $dispatcher->listen(new QueuedClosure(function(EventTest $event) use (&$magic_value) { + + })); + $this->addToAssertionCount(1); + + } +} \ No newline at end of file diff --git a/tests/fixtures/events/EventTest.php b/tests/fixtures/events/EventTest.php new file mode 100644 index 000000000..c6d030a1c --- /dev/null +++ b/tests/fixtures/events/EventTest.php @@ -0,0 +1,5 @@ + Date: Thu, 29 Apr 2021 17:01:53 -0600 Subject: [PATCH 31/41] Update tests/fixtures/events/EventTest.php --- tests/fixtures/events/EventTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fixtures/events/EventTest.php b/tests/fixtures/events/EventTest.php index c6d030a1c..efac398af 100644 --- a/tests/fixtures/events/EventTest.php +++ b/tests/fixtures/events/EventTest.php @@ -2,4 +2,4 @@ class EventTest { -} \ No newline at end of file +} From 99be292792fde2fcd2db8a8bd6e057e69bdce95f Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Thu, 29 Apr 2021 17:03:11 -0600 Subject: [PATCH 32/41] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index a9a614516..de9c8d977 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": ">=7.3", + "php": ">=7.4", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", From 3c3a43768004aefd35ced15e0ec96afa25e5ad5e Mon Sep 17 00:00:00 2001 From: Michael Dibbets Date: Fri, 30 Apr 2021 11:38:21 +0200 Subject: [PATCH 33/41] Fixed code sniffer errors. Also learned how to run code sniffer. --- tests/Events/DispatcherTest.php | 16 +++++++--------- tests/fixtures/events/EventTest.php | 6 +++--- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/tests/Events/DispatcherTest.php b/tests/Events/DispatcherTest.php index 5ed9055a9..19082e5dc 100644 --- a/tests/Events/DispatcherTest.php +++ b/tests/Events/DispatcherTest.php @@ -1,4 +1,4 @@ -listen('test.test', function() use (&$magic_value) { + $dispatcher->listen('test.test', function () use (&$magic_value) { $magic_value = true; }); $dispatcher->fire('test.test'); @@ -40,11 +40,11 @@ public function testNormalListen() /** * Test closure usage */ - public function testTypedClosureListen() + public function testTypedClosureListen() { $magic_value = false; $dispatcher = new Dispatcher(); - $dispatcher->listen(function(EventTest $event) use (&$magic_value) { + $dispatcher->listen(function (EventTest $event) use (&$magic_value) { $magic_value = true; }); $dispatcher->dispatch('test.test'); @@ -60,10 +60,8 @@ public function testTypedClosureListen() public function testQueuedClosureListen() { $dispatcher = new Dispatcher(); - $dispatcher->listen(new QueuedClosure(function(EventTest $event) use (&$magic_value) { - + $dispatcher->listen(new QueuedClosure(function (EventTest $event) use (&$magic_value) { })); $this->addToAssertionCount(1); - } -} \ No newline at end of file +} diff --git a/tests/fixtures/events/EventTest.php b/tests/fixtures/events/EventTest.php index efac398af..91b016959 100644 --- a/tests/fixtures/events/EventTest.php +++ b/tests/fixtures/events/EventTest.php @@ -1,5 +1,5 @@ - Date: Mon, 3 May 2021 22:31:59 +0200 Subject: [PATCH 34/41] Moved non public api methods to use throwable in the method name to reflect its purpose. Changed exception to throwable where applicable in the doc comments Added import for Throwable Changed remaining Exception into ThrowAble --- src/Foundation/Exception/Handler.php | 83 ++++++++++++++-------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/Foundation/Exception/Handler.php b/src/Foundation/Exception/Handler.php index 8485bfef6..027626877 100644 --- a/src/Foundation/Exception/Handler.php +++ b/src/Foundation/Exception/Handler.php @@ -3,6 +3,7 @@ use Log; use Closure; use Response; +use Throwable; use ReflectionClass; use ReflectionFunction; use Winter\Storm\Exception\AjaxException; @@ -32,14 +33,14 @@ class Handler extends ExceptionHandler protected $handlers = []; /** - * Report or log an exception. + * Report or log an throwable. * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * - * @param \Throwable $exception + * @param \Throwable $throwable * @return void */ - public function report(\Throwable $exception) + public function report(Throwable $throwable) { /** * @event exception.beforeReport @@ -47,22 +48,22 @@ public function report(\Throwable $exception) * * Example usage (prevents the reporting of a given exception) * - * Event::listen('exception.report', function (\Exception $exception) { - * if ($exception instanceof \My\Custom\Exception) { + * Event::listen('exception.report', function (\Throwable $throwable) { + * if ($throwable instanceof \My\Custom\Exception) { * return false; * } * }); */ - if (app()->make('events')->fire('exception.beforeReport', [$exception], true) === false) { + if (app()->make('events')->fire('exception.beforeReport', [$throwable], true) === false) { return; } - if ($this->shouldntReport($exception)) { + if ($this->shouldntReport($throwable)) { return; } if (class_exists('Log')) { - Log::error($exception); + Log::error($throwable); } /** @@ -71,24 +72,24 @@ public function report(\Throwable $exception) * * Example usage (performs additional reporting on the exception) * - * Event::listen('exception.report', function (\Exception $exception) { - * app('sentry')->captureException($exception); + * Event::listen('exception.report', function (\Throwable $throwable) { + * app('sentry')->captureException($throwable); * }); */ - app()->make('events')->fire('exception.report', [$exception]); + app()->make('events')->fire('exception.report', [$throwable]); } /** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request - * @param \Throwable $exception + * @param \Throwable $throwable * @return \Illuminate\Http\Response */ - public function render($request, \Throwable $exception) + public function render($request, Throwable $throwable) { - $statusCode = $this->getStatusCode($exception); - $response = $this->callCustomHandlers($exception); + $statusCode = $this->getStatusCode($throwable); + $response = $this->callCustomHandlers($throwable); if (!is_null($response)) { if ($response instanceof \Symfony\Component\HttpFoundation\Response) { @@ -98,25 +99,25 @@ public function render($request, \Throwable $exception) return Response::make($response, $statusCode); } - if ($event = app()->make('events')->fire('exception.beforeRender', [$exception, $statusCode, $request], true)) { + if ($event = app()->make('events')->fire('exception.beforeRender', [$throwable, $statusCode, $request], true)) { return Response::make($event, $statusCode); } - return parent::render($request, $exception); + return parent::render($request, $throwable); } /** * Checks if the exception implements the HttpExceptionInterface, or returns * as generic 500 error code for a server side error. - * @param \Exception $exception + * @param \Throwable $throwable * @return int */ - protected function getStatusCode($exception) + protected function getStatusCode($throwable) { - if ($exception instanceof HttpExceptionInterface) { - $code = $exception->getStatusCode(); + if ($throwable instanceof HttpExceptionInterface) { + $code = $throwable->getStatusCode(); } - elseif ($exception instanceof AjaxException) { + elseif ($throwable instanceof AjaxException) { $code = 406; } else { @@ -152,32 +153,32 @@ public function error(Closure $callback) } /** - * Handle the given exception. + * Handle the given throwable. * - * @param \Exception $exception + * @param \Throwable $throwable * @param bool $fromConsole * @return void */ - protected function callCustomHandlers($exception, $fromConsole = false) + protected function callCustomHandlers($throwable, $fromConsole = false) { foreach ($this->handlers as $handler) { - // If this exception handler does not handle the given exception, we will just - // go the next one. A handler may type-hint an exception that it handles so + // If this throwable handler does not handle the given throwable, we will just + // go the next one. A handler may type-hint an throwable that it handles so // we can have more granularity on the error handling for the developer. - if (!$this->handlesException($handler, $exception)) { + if (!$this->handlesThrowable($handler, $throwable)) { continue; } - $code = $this->getStatusCode($exception); + $code = $this->getStatusCode($throwable); // We will wrap this handler in a try / catch and avoid white screens of death - // if any exceptions are thrown from a handler itself. This way we will get + // if any throwables are thrown from a handler itself. This way we will get // at least some errors, and avoid errors with no data or not log writes. try { - $response = $handler($exception, $code, $fromConsole); + $response = $handler($throwable, $code, $fromConsole); } - catch (\Exception $e) { - $response = $this->convertExceptionToResponse($e); + catch (Throwable $t) { + $response = $this->convertThrowableToResponse($t); } // If this handler returns a "non-null" response, we will return it so it will // get sent back to the browsers. Once the handler returns a valid response @@ -189,33 +190,33 @@ protected function callCustomHandlers($exception, $fromConsole = false) } /** - * Determine if the given handler handles this exception. + * Determine if the given handler handles this throwable. * * @param \Closure $handler - * @param \Exception $exception + * @param \Throwable $throwable * @return bool */ - protected function handlesException(Closure $handler, $exception) + protected function handlesThrowable(Closure $handler, $throwable) { $reflection = new ReflectionFunction($handler); - return $reflection->getNumberOfParameters() == 0 || $this->hints($reflection, $exception); + return $reflection->getNumberOfParameters() == 0 || $this->hints($reflection, $throwable); } /** - * Determine if the given handler type hints the exception. + * Determine if the given handler type hints the throwable. * * @param \ReflectionFunction $reflection - * @param \Exception $exception + * @param \Throwable $throwable * @return bool */ - protected function hints(ReflectionFunction $reflection, $exception) + protected function hints(ReflectionFunction $reflection, $throwable) { $parameters = $reflection->getParameters(); $expected = $parameters[0]; try { return (new ReflectionClass($expected->getType()->getName())) - ->isInstance($exception); + ->isInstance($throwable); } catch (\Throwable $t) { return false; } From 652c7b850bb52d1019fa153ed066a2901a84a251 Mon Sep 17 00:00:00 2001 From: = Date: Mon, 3 May 2021 22:55:51 +0200 Subject: [PATCH 35/41] Targetting dev-master for laravel 9 --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index de9c8d977..f44a2f1af 100644 --- a/composer.json +++ b/composer.json @@ -43,8 +43,8 @@ "twig/twig": "~2.0", "league/csv": "~9.1", "nesbot/carbon": "^2.0", - "laravel/framework": "^8.0", - "laravel/tinker": "~2.0" + "laravel/framework": "9.x-dev", + "laravel/tinker": "dev-develop" }, "require-dev": { "phpunit/phpunit": "^8.5.12|^9.3.3", From 1cda0ebc75eec61ce1c0fa37c73f277370697a55 Mon Sep 17 00:00:00 2001 From: = Date: Thu, 6 May 2021 23:41:11 +0200 Subject: [PATCH 36/41] Added unit tests for priorities in event handlers Added unit test for QueuedClosures Added priority sorting for all accepted event types Added documentation for the duality of for priority purposes --- src/Events/Dispatcher.php | 23 ++++++--- tests/Events/DispatcherTest.php | 84 +++++++++++++++++++++++++++++---- 2 files changed, 92 insertions(+), 15 deletions(-) diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index 4a90c0b4a..4836a3ea2 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -27,17 +27,26 @@ class Dispatcher extends BaseDispatcher /** * Register an event listener with the dispatcher. * - * @param string|array $events - * @param mixed $listener - * @param int $priority + * @param string|array|Closure|QueuedClosure $events + * @param mixed $listener when the third parameter is omitted and a Closure or QueuedClosure is provided this parameter is used as an integer this is used as priority value + * @param int $priority * @return void */ public function listen($events, $listener = null, $priority = 0) { - if ($events instanceof Closure || $events instanceof QueuedClosure) { - return parent::listen($events, $listener, $priority); + if ($events instanceof Closure || $events instanceof QueuedClosure) { + if ($priority === 0 && (is_int($listener) || filter_var($listener, FILTER_VALIDATE_INT))) { + $priority = (int)$listener; + } + } + if ($events instanceof Closure) { + return $this->listen($this->firstClosureParameterType($events), $events, $priority); + } elseif ($events instanceof QueuedClosure) { + return $this->listen($this->firstClosureParameterType($events->closure), $events->resolve(), $priority); + } elseif ($listener instanceof QueuedClosure) { + $listener = $listener->resolve(); } - + foreach ((array) $events as $event) { if (Str::contains($event, '*')) { $this->setupWildcardListen($event, $listener); @@ -177,7 +186,7 @@ protected function sortListeners($eventName) // If listeners exist for the given event, we will sort them by the priority // so that we can call them in the correct order. We will cache off these - // sorted event listeners so we do not have to re-sort on every events. + // sorted event listeners so we do not have to re-sort on every event. if (isset($this->listeners[$eventName])) { krsort($this->listeners[$eventName]); diff --git a/tests/Events/DispatcherTest.php b/tests/Events/DispatcherTest.php index 19082e5dc..6dcfccc96 100644 --- a/tests/Events/DispatcherTest.php +++ b/tests/Events/DispatcherTest.php @@ -12,14 +12,14 @@ class DispatcherTest extends TestCase { - + public function setUp(): void { include_once __DIR__.'/../fixtures/events/EventTest.php'; - + parent::setUp(); } - + /** * Test normal string event dispatch */ @@ -36,7 +36,7 @@ public function testNormalListen() $dispatcher->fire('test.test'); $this->assertTrue($magic_value); } - + /** * Test closure usage */ @@ -52,16 +52,84 @@ public function testTypedClosureListen() $dispatcher->dispatch(new EventTest); $this->assertTrue($magic_value); } - + + public function testStringEventPriorities() + { + $magic_value = 0; + $dispatcher = new Dispatcher(); + + $dispatcher->listen("test.test", function () use (&$magic_value) { + $magic_value = 42; + }, 1); + $dispatcher->listen("test.test", function () use (&$magic_value) { + $magic_value = 1; + }, 2); + + $dispatcher->dispatch("test.test"); + $this->assertEquals(42, $magic_value); + } + + public function testClosurePriorities() + { + $magic_value = 0; + $dispatcher = new Dispatcher(); + + $dispatcher->listen(function (EventTest $test) use (&$magic_value) { + $magic_value = 42; + }, 1); + $dispatcher->listen(function (EventTest $test) use (&$magic_value) { + $magic_value = 1; + }, 2); + + $dispatcher->dispatch(new EventTest()); + $this->assertEquals(42, $magic_value); + } + + public function testQueuedClosurePriorities() + { + $mock_queued_closure_should_match = $this->createMock(QueuedClosure::class); + $mock_queued_closure_should_match->closure = function (EventTest $test) use (&$magic_value) { + $magic_value = 42; + }; + $mock_queued_closure_should_match->method('resolve')->willReturn($mock_queued_closure_should_match->closure); + + $mock_queued_closure_should_not_match = $this->createMock(QueuedClosure::class); + $mock_queued_closure_should_not_match->closure = function (EventTest $test) use (&$magic_value) { + $magic_value = 2; + }; + $mock_queued_closure_should_not_match->method('resolve')->willReturn($mock_queued_closure_should_not_match->closure); + $dispatcher = new Dispatcher(); + $magic_value = 0; + + // Test natural sorting without priority to the queued tasks to be queued. + $dispatcher->listen($mock_queued_closure_should_not_match); + $dispatcher->listen($mock_queued_closure_should_match); + $dispatcher->dispatch(new EventTest()); + $this->assertEquals(42, $magic_value); + + // Test priority sorting for the queued tasks to be queued + $magic_value = 0; + $dispatcher->listen($mock_queued_closure_should_match, 1); + $dispatcher->listen($mock_queued_closure_should_not_match, 2); + $dispatcher->dispatch(new EventTest()); + $this->assertEquals(42, $magic_value); + } + /** * Test wether the dispatcher accepts a QueuedClosure * TODO: Figure out how to test successful execution of event closure on a triggered event. */ public function testQueuedClosureListen() { + $magic_value = false; + $mock_queued_closure = $this->createMock(QueuedClosure::class); + $mock_queued_closure->closure = function (EventTest $test) use (&$magic_value) { + $magic_value = true; + }; + $mock_queued_closure->method('resolve')->willReturn($mock_queued_closure->closure); $dispatcher = new Dispatcher(); - $dispatcher->listen(new QueuedClosure(function (EventTest $event) use (&$magic_value) { - })); - $this->addToAssertionCount(1); + $dispatcher->listen($mock_queued_closure); + $dispatcher->dispatch(new EventTest()); + $this->assertTrue($magic_value); } } From 2813f8d878d0776bf90facc9e0fd686b78477672 Mon Sep 17 00:00:00 2001 From: = Date: Sun, 9 May 2021 19:04:27 +0200 Subject: [PATCH 37/41] Upgraded emitter to accept Events like Dispatcher does Addes serializable protections for emitter and extendable addes Serialisation helper for wrapping closures Added constants to get rid of the magic strings in the traits. --- src/Events/Dispatcher.php | 10 +- src/Extension/ExtendableTrait.php | 60 ++++---- src/Extension/ExtensionConstants.php | 15 ++ src/Extension/ExtensionTrait.php | 21 ++- src/Support/Serialisation.php | 35 +++++ src/Support/Traits/Emitter.php | 73 ++++++++-- tests/Events/DispatcherTest.php | 3 +- tests/Extension/ExtendableTest.php | 35 ++++- tests/Support/EmitterTest.php | 128 ++++++++++++++++++ .../ExtensionAndEmitterSerialisationTest.php | 34 +++++ 10 files changed, 364 insertions(+), 50 deletions(-) create mode 100644 src/Extension/ExtensionConstants.php create mode 100644 src/Support/Serialisation.php create mode 100644 tests/Support/ExtensionAndEmitterSerialisationTest.php diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index 4836a3ea2..df2b63218 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -1,6 +1,7 @@ resolve(); } + if ($listener instanceof Closure && !($listener instanceof SerializableClosure)) { + $listener = new SerializableClosure($listener); + } foreach ((array) $events as $event) { if (Str::contains($event, '*')) { @@ -124,6 +129,9 @@ public function dispatch($event, $payload = [], $halt = false) } foreach ($this->getListeners($event) as $listener) { + if ($listener instanceof SerializableClosure) { + $listener = $listener->getClosure(); + } $response = $listener($event, $payload); // If a response is returned from the listener and event halting is enabled diff --git a/src/Extension/ExtendableTrait.php b/src/Extension/ExtendableTrait.php index fa07e73a7..7ef2011e2 100644 --- a/src/Extension/ExtendableTrait.php +++ b/src/Extension/ExtendableTrait.php @@ -1,9 +1,11 @@ [], - 'methods' => [], - 'dynamicMethods' => [], - 'dynamicProperties' => [] + ExtensionConstants::EXTENSIONS => [], + ExtensionConstants::METHODS => [], + ExtensionConstants::DYNAMIC_METHODS => [], + ExtensionConstants::DYNAMIC_PROPERTIES => [] ]; /** @@ -56,7 +58,7 @@ public function extendableConstruct() foreach ($classes as $class) { if (isset(self::$extendableCallbacks[$class]) && is_array(self::$extendableCallbacks[$class])) { foreach (self::$extendableCallbacks[$class] as $callback) { - call_user_func($callback, $this); + call_user_func(Serialisation::unwrapClosure($callback), $this); } } } @@ -109,8 +111,7 @@ public static function extendableExtendCallback($callback) ) { self::$extendableCallbacks[$class] = []; } - - self::$extendableCallbacks[$class][] = $callback; + self::$extendableCallbacks[$class][] = Serialisation::wrapClosure($callback); } /** @@ -147,7 +148,7 @@ protected function extensionExtractMethods($extensionName, $extensionObject) continue; } - $this->extensionData['methods'][$methodName] = $extensionName; + $this->extensionData[ExtensionConstants::METHODS][$methodName] = $extensionName; } } @@ -166,8 +167,7 @@ public function addDynamicMethod($dynamicName, $method, $extension = null) ) { $method = [$extensionObj, $method]; } - - $this->extensionData['dynamicMethods'][$dynamicName] = $method; + $this->extensionData[ExtensionConstants::DYNAMIC_METHODS][$dynamicName] = Serialisation::wrapClosure($method); } /** @@ -186,7 +186,7 @@ public function addDynamicProperty($dynamicName, $value = null) $this->{$dynamicName} = $value; } - $this->extensionData['dynamicProperties'][] = $dynamicName; + $this->extensionData[ExtensionConstants::DYNAMIC_PROPERTIES][] = $dynamicName; self::$extendableGuardProperties = true; } @@ -204,7 +204,7 @@ public function extendClassWith($extensionName) $extensionName = str_replace('.', '\\', trim($extensionName)); - if (isset($this->extensionData['extensions'][$extensionName])) { + if (isset($this->extensionData[ExtensionConstants::EXTENSIONS][$extensionName])) { throw new Exception(sprintf( 'Class %s has already been extended with %s', get_class($this), @@ -212,7 +212,7 @@ public function extendClassWith($extensionName) )); } - $this->extensionData['extensions'][$extensionName] = $extensionObject = new $extensionName($this); + $this->extensionData[ExtensionConstants::EXTENSIONS][$extensionName] = $extensionObject = new $extensionName($this); $this->extensionExtractMethods($extensionName, $extensionObject); $extensionObject->extensionApplyInitCallbacks(); } @@ -225,7 +225,7 @@ public function extendClassWith($extensionName) public function isClassExtendedWith($name) { $name = str_replace('.', '\\', trim($name)); - return isset($this->extensionData['extensions'][$name]); + return isset($this->extensionData[ExtensionConstants::EXTENSIONS][$name]); } /** @@ -239,7 +239,7 @@ public function isClassExtendedWith($name) public function getClassExtension($name) { $name = str_replace('.', '\\', trim($name)); - return $this->extensionData['extensions'][$name] ?? null; + return $this->extensionData[ExtensionConstants::EXTENSIONS][$name] ?? null; } /** @@ -254,7 +254,7 @@ public function getClassExtension($name) public function asExtension($shortName) { $hints = []; - foreach ($this->extensionData['extensions'] as $class => $obj) { + foreach ($this->extensionData[ExtensionConstants::EXTENSIONS] as $class => $obj) { if ( preg_match('@\\\\([\w]+)$@', $class, $matches) && $matches[1] == $shortName @@ -275,8 +275,8 @@ public function methodExists($name) { return ( method_exists($this, $name) || - isset($this->extensionData['methods'][$name]) || - isset($this->extensionData['dynamicMethods'][$name]) + isset($this->extensionData[ExtensionConstants::METHODS][$name]) || + isset($this->extensionData[ExtensionConstants::DYNAMIC_METHODS][$name]) ); } @@ -288,8 +288,8 @@ public function getClassMethods() { return array_values(array_unique(array_merge( get_class_methods($this), - array_keys($this->extensionData['methods']), - array_keys($this->extensionData['dynamicMethods']) + array_keys($this->extensionData[ExtensionConstants::METHODS]), + array_keys($this->extensionData[ExtensionConstants::DYNAMIC_METHODS]) ))); } @@ -300,7 +300,7 @@ public function getClassMethods() public function getDynamicProperties() { $result = []; - $propertyNames = $this->extensionData['dynamicProperties']; + $propertyNames = $this->extensionData[ExtensionConstants::DYNAMIC_PROPERTIES]; foreach ($propertyNames as $propName) { $result[$propName] = $this->{$propName}; } @@ -318,7 +318,7 @@ public function propertyExists($name) return true; } - foreach ($this->extensionData['extensions'] as $extensionObject) { + foreach ($this->extensionData[ExtensionConstants::EXTENSIONS] as $extensionObject) { if ( property_exists($extensionObject, $name) && $this->extendableIsAccessible($extensionObject, $name) @@ -350,7 +350,7 @@ protected function extendableIsAccessible($class, $propertyName) */ public function extendableGet($name) { - foreach ($this->extensionData['extensions'] as $extensionObject) { + foreach ($this->extensionData[ExtensionConstants::EXTENSIONS] as $extensionObject) { if ( property_exists($extensionObject, $name) && $this->extendableIsAccessible($extensionObject, $name) @@ -373,7 +373,7 @@ public function extendableGet($name) */ public function extendableSet($name, $value) { - foreach ($this->extensionData['extensions'] as $extensionObject) { + foreach ($this->extensionData[ExtensionConstants::EXTENSIONS] as $extensionObject) { if (!property_exists($extensionObject, $name)) { continue; } @@ -405,20 +405,20 @@ public function extendableSet($name, $value) */ public function extendableCall($name, $params = null) { - if (isset($this->extensionData['methods'][$name])) { - $extension = $this->extensionData['methods'][$name]; - $extensionObject = $this->extensionData['extensions'][$extension]; + if (isset($this->extensionData[ExtensionConstants::METHODS][$name])) { + $extension = $this->extensionData[ExtensionConstants::METHODS][$name]; + $extensionObject = $this->extensionData[ExtensionConstants::EXTENSIONS][$extension]; if (method_exists($extension, $name)) { return call_user_func_array([$extensionObject, $name], array_values($params)); } } - if (isset($this->extensionData['dynamicMethods'][$name])) { - $dynamicCallable = $this->extensionData['dynamicMethods'][$name]; + if (isset($this->extensionData[ExtensionConstants::DYNAMIC_METHODS][$name])) { + $dynamicCallable = $this->extensionData[ExtensionConstants::DYNAMIC_METHODS][$name]; if (is_callable($dynamicCallable)) { - return call_user_func_array($dynamicCallable, array_values($params)); + return call_user_func_array(Serialisation::unwrapClosure($dynamicCallable), array_values($params)); } } diff --git a/src/Extension/ExtensionConstants.php b/src/Extension/ExtensionConstants.php new file mode 100644 index 000000000..a1de9e1d3 --- /dev/null +++ b/src/Extension/ExtensionConstants.php @@ -0,0 +1,15 @@ + [], - 'methods' => ['extensionIsHiddenField', 'extensionIsHiddenMethod'] + ExtensionConstants::FIELDS => [], + ExtensionConstants::METHODS => ['extensionIsHiddenField', 'extensionIsHiddenMethod'] ]; public function extensionApplyInitCallbacks() @@ -34,6 +36,9 @@ public function extensionApplyInitCallbacks() foreach ($classes as $class) { if (isset(self::$extensionCallbacks[$class]) && is_array(self::$extensionCallbacks[$class])) { foreach (self::$extensionCallbacks[$class] as $callback) { + if ($callback instanceof SerializableClosure) { + $callback = $callback->getClosure(); + } call_user_func($callback, $this); } } @@ -54,28 +59,30 @@ public static function extensionExtendCallback($callback) ) { self::$extensionCallbacks[$class] = []; } - + if ($callback instanceof \Closure && !($callback instanceof SerializableClosure)) { + $callback = new SerializableClosure(($callback)); + } self::$extensionCallbacks[$class][] = $callback; } protected function extensionHideField($name) { - $this->extensionHidden['fields'][] = $name; + $this->extensionHidden[ExtensionConstants::FIELDS][] = $name; } protected function extensionHideMethod($name) { - $this->extensionHidden['methods'][] = $name; + $this->extensionHidden[ExtensionConstants::METHODS][] = $name; } public function extensionIsHiddenField($name) { - return in_array($name, $this->extensionHidden['fields']); + return in_array($name, $this->extensionHidden[ExtensionConstants::FIELDS]); } public function extensionIsHiddenMethod($name) { - return in_array($name, $this->extensionHidden['methods']); + return in_array($name, $this->extensionHidden[ExtensionConstants::METHODS]); } public static function getCalledExtensionClass() diff --git a/src/Support/Serialisation.php b/src/Support/Serialisation.php new file mode 100644 index 000000000..3cd23d508 --- /dev/null +++ b/src/Support/Serialisation.php @@ -0,0 +1,35 @@ +getClosure(); + } + return $callable; + } +} diff --git a/src/Support/Traits/Emitter.php b/src/Support/Traits/Emitter.php index c6629e628..be2b98375 100644 --- a/src/Support/Traits/Emitter.php +++ b/src/Support/Traits/Emitter.php @@ -1,5 +1,11 @@ emitterEventCollection[$event][$priority][] = $callback; + if ($event instanceof Closure || $event instanceof QueuedClosure) { + if ($priority === 0 && (is_int($callback) || filter_var($callback, FILTER_VALIDATE_INT))) { + $priority = (int)$callback; + } + } + if ($event instanceof Closure) { + return $this->bindEvent($this->firstClosureParameterType($event), $event, $priority); + } elseif ($event instanceof QueuedClosure) { + return $this->bindEvent($this->firstClosureParameterType($event->closure), $event->resolve(), $priority); + } elseif ($callback instanceof QueuedClosure) { + $callback = $callback->resolve(); + } + $this->emitterEventCollection[$event][$priority][] = Serialisation::wrapClosure($callback); unset($this->emitterEventSorted[$event]); return $this; } /** * Create a new event binding that fires once only + * @param string|Closure|QueuedClosure $event + * @param Closure|null $callback When a Closure or QueuedClosure is provided as the first parameter + * this parameter can be omitted * @return self */ - public function bindEventOnce($event, $callback) + public function bindEventOnce($event, $callback = null) { - $this->emitterSingleEventCollection[$event][] = $callback; + if ($event instanceof Closure) { + return $this->bindEventOnce($this->firstClosureParameterType($event), $event); + } elseif ($event instanceof QueuedClosure) { + return $this->bindEventOnce($this->firstClosureParameterType($event->closure), $event->resolve()); + } elseif ($callback instanceof QueuedClosure) { + $callback = $callback->resolve(); + } + $this->emitterSingleEventCollection[$event][] = Serialisation::wrapClosure($callback); return $this; } @@ -77,6 +110,10 @@ public function unbindEvent($event = null) return; } + if (is_object($event)) { + $event = get_class($event); + } + if ($event === null) { unset($this->emitterSingleEventCollection, $this->emitterEventCollection, $this->emitterEventSorted); return $this; @@ -106,9 +143,11 @@ public function unbindEvent($event = null) */ public function fireEvent($event, $params = [], $halt = false) { - if (!is_array($params)) { - $params = [$params]; - } + // When the given "event" is actually an object we will assume it is an event + // object and use the class as the event name and this event itself as the + // payload to the handler, which makes object based events quite simple. + list($event, $params) = $this->parseEventAndPayload($event, $params); + $result = []; /* @@ -116,7 +155,7 @@ public function fireEvent($event, $params = [], $halt = false) */ if (isset($this->emitterSingleEventCollection[$event])) { foreach ($this->emitterSingleEventCollection[$event] as $callback) { - $response = call_user_func_array($callback, $params); + $response = call_user_func_array(Serialisation::unwrapClosure($callback), $params); if (is_null($response)) { continue; } @@ -138,7 +177,7 @@ public function fireEvent($event, $params = [], $halt = false) } foreach ($this->emitterEventSorted[$event] as $callback) { - $response = call_user_func_array($callback, $params); + $response = call_user_func_array(Serialisation::unwrapClosure($callback), $params); if (is_null($response)) { continue; } @@ -151,4 +190,20 @@ public function fireEvent($event, $params = [], $halt = false) return $halt ? null : $result; } + + /** + * Parse the given event and payload and prepare them for dispatching. + * + * @param mixed $event + * @param mixed $payload + * @return array + */ + protected function parseEventAndPayload($event, $payload = null) + { + if (is_object($event)) { + [$payload, $event] = [[$event], get_class($event)]; + } + + return [$event, Arr::wrap($payload)]; + } } diff --git a/tests/Events/DispatcherTest.php b/tests/Events/DispatcherTest.php index 6dcfccc96..c48005a42 100644 --- a/tests/Events/DispatcherTest.php +++ b/tests/Events/DispatcherTest.php @@ -116,8 +116,7 @@ public function testQueuedClosurePriorities() } /** - * Test wether the dispatcher accepts a QueuedClosure - * TODO: Figure out how to test successful execution of event closure on a triggered event. + * Test whether the dispatcher accepts a QueuedClosure */ public function testQueuedClosureListen() { diff --git a/tests/Extension/ExtendableTest.php b/tests/Extension/ExtendableTest.php index dfbe93227..66d8bca09 100644 --- a/tests/Extension/ExtendableTest.php +++ b/tests/Extension/ExtendableTest.php @@ -149,7 +149,7 @@ public function testInvalidImplementValue() { $this->expectException(Exception::class); $this->expectExceptionMessage('Class ExtendableTestInvalidExtendableClass contains an invalid $implement value'); - + $result = new ExtendableTestInvalidExtendableClass; } @@ -216,6 +216,35 @@ public function testGetClassMethods() $this->assertContains('getFooAnotherWay', $methods); $this->assertNotContains('missingFunction', $methods); } + + public function testClosureSerialisation() + { + $test_string = 'hello world'; + BasicExtendable::extend(function (BasicExtendable $class) use ($test_string) { + $class->addDynamicMethod('foobar', function () use ($test_string) { + $x = function () use ($test_string) { + return $test_string; + }; + return $x(); + }); + $class->addDynamicMethod('bazbal', function () use ($test_string) { + return function () use ($test_string) { + return $test_string; + }; + }); + }); + + $subject = new BasicExtendable(); + + $serialized = serialize($subject); + + $unserialized = unserialize($serialized); + + $this->assertEquals($test_string, $unserialized->foobar()); + $test = $unserialized->bazbal(); + $this->assertInstanceOf(Closure::class, $test); + $this->assertEquals($test(), $test_string); + } } // @@ -308,6 +337,10 @@ public static function getName() } } +class BasicExtendable extends Extendable +{ +} + /* * Example class with soft implement failure */ diff --git a/tests/Support/EmitterTest.php b/tests/Support/EmitterTest.php index d01947cb3..b43ec113c 100644 --- a/tests/Support/EmitterTest.php +++ b/tests/Support/EmitterTest.php @@ -1,5 +1,7 @@ assertEquals('the quick brown fox jumped over the lazy dog', $result); } + + /** + * Test closure usage + */ + public function testTypedClosureListen() + { + $magic_value = false; + $dispatcher = $this->traitObject; + $dispatcher->bindEvent(function (EventTest $event) use (&$magic_value) { + $magic_value = true; + }); + $dispatcher->fireEvent('test.test'); + $this->assertFalse($magic_value); + $dispatcher->fireEvent(new EventTest); + $this->assertTrue($magic_value); + } + + public function testClosurePriorities() + { + $magic_value = 0; + $dispatcher = $this->traitObject; + + $dispatcher->bindEvent(function (EventTest $test) use (&$magic_value) { + $magic_value = 42; + }, 1); + $dispatcher->bindEvent(function (EventTest $test) use (&$magic_value) { + $magic_value = 1; + }, 2); + + $dispatcher->fireEvent(new EventTest()); + $this->assertEquals(42, $magic_value); + } + + public function testQueuedClosurePriorities() + { + $mock_queued_closure_should_match = $this->createMock(QueuedClosure::class); + $mock_queued_closure_should_match->closure = function (EventTest $test) use (&$magic_value) { + $magic_value = 42; + }; + $mock_queued_closure_should_match->method('resolve')->willReturn($mock_queued_closure_should_match->closure); + + $mock_queued_closure_should_not_match = $this->createMock(QueuedClosure::class); + $mock_queued_closure_should_not_match->closure = function (EventTest $test) use (&$magic_value) { + $magic_value = 2; + }; + $mock_queued_closure_should_not_match->method('resolve')->willReturn($mock_queued_closure_should_not_match->closure); + $dispatcher = $this->traitObject; + $magic_value = 0; + + // Test natural sorting without priority to the queued tasks to be queued. + $dispatcher->bindEvent($mock_queued_closure_should_not_match); + $dispatcher->bindEvent($mock_queued_closure_should_match); + $dispatcher->fireEvent(new EventTest()); + $this->assertEquals(42, $magic_value); + + // Test priority sorting for the queued tasks to be queued + $magic_value = 0; + $dispatcher->bindEvent($mock_queued_closure_should_match, 1); + $dispatcher->bindEvent($mock_queued_closure_should_not_match, 2); + $dispatcher->fireEvent(new EventTest()); + $this->assertEquals(42, $magic_value); + } + + /** + * Test whether the Emitter accepts a QueuedClosure + */ + public function testQueuedClosureListen() + { + $magic_value = false; + $mock_queued_closure = $this->createMock(QueuedClosure::class); + $mock_queued_closure->closure = function (EventTest $test) use (&$magic_value) { + $magic_value = true; + }; + $mock_queued_closure->method('resolve')->willReturn($mock_queued_closure->closure); + $dispatcher = $this->traitObject; + $dispatcher->bindEvent($mock_queued_closure); + $dispatcher->fireEvent(new EventTest()); + $this->assertTrue($magic_value); + } + + public function testClosureSerialisation() + { + $emitter = new EmitterClass(); + $test = 'foobar'; + $emitter->bindEvent($test, function () use ($test) { + EmitterClass::$output = $test; + }); + $emitter->bindEvent(function(EventTest $event) use ($test) { + EmitterClass::$output = $test.$test; + }); + $serialized = serialize($emitter); + $unserialized = unserialize($serialized); + $unserialized->fireEvent($test); + $this->assertEquals($test, EmitterClass::$output); + + $unserialized->fireEvent(new EventTest()); + $this->assertEquals($test.$test, EmitterClass::$output); + } + + public function testNestedClosureSerialisation() + { + $emitter = new EmitterClass(); + $test = 'foobar'; + $emitter->bindEvent($test, function () use ($test) { + EmitterClass::$output = function () use ($test) { + return $test; + }; + }); + + $serialized = serialize($emitter); + $unserialized = unserialize($serialized); + $unserialized->fireEvent($test); + + $closure = EmitterClass::$output; + $this->assertInstanceOf(Closure::class, $closure); + $this->assertEquals($test, $closure()); + } +} +class EmitterClass +{ + use \Winter\Storm\Support\Traits\Emitter; + + /** + * @var string $output used for keeping a testable variable as references don't survive serialisation + */ + public static $output; } diff --git a/tests/Support/ExtensionAndEmitterSerialisationTest.php b/tests/Support/ExtensionAndEmitterSerialisationTest.php new file mode 100644 index 000000000..62cdd1577 --- /dev/null +++ b/tests/Support/ExtensionAndEmitterSerialisationTest.php @@ -0,0 +1,34 @@ +bindEvent($test, function () use ($test) { + ExtendableEmitter::$output = $test; + }); + }); + $instance = new ExtendableEmitter(); + $serialized = serialize($instance); + $unserialized = unserialize($serialized); + $unserialized->fireEvent($test); + $this->assertEquals($test, ExtendableEmitter::$output); + } +} + +class ExtendableEmitter extends Extendable +{ + use \Winter\Storm\Support\Traits\Emitter; + + /** + * @var string $output used for keeping a testable variable as references don't survive serialisation + */ + public static $output; +} From 6da424247791ca10f72c95271bdcb484de106649 Mon Sep 17 00:00:00 2001 From: = Date: Tue, 11 May 2021 22:20:10 +0200 Subject: [PATCH 38/41] Removed constants per descission https://github.com/wintercms/storm/pull/26#pullrequestreview-655614717 replaced code with calls to serialisation helpers --- src/Events/Dispatcher.php | 5 ++- src/Extension/ExtendableTrait.php | 50 ++++++++++++++-------------- src/Extension/ExtensionConstants.php | 15 --------- src/Extension/ExtensionTrait.php | 23 +++++-------- 4 files changed, 36 insertions(+), 57 deletions(-) delete mode 100644 src/Extension/ExtensionConstants.php diff --git a/src/Events/Dispatcher.php b/src/Events/Dispatcher.php index df2b63218..6c3f118e6 100644 --- a/src/Events/Dispatcher.php +++ b/src/Events/Dispatcher.php @@ -4,6 +4,7 @@ use Opis\Closure\SerializableClosure; use ReflectionClass; use Winter\Storm\Support\Arr; +use Winter\Storm\Support\Serialisation; use Winter\Storm\Support\Str; use Illuminate\Events\Dispatcher as BaseDispatcher; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; @@ -48,9 +49,7 @@ public function listen($events, $listener = null, $priority = 0) } elseif ($listener instanceof QueuedClosure) { $listener = $listener->resolve(); } - if ($listener instanceof Closure && !($listener instanceof SerializableClosure)) { - $listener = new SerializableClosure($listener); - } + $listener = Serialisation::wrapClosure($listener); foreach ((array) $events as $event) { if (Str::contains($event, '*')) { diff --git a/src/Extension/ExtendableTrait.php b/src/Extension/ExtendableTrait.php index 7ef2011e2..53703c0b6 100644 --- a/src/Extension/ExtendableTrait.php +++ b/src/Extension/ExtendableTrait.php @@ -22,10 +22,10 @@ trait ExtendableTrait * @var array Class reflection information, including behaviors. */ protected $extensionData = [ - ExtensionConstants::EXTENSIONS => [], - ExtensionConstants::METHODS => [], - ExtensionConstants::DYNAMIC_METHODS => [], - ExtensionConstants::DYNAMIC_PROPERTIES => [] + 'extensions' => [], + 'methods' => [], + 'dynamicMethods' => [], + 'dynamicProperties' => [] ]; /** @@ -148,7 +148,7 @@ protected function extensionExtractMethods($extensionName, $extensionObject) continue; } - $this->extensionData[ExtensionConstants::METHODS][$methodName] = $extensionName; + $this->extensionData['methods'][$methodName] = $extensionName; } } @@ -167,7 +167,7 @@ public function addDynamicMethod($dynamicName, $method, $extension = null) ) { $method = [$extensionObj, $method]; } - $this->extensionData[ExtensionConstants::DYNAMIC_METHODS][$dynamicName] = Serialisation::wrapClosure($method); + $this->extensionData['dynamicMethods'][$dynamicName] = Serialisation::wrapClosure($method); } /** @@ -186,7 +186,7 @@ public function addDynamicProperty($dynamicName, $value = null) $this->{$dynamicName} = $value; } - $this->extensionData[ExtensionConstants::DYNAMIC_PROPERTIES][] = $dynamicName; + $this->extensionData['dynamicProperties'][] = $dynamicName; self::$extendableGuardProperties = true; } @@ -204,7 +204,7 @@ public function extendClassWith($extensionName) $extensionName = str_replace('.', '\\', trim($extensionName)); - if (isset($this->extensionData[ExtensionConstants::EXTENSIONS][$extensionName])) { + if (isset($this->extensionData['extensions'][$extensionName])) { throw new Exception(sprintf( 'Class %s has already been extended with %s', get_class($this), @@ -212,7 +212,7 @@ public function extendClassWith($extensionName) )); } - $this->extensionData[ExtensionConstants::EXTENSIONS][$extensionName] = $extensionObject = new $extensionName($this); + $this->extensionData['extensions'][$extensionName] = $extensionObject = new $extensionName($this); $this->extensionExtractMethods($extensionName, $extensionObject); $extensionObject->extensionApplyInitCallbacks(); } @@ -225,7 +225,7 @@ public function extendClassWith($extensionName) public function isClassExtendedWith($name) { $name = str_replace('.', '\\', trim($name)); - return isset($this->extensionData[ExtensionConstants::EXTENSIONS][$name]); + return isset($this->extensionData['extensions'][$name]); } /** @@ -239,7 +239,7 @@ public function isClassExtendedWith($name) public function getClassExtension($name) { $name = str_replace('.', '\\', trim($name)); - return $this->extensionData[ExtensionConstants::EXTENSIONS][$name] ?? null; + return $this->extensionData['extensions'][$name] ?? null; } /** @@ -254,7 +254,7 @@ public function getClassExtension($name) public function asExtension($shortName) { $hints = []; - foreach ($this->extensionData[ExtensionConstants::EXTENSIONS] as $class => $obj) { + foreach ($this->extensionData['extensions'] as $class => $obj) { if ( preg_match('@\\\\([\w]+)$@', $class, $matches) && $matches[1] == $shortName @@ -275,8 +275,8 @@ public function methodExists($name) { return ( method_exists($this, $name) || - isset($this->extensionData[ExtensionConstants::METHODS][$name]) || - isset($this->extensionData[ExtensionConstants::DYNAMIC_METHODS][$name]) + isset($this->extensionData['methods'][$name]) || + isset($this->extensionData['dynamicMethods'][$name]) ); } @@ -288,8 +288,8 @@ public function getClassMethods() { return array_values(array_unique(array_merge( get_class_methods($this), - array_keys($this->extensionData[ExtensionConstants::METHODS]), - array_keys($this->extensionData[ExtensionConstants::DYNAMIC_METHODS]) + array_keys($this->extensionData['methods']), + array_keys($this->extensionData['dynamicMethods']) ))); } @@ -300,7 +300,7 @@ public function getClassMethods() public function getDynamicProperties() { $result = []; - $propertyNames = $this->extensionData[ExtensionConstants::DYNAMIC_PROPERTIES]; + $propertyNames = $this->extensionData['dynamicProperties']; foreach ($propertyNames as $propName) { $result[$propName] = $this->{$propName}; } @@ -318,7 +318,7 @@ public function propertyExists($name) return true; } - foreach ($this->extensionData[ExtensionConstants::EXTENSIONS] as $extensionObject) { + foreach ($this->extensionData['extensions'] as $extensionObject) { if ( property_exists($extensionObject, $name) && $this->extendableIsAccessible($extensionObject, $name) @@ -350,7 +350,7 @@ protected function extendableIsAccessible($class, $propertyName) */ public function extendableGet($name) { - foreach ($this->extensionData[ExtensionConstants::EXTENSIONS] as $extensionObject) { + foreach ($this->extensionData['extensions'] as $extensionObject) { if ( property_exists($extensionObject, $name) && $this->extendableIsAccessible($extensionObject, $name) @@ -373,7 +373,7 @@ public function extendableGet($name) */ public function extendableSet($name, $value) { - foreach ($this->extensionData[ExtensionConstants::EXTENSIONS] as $extensionObject) { + foreach ($this->extensionData['extensions'] as $extensionObject) { if (!property_exists($extensionObject, $name)) { continue; } @@ -405,17 +405,17 @@ public function extendableSet($name, $value) */ public function extendableCall($name, $params = null) { - if (isset($this->extensionData[ExtensionConstants::METHODS][$name])) { - $extension = $this->extensionData[ExtensionConstants::METHODS][$name]; - $extensionObject = $this->extensionData[ExtensionConstants::EXTENSIONS][$extension]; + if (isset($this->extensionData['methods'][$name])) { + $extension = $this->extensionData['methods'][$name]; + $extensionObject = $this->extensionData['extensions'][$extension]; if (method_exists($extension, $name)) { return call_user_func_array([$extensionObject, $name], array_values($params)); } } - if (isset($this->extensionData[ExtensionConstants::DYNAMIC_METHODS][$name])) { - $dynamicCallable = $this->extensionData[ExtensionConstants::DYNAMIC_METHODS][$name]; + if (isset($this->extensionData['dynamicMethods'][$name])) { + $dynamicCallable = $this->extensionData['dynamicMethods'][$name]; if (is_callable($dynamicCallable)) { return call_user_func_array(Serialisation::unwrapClosure($dynamicCallable), array_values($params)); diff --git a/src/Extension/ExtensionConstants.php b/src/Extension/ExtensionConstants.php deleted file mode 100644 index a1de9e1d3..000000000 --- a/src/Extension/ExtensionConstants.php +++ /dev/null @@ -1,15 +0,0 @@ - [], - ExtensionConstants::METHODS => ['extensionIsHiddenField', 'extensionIsHiddenMethod'] + 'fields' => [], + 'methods' => ['extensionIsHiddenField', 'extensionIsHiddenMethod'] ]; public function extensionApplyInitCallbacks() @@ -36,10 +37,7 @@ public function extensionApplyInitCallbacks() foreach ($classes as $class) { if (isset(self::$extensionCallbacks[$class]) && is_array(self::$extensionCallbacks[$class])) { foreach (self::$extensionCallbacks[$class] as $callback) { - if ($callback instanceof SerializableClosure) { - $callback = $callback->getClosure(); - } - call_user_func($callback, $this); + call_user_func(Serialisation::unwrapClosure($callback), $this); } } } @@ -59,30 +57,27 @@ public static function extensionExtendCallback($callback) ) { self::$extensionCallbacks[$class] = []; } - if ($callback instanceof \Closure && !($callback instanceof SerializableClosure)) { - $callback = new SerializableClosure(($callback)); - } - self::$extensionCallbacks[$class][] = $callback; + self::$extensionCallbacks[$class][] = Serialisation::wrapClosure($callback); } protected function extensionHideField($name) { - $this->extensionHidden[ExtensionConstants::FIELDS][] = $name; + $this->extensionHidden['fields'][] = $name; } protected function extensionHideMethod($name) { - $this->extensionHidden[ExtensionConstants::METHODS][] = $name; + $this->extensionHidden['methods'][] = $name; } public function extensionIsHiddenField($name) { - return in_array($name, $this->extensionHidden[ExtensionConstants::FIELDS]); + return in_array($name, $this->extensionHidden['fields']); } public function extensionIsHiddenMethod($name) { - return in_array($name, $this->extensionHidden[ExtensionConstants::METHODS]); + return in_array($name, $this->extensionHidden['methods']); } public static function getCalledExtensionClass() From e0c8e33cb4d3a7629855352292dc2b182985d0cd Mon Sep 17 00:00:00 2001 From: Luke Towers Date: Tue, 11 May 2021 22:35:20 -0600 Subject: [PATCH 39/41] Update src/Extension/ExtendableTrait.php --- src/Extension/ExtendableTrait.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Extension/ExtendableTrait.php b/src/Extension/ExtendableTrait.php index 53703c0b6..845ccdcee 100644 --- a/src/Extension/ExtendableTrait.php +++ b/src/Extension/ExtendableTrait.php @@ -22,10 +22,10 @@ trait ExtendableTrait * @var array Class reflection information, including behaviors. */ protected $extensionData = [ - 'extensions' => [], - 'methods' => [], - 'dynamicMethods' => [], - 'dynamicProperties' => [] + 'extensions' => [], + 'methods' => [], + 'dynamicMethods' => [], + 'dynamicProperties' => [] ]; /** From 0e880184f789c656479e770f45b3d10d72a36bb1 Mon Sep 17 00:00:00 2001 From: Tschallacka Date: Wed, 12 May 2021 06:56:30 +0200 Subject: [PATCH 40/41] Code quality fix --- tests/Support/EmitterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Support/EmitterTest.php b/tests/Support/EmitterTest.php index b43ec113c..098a138a0 100644 --- a/tests/Support/EmitterTest.php +++ b/tests/Support/EmitterTest.php @@ -215,7 +215,7 @@ public function testClosureSerialisation() $emitter->bindEvent($test, function () use ($test) { EmitterClass::$output = $test; }); - $emitter->bindEvent(function(EventTest $event) use ($test) { + $emitter->bindEvent(function (EventTest $event) use ($test) { EmitterClass::$output = $test.$test; }); $serialized = serialize($emitter); From 539754948cce430e3eada71c78c647f058847fbb Mon Sep 17 00:00:00 2001 From: Tschallacka Date: Wed, 12 May 2021 06:58:23 +0200 Subject: [PATCH 41/41] Code quality fix --- src/Support/Serialisation.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Support/Serialisation.php b/src/Support/Serialisation.php index 3cd23d508..41a7bd0b8 100644 --- a/src/Support/Serialisation.php +++ b/src/Support/Serialisation.php @@ -1,6 +1,5 @@