From 266b0540fb01577e43d54a122fef233b7420a46f Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Mon, 7 Mar 2022 23:32:31 +0100 Subject: [PATCH 01/45] Ignore .idea folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5826402..0b27101 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ composer.phar composer.lock .DS_Store +/.idea From c03f9dee38fd15c4f120531529c882f6d21e4dc7 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Mon, 7 Mar 2022 23:32:51 +0100 Subject: [PATCH 02/45] Remove docblocks --- src/HasBooleanDates.php | 93 ++++++----------------------------------- 1 file changed, 12 insertions(+), 81 deletions(-) diff --git a/src/HasBooleanDates.php b/src/HasBooleanDates.php index 615d03d..7cfff3b 100644 --- a/src/HasBooleanDates.php +++ b/src/HasBooleanDates.php @@ -8,12 +8,7 @@ trait HasBooleanDates { - /** - * Initialize the trait. - * - * @return void - */ - public function initializeHasBooleanDates() : void + public function initializeHasBooleanDates(): void { $this->dates = array_unique( array_merge( @@ -23,27 +18,13 @@ public function initializeHasBooleanDates() : void ); } - /** - * Convert the model's attributes to an array. - * - * @return array - */ - public function attributesToArray() : array + public function attributesToArray(): array { $attributes = parent::attributesToArray(); - $attributes = $this->addBooleanDateAttributesToArray($attributes); - - return $attributes; + return $this->addBooleanDateAttributesToArray($attributes); } - /** - * Get an attribute from the model. - * - * @param string $key - * - * @return mixed - */ public function getAttribute($key) { if (! $key) { @@ -57,14 +38,6 @@ public function getAttribute($key) return parent::getAttribute($key); } - /** - * Set a given attribute on the model. - * - * @param string $key - * @param mixed $value - * - * @return $this - */ public function setAttribute($key, $value) { if ($this->hasBooleanDate($key)) { @@ -76,18 +49,12 @@ public function setAttribute($key, $value) return parent::setAttribute($key, $value); } - /** - * @return array - */ - public function getBooleanDates() : array + public function getBooleanDates(): array { return $this->booleanDates ?? []; } - /** - * @return array - */ - protected function getBooleanDateAttributes() : array + protected function getBooleanDateAttributes(): array { return array_intersect_key( $this->getAttributes(), @@ -95,23 +62,12 @@ protected function getBooleanDateAttributes() : array ); } - /** - * @param mixed $key - * - * @return bool - */ - protected function getBooleanDate($key) : bool + protected function getBooleanDate(string $key): bool { return parent::getAttribute($this->getBooleanDateField($key)) !== null; } - /** - * @param string $key - * @param mixed $value - * - * @return void - */ - protected function setBooleanDate(string $key, $value) : void + protected function setBooleanDate(string $key, mixed $value): void { // Only update the timestamp if the value is true and if it's not yet set // or if the value is false and we need to unset the field. @@ -124,22 +80,12 @@ protected function setBooleanDate(string $key, $value) : void } } - /** - * @param string $key - * - * @return bool - */ - protected function hasBooleanDate(string $key) : bool + protected function hasBooleanDate(string $key): bool { return array_key_exists($key, $this->getBooleanDates()); } - /** - * @param mixed $key - * - * @return bool - */ - protected function currentBooleanDateFieldValueIsNotYetSet($key) : bool + protected function currentBooleanDateFieldValueIsNotYetSet(string $key): bool { if (! array_key_exists($this->getBooleanDateField($key), $this->getAttributes())) { return true; @@ -148,32 +94,17 @@ protected function currentBooleanDateFieldValueIsNotYetSet($key) : bool return parent::getAttribute($this->getBooleanDateField($key)) === null; } - /** - * @param mixed $key - * - * @return string - */ - protected function getBooleanDateField($key) : string + protected function getBooleanDateField(string $key): string { return $this->booleanDates[$key]; } - /** - * @param mixed $value - * - * @return string|null - */ - protected function getNewBooleanDateValue($value) : ?string + protected function getNewBooleanDateValue(mixed $value): ?string { return $value ? $this->fromDateTime(Carbon::now()) : null; } - /** - * @param array $attributes - * - * @return array - */ - protected function addBooleanDateAttributesToArray(array $attributes) : array + protected function addBooleanDateAttributesToArray(array $attributes): array { foreach ($this->getBooleanDates() as $booleanField => $date) { if (! array_key_exists($date, $attributes)) { From 960c11480d5ca0caee4ab733de137d429eaa07c2 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Mon, 7 Mar 2022 23:32:58 +0100 Subject: [PATCH 03/45] Use Illuminate\Support\Carbon --- src/HasBooleanDates.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HasBooleanDates.php b/src/HasBooleanDates.php index 7cfff3b..e28d395 100644 --- a/src/HasBooleanDates.php +++ b/src/HasBooleanDates.php @@ -4,7 +4,7 @@ namespace SebastiaanLuca\BooleanDates; -use Carbon\Carbon; +use Illuminate\Support\Carbon; trait HasBooleanDates { From 6c33a50f5ca0f2d8ffe1c537d1238c10b35e01d5 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Mon, 7 Mar 2022 23:40:43 +0100 Subject: [PATCH 04/45] Update readme --- README.md | 55 ++++++++++++++++++++----------------------------------- 1 file changed, 20 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 12eb9bd..5ad429b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Automatically convert Eloquent model boolean attributes to dates (and back) +# Convert Eloquent boolean attributes to dates (and back) [![Latest stable release][version-badge]][link-packagist] [![Software license][license-badge]](LICENSE.md) @@ -11,7 +11,7 @@ [![Follow @sebastiaanluca on Twitter][twitter-profile-badge]][link-twitter] [![Share this package on Twitter][twitter-share-badge]][link-twitter-share] -**A package to automatically convert boolean fields to dates (and back to booleans) so you always know when something was accepted or changed.** +**Automatically convert Eloquent model boolean fields to dates (and back to booleans)** so you always know _when_ something was accepted or changed. Say you've got a registration page for users where they need to accept your terms and perhaps can opt-in to certain features using checkboxes. With the new(-ish) GDPR privacy laws, you're somewhat required to not just keep track of the fact *if* they accepted those (or not), but also *when* they did. @@ -66,8 +66,8 @@ $user->accepted_terms_and_conditions_at; ## Requirements -- PHP 7.3 or higher -- Laravel 7.0 or higher +- PHP 8 or 8.1 +- Laravel 8 or 9 ## How to install @@ -100,34 +100,29 @@ class User extends Model } ``` -To wrap up, create a **migration** to create a new or alter your existing table and add the timestamp fields: +To wrap up, create a **migration** to create a new table or alter your existing table to add the timestamp fields: ```php timestamp('accepted_terms_at')->nullable(); $table->timestamp('accepted_processing_at')->nullable(); $table->timestamp('agreed_to_something_at')->nullable(); }); } -} -``` +}; -Note: the related boolean fields are dynamic and do not need database fields. +``` ## How to use @@ -143,9 +138,7 @@ $user->has_accepted_terms_and_conditions = true; $user->allows_data_processing = 'yes'; // Or using attribute filling -$user->fill([ - 'has_agreed_to_something' => 1, -]); +$user->fill(['has_agreed_to_something' => 1]); $user->save(); ``` @@ -183,9 +176,7 @@ $user = User::findOrFail(42); $user->has_accepted_terms_and_conditions; -/* - * true or false (boolean) - */ +// true or false (boolean) ``` #### Retrieving fields as datetimes @@ -195,17 +186,11 @@ Use a boolean field's defined _value_ to explicitly access its (Carbon) datetime ```php $user = User::findOrFail(42); +// 2018-05-10 16:24:22 (Carbon instance) $user->accepted_terms_at; -/* - * 2018-05-10 16:24:22 (Carbon instance) - */ - +// null $user->accepted_processing_at; - -/* - * NULL - */ ``` ### Array conversion @@ -221,9 +206,9 @@ $user->toArray(); * Which will return something like: * * [ - * 'accepted_terms_at' => \Carbon\Carbon('2018-05-10 16:24:22'), + * 'accepted_terms_at' => \Illuminate\Support\Carbon('2018-05-10 16:24:22'), * 'accepted_processing_at' => NULL, - * 'agreed_to_something_at' => \Carbon\Carbon('2018-05-10 16:24:22'), + * 'agreed_to_something_at' => \Illuminate\Support\Carbon('2018-05-10 16:24:22'), * 'accepted_terms_and_conditions' => true, * 'allows_data_processing' => false, * 'agreed_to_something' => true, @@ -282,8 +267,8 @@ Have a project that could use some guidance? Send me an e-mail at [hello@sebasti [link-twitter-share]: https://twitter.com/intent/tweet?text=Easily%20convert%20Eloquent%20model%20booleans%20to%20dates%20and%20back%20with%20Laravel%20Boolean%20Dates.%20Via%20@sebastiaanluca%20https://github.com/sebastiaanluca/laravel-boolean-dates [link-contributors]: ../../contributors -[link-portfolio]: https://www.sebastiaanluca.com -[link-blog]: https://blog.sebastiaanluca.com +[link-portfolio]: https://sebastiaanluca.com +[link-blog]: https://sebastiaanluca.com/blog [link-packages]: https://packagist.org/packages/sebastiaanluca [link-twitter]: https://twitter.com/sebastiaanluca [link-github-profile]: https://github.com/sebastiaanluca From c3e8c26cd210e4abb0351f121a7e87dec2479906 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 00:04:43 +0100 Subject: [PATCH 05/45] Add .gitattributes --- .gitattributes | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..cdac80f --- /dev/null +++ b/.gitattributes @@ -0,0 +1,11 @@ +# Reduce Composer package download by removing obsolete files + +/.editorconfig export-ignore +/.gitattributes export-ignore +/.github export-ignore +/.gitignore export-ignore +/.php_cs.dist.php export-ignore +/CODE_OF_CONDUCT.md export-ignore +/CONTRIBUTING.md export-ignore +/phpunit.xml.dist export-ignore +/tests export-ignore From 904e15f91c4248840bfbfbbb7e7f4676589153cc Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 00:05:04 +0100 Subject: [PATCH 06/45] Add GitHub templates --- .github/ISSUE_TEMPLATE/BUG_REPORT.md | 19 +++++++++++++++ .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md | 23 ++++++++++++++++++ .../PULL_REQUEST_TEMPLATE.md | 22 +++++++++++------ ISSUE_TEMPLATE.md | 24 ------------------- 4 files changed, 57 insertions(+), 31 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/BUG_REPORT.md create mode 100644 .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md rename PULL_REQUEST_TEMPLATE.md => .github/PULL_REQUEST_TEMPLATE.md (73%) delete mode 100644 ISSUE_TEMPLATE.md diff --git a/.github/ISSUE_TEMPLATE/BUG_REPORT.md b/.github/ISSUE_TEMPLATE/BUG_REPORT.md new file mode 100644 index 0000000..48f1395 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/BUG_REPORT.md @@ -0,0 +1,19 @@ +--- +name: Bug report +about: Create a report to help us improve this project +title: '' +labels: bug +assignees: sebastiaanluca +--- + +### Description + +### Expected result + +### Steps to reproduce + +Please provide a fully working repository that reproduces the bug. + +### Additional info + +Logs, error output, setup, environment, packages, versions, etc. diff --git a/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md new file mode 100644 index 0000000..60093d4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/FEATURE_REQUEST.md @@ -0,0 +1,23 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: feature +assignees: sebastiaanluca +--- + +### Description + +A clear and concise description of the problem or proposal. + +### Suggested solution + +A clear and concise description of what you want to happen. + +### Possible alternatives + +A clear and concise description of any alternative solutions or features you've considered. + +### Additional context + +Any other context or screenshots to help situate and understand the requested feature. diff --git a/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 73% rename from PULL_REQUEST_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md index 7ff85fa..8828020 100644 --- a/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,3 +1,11 @@ +--- +name: Pull request +about: Create a new pull request to merge code into the main branch +title: 'A short, descriptive title' +labels: '' +assignees: sebastiaanluca +--- + ## PR Type What kind of pull request is this? Put an `x` in all the boxes that apply: @@ -8,17 +16,16 @@ What kind of pull request is this? Put an `x` in all the boxes that apply: - [ ] Change feature (non-breaking change which either changes or refactors existing functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) -## What does it change? - -Describe your changes in detail. +--- -## Why this PR? +### Description -Why is this change required? What problem does it solve? +Clearly describe what this pull request changes and why. -## How has this been tested? +### Steps to follow to verify functionality -Please describe in detail how you tested your changes (or are planning on testing them). +1. Clearly state which actions should be performed to fully and correctly review this issue. +2. … ## Checklist @@ -32,3 +39,4 @@ To facilitate merging your change and the approval of this PR, please make sure - If the change to the code requires a change to the documentation, it has been updated accordingly If you're unsure about any of these, don't hesitate to ask. We're here to help! + diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index 08bee51..0000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,24 +0,0 @@ -## Description - -Make it clear if the issue is a **bug**, an **enhancement** or just a **question**. The easiest way to indicate this is to prefix the title, e.g. `[Question] I have a question`. - -Provide a detailed description of the change or addition you are proposing. Include some screenshots or code examples if possible. - -### Your environment - -If you're reporting a bug or asking a specific question, include as many relevant details about your environment so we can reproduce it. The more, the better. - -- Package version or last commit -- Operating system and version -- PHP version -- Laravel version -- Related package versions -- … - -## Context - -Why is this change important to you? How would you use it? How can it benefit other users? - -## Possible implementation - -Not obligatory, but suggest an idea for implementing addition or change. From 1d78d85bf8fc9098b5c3553f3b6aa4176627fe8e Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 00:05:09 +0100 Subject: [PATCH 07/45] Update .gitignore --- .gitignore | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 0b27101..28188ad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ -/vendor -composer.phar +.idea +.php-cs-fixer.cache +.phpunit.result.cache composer.lock -.DS_Store -/.idea +composer.phar +phpunit.xml +vendor/ From 8fef7eac53e75dadb989dafef79955b070f5b670 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 00:05:16 +0100 Subject: [PATCH 08/45] Remove TravisCI config --- .travis.yml | 44 -------------------------------------------- 1 file changed, 44 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 2b69546..0000000 --- a/.travis.yml +++ /dev/null @@ -1,44 +0,0 @@ -language: php - -php: - - 7.3 - - 7.4 - - nightly - -cache: - directories: - - $HOME/.composer/cache - -env: - matrix: - - LARAVEL_VERSION="^7.0" COMPOSER_FLAGS="--prefer-lowest" - - LARAVEL_VERSION="^7.0" COMPOSER_FLAGS="--prefer-stable" - - LARAVEL_VERSION="^8.0" COMPOSER_FLAGS="--prefer-lowest" - - LARAVEL_VERSION="^8.0" COMPOSER_FLAGS="--prefer-stable" - - LARAVEL_VERSION="dev-master" ORCHESTRA_VERSION="dev-master" COMPOSER_FLAGS="--prefer-lowest" MINIMUM_STABILITY="dev" - - LARAVEL_VERSION="dev-master" ORCHESTRA_VERSION="dev-master" COMPOSER_FLAGS="--prefer-stable" MINIMUM_STABILITY="dev" - -matrix: - allow_failures: - - php: nightly - - env: LARAVEL_VERSION="dev-master" ORCHESTRA_VERSION="dev-master" COMPOSER_FLAGS="--prefer-lowest" MINIMUM_STABILITY="dev" - - env: LARAVEL_VERSION="dev-master" ORCHESTRA_VERSION="dev-master" COMPOSER_FLAGS="--prefer-stable" MINIMUM_STABILITY="dev" - fast_finish: true - -before_install: - - composer validate --strict - - travis_retry composer self-update - - if [[ -n ${MINIMUM_STABILITY} ]]; then composer config minimum-stability ${MINIMUM_STABILITY}; echo "Minimum stability set to ${MINIMUM_STABILITY}"; else echo "Minimum stability left unchanged"; fi - - if [[ -n ${ORCHESTRA_VERSION} ]]; then composer require orchestra/testbench=${ORCHESTRA_VERSION} --dev --no-update; else echo "orchestra/testbench version requirement left unchanged"; fi - - composer require laravel/framework=${LARAVEL_VERSION} --no-update - -install: - - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-dist - -script: - - vendor/bin/phpunit - -notifications: - email: - on_failure: change - on_success: never From 175305a6114e0a67fa5a6d68393ba2985c54f62e Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 00:06:01 +0100 Subject: [PATCH 09/45] Update packages --- composer.json | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 7ec60cd..c7eae85 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,7 @@ "type": "library", "description": "Automatically convert Eloquent model boolean attributes to dates (and back).", "keywords": [ + "php", "bool", "boolean", "convert", @@ -24,16 +25,14 @@ } ], "require": { - "php": "^7.3", - "laravel/framework": "^7.0|^8.0", - "nesbot/carbon": "^1.22|^2.0" + "php": "^8.0|^8.1", + "illuminate/support": "^8.0|^9.0" }, "require-dev": { - "dms/phpunit-arraysubset-asserts": "^0.1.0", - "kint-php/kint": "^3.3", - "mockery/mockery": "^1.3", - "orchestra/testbench": "^5.1|^6.0", - "phpunit/phpunit": "^8.5" + "dms/phpunit-arraysubset-asserts": "^0.4.0", + "mockery/mockery": "^1.5", + "orchestra/testbench": "^v6.24|^7.1", + "phpunit/phpunit": "^9.5" }, "autoload": { "psr-4": { @@ -48,6 +47,8 @@ "config": { "sort-packages": true }, + "minimum-stability": "dev", + "prefer-stable": true, "extra": { "laravel": { "providers": [ @@ -70,8 +71,6 @@ "@composer-validate", "@test" ] - }, - "minimum-stability": "dev", - "prefer-stable": true + } } From ac3e8aac16fd34a5fccc07a2b38fbd5644d11cf8 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 00:06:11 +0100 Subject: [PATCH 10/45] Update PHPUnit config --- phpunit.xml | 32 -------------------------------- phpunit.xml.dist | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 32 deletions(-) delete mode 100644 phpunit.xml create mode 100644 phpunit.xml.dist diff --git a/phpunit.xml b/phpunit.xml deleted file mode 100644 index 74a29bd..0000000 --- a/phpunit.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - ./tests/Feature - - - ./tests/Unit - - - - - src/ - - - diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..08a1dbe --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,25 @@ + + + + + src/ + + + + + tests/Feature + + + From 487955519b57dbeea4323ddd64d947c6d291ed0f Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 00:06:16 +0100 Subject: [PATCH 11/45] Format code --- tests/TestCase.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index 0549332..9fa82c4 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -10,11 +10,13 @@ class TestCase extends BaseTestCase { /** + * Get package providers. + * * @param \Illuminate\Foundation\Application $app * - * @return array + * @return array */ - protected function getPackageProviders($app) : array + protected function getPackageProviders($app): array { return [ BooleanDatesServiceProvider::class, From 6cc3935bec3a87cccb081cc10d0a0539819b87bb Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 00:06:22 +0100 Subject: [PATCH 12/45] Remove PHPCS config --- phpcs.xml.dist | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 phpcs.xml.dist diff --git a/phpcs.xml.dist b/phpcs.xml.dist deleted file mode 100644 index 5dacc60..0000000 --- a/phpcs.xml.dist +++ /dev/null @@ -1,9 +0,0 @@ - - - - - ./src - ./tests - - - From 93f36ea994781dd6b7b67f8bc71f8fcbbc784685 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 00:06:26 +0100 Subject: [PATCH 13/45] Update changelog --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 122aeee..15ddd6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,23 @@ All Notable changes to `sebastiaanluca/laravel-boolean-dates` will be documented Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles. +## 6.0.0 (2022-03-09) + +### Added + +- Added support for Laravel 9 + +### Changed + +- Cleaned up code internally +- Switched to using `\Illuminate\Support\Carbon` instead of `\Carbon\Carbon` + +### Removed + +- Dropped support for PHP 7.x +- Dropped support for Laravel 7 +- Removed requirements for `nesbot/carbon` + ## 5.0.0 (2020-10-19) ### Added From 84a9c64e9fcb8f7a66047ab69598032978342afb Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 12:35:14 +0100 Subject: [PATCH 14/45] Update readme --- README.md | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 5ad429b..747a52b 100644 --- a/README.md +++ b/README.md @@ -32,17 +32,11 @@ $user = User::create([ Anywhere else in your code: ```php +// true or false (boolean) $user->has_accepted_terms_and_conditions; -/* - * true or false (boolean) - */ - +// 2018-05-10 16:24:22 (Carbon instance) $user->accepted_terms_and_conditions_at; - -/* - * 2018-05-10 16:24:22 (Carbon instance) - */ ``` ## Table of contents @@ -89,10 +83,7 @@ class User extends Model { use HasBooleanDates; - /** - * @var array - */ - protected $booleanDates = [ + protected array $booleanDates = [ 'has_accepted_terms_and_conditions' => 'accepted_terms_at', 'allows_data_processing' => 'accepted_processing_at', 'has_agreed_to_something' => 'agreed_to_something_at', From ae01ca9be708ac2078d8044ec1ab6e8ea8c9a87c Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 12:35:28 +0100 Subject: [PATCH 15/45] Format code --- src/HasBooleanDates.php | 11 +++++++++++ tests/resources/TestModel.php | 10 +--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/HasBooleanDates.php b/src/HasBooleanDates.php index e28d395..a3c8539 100644 --- a/src/HasBooleanDates.php +++ b/src/HasBooleanDates.php @@ -8,6 +8,17 @@ trait HasBooleanDates { + /** + * Set the date of fields to the current date and time if a counterpart + * boolean field is true-ish. + * + * Keys and values should be in the format: `'boolean_field' => + * 'internal_timestamp_field'`. + * + * @var array + */ + protected array $booleanDates = []; + public function initializeHasBooleanDates(): void { $this->dates = array_unique( diff --git a/tests/resources/TestModel.php b/tests/resources/TestModel.php index 690bcee..c275eee 100644 --- a/tests/resources/TestModel.php +++ b/tests/resources/TestModel.php @@ -11,15 +11,7 @@ class TestModel extends Model { use HasBooleanDates; - /** - * Set the date of fields to the current date and time if a counterpart boolean field is - * true-ish. - * - * Keys and values should be in the format: `'boolean_field' => 'internal_timestamp_field'`. - * - * @var array - */ - protected $booleanDates = [ + protected array $booleanDates = [ 'has_accepted_terms_and_conditions' => 'accepted_terms_at', 'allows_data_processing' => 'accepted_processing_at', 'has_agreed_to_something' => 'agreed_to_something_at', From a4b8794d78a01beb0f2ee7f718e06fcd5a89113e Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 12:35:35 +0100 Subject: [PATCH 16/45] Tweak PHPUnit config --- phpunit.xml.dist | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 08a1dbe..9a29d1a 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,16 +1,17 @@ - From 2f82ef20b9fbf3ca8d93ccbf6d36a332c3f972de Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 12:37:11 +0100 Subject: [PATCH 17/45] Add PHP CS Fixer --- .php-cs-fixer.dist.php | 242 +++++++++++++++++++++++++++++++++++++++++ composer.json | 23 ++-- config/flow.php | 5 - 3 files changed, 255 insertions(+), 15 deletions(-) create mode 100644 .php-cs-fixer.dist.php delete mode 100644 config/flow.php diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000..8db5cb0 --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,242 @@ + true, + '@PSR2' => true, + '@PhpCsFixer' => true, + '@Symfony' => true, + '@PHP70Migration' => true, + '@PHP70Migration:risky' => true, + '@PHP71Migration' => true, + '@PHP71Migration:risky' => true, + '@PHP73Migration' => true, + '@PHPUnit75Migration:risky' => true, + 'final_class' => false, + 'new_with_braces' => false, + 'strict_comparison' => true, + 'list_syntax' => ['syntax' => 'short'], + 'mb_str_functions' => true, + 'class_attributes_separation' => [ + 'elements' => [ + 'method' => 'one', + ], + ], + 'no_extra_blank_lines' => [ + 'tokens' => [ + 'break', + 'continue', + 'curly_brace_block', + 'extra', + 'parenthesis_brace_block', + 'return', + 'square_brace_block', + 'throw', + 'use', + 'use_trait', + 'switch', + + 'case', + 'default', + ], + ], + 'no_blank_lines_before_namespace' => false, + 'nullable_type_declaration_for_default_null_value' => true, + 'increment_style' => ['style' => 'pre'], + 'self_static_accessor' => true, + 'static_lambda' => false, + 'no_empty_phpdoc' => true, + 'no_superfluous_phpdoc_tags' => [ + 'remove_inheritdoc' => true, + ], + 'phpdoc_line_span' => [ + 'const' => 'multi', + 'method' => 'multi', + 'property' => 'multi', + ], + 'general_phpdoc_tag_rename' => true, + 'phpdoc_add_missing_param_annotation' => ['only_untyped' => true], + 'phpdoc_align' => ['align' => 'left'], + 'phpdoc_indent' => true, + 'phpdoc_inline_tag_normalizer' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => false, + 'phpdoc_no_package' => true, + 'phpdoc_no_useless_inheritdoc' => true, + 'phpdoc_order' => true, + 'phpdoc_order_by_value' => false, + 'phpdoc_scalar' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_summary' => true, + 'phpdoc_tag_casing' => ['tags' => ['inheritDoc']], + 'phpdoc_tag_type' => true, + 'phpdoc_to_comment' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => ['groups' => ['simple', 'alias']], + 'phpdoc_types_order' => ['null_adjustment' => 'always_last'], + 'phpdoc_var_annotation_correct_order' => true, + 'phpdoc_var_without_name' => true, + 'align_multiline_comment' => ['comment_type' => 'phpdocs_like'], + 'php_unit_test_class_requires_covers' => false, + 'php_unit_internal_class' => false, + 'yoda_style' => false, + 'ordered_class_elements' => [ + 'order' => [ + 'use_trait', + 'constant_public', + 'constant_protected', + 'constant_private', + + 'property_static', + 'property_public_static', + 'property_protected_static', + 'property_private_static', + + 'property', + 'property_public', + 'property_protected', + 'property_private', + + 'construct', + 'destruct', + 'magic', + + 'method_static', + 'method_public_abstract_static', + 'method_public_static', + 'method_protected_abstract_static', + 'method_protected_static', + 'method_private_static', + 'method_public_abstract', + 'method_public', + 'method_protected_abstract', + 'method_protected', + 'method_private', + ], + ], + 'array_syntax' => ['syntax' => 'short'], + 'blank_line_after_namespace' => true, + 'blank_line_after_opening_tag' => true, + 'braces' => true, + 'cast_spaces' => true, + 'concat_space' => [ + 'spacing' => 'none', + ], + 'declare_equal_normalize' => true, + 'elseif' => true, + 'encoding' => true, + 'full_opening_tag' => true, + 'fully_qualified_strict_types' => true, // added by Shift + 'function_declaration' => true, + 'function_typehint_space' => true, + 'heredoc_to_nowdoc' => true, + 'include' => true, + 'indentation_type' => true, + 'linebreak_after_opening_tag' => true, + 'line_ending' => true, + 'lowercase_cast' => true, + 'lowercase_keywords' => true, + 'lowercase_static_reference' => true, // added from Symfony + 'magic_method_casing' => true, // added from Symfony + 'magic_constant_casing' => true, + 'method_argument_space' => true, + 'native_function_casing' => true, + 'no_alias_functions' => false, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_closing_tag' => true, + 'no_empty_statement' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => [ + 'use' => 'echo', + ], + 'no_multiline_whitespace_around_double_arrow' => true, + 'multiline_whitespace_before_semicolons' => [ + 'strategy' => 'no_multi_line', + ], + 'no_short_bool_cast' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_trailing_comma_in_list_call' => false, + 'no_trailing_comma_in_singleline_array' => true, + 'no_trailing_whitespace' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_unreachable_default_argument_value' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'normalize_index_brace' => true, + 'not_operator_with_successor_space' => true, + 'object_operator_without_whitespace' => true, + 'self_accessor' => false, + 'short_scalar_cast' => true, + 'simplified_null_return' => false, // disabled by Shift + 'single_blank_line_at_eof' => true, + 'single_blank_line_before_namespace' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'single_line_comment_style' => [ + 'comment_types' => ['hash'], + ], + 'single_quote' => true, + 'space_after_semicolon' => true, + 'standardize_not_equals' => true, + 'switch_case_semicolon_to_colon' => true, + 'switch_case_space' => true, + 'ternary_operator_spaces' => true, + 'trim_array_spaces' => true, + 'unary_operator_spaces' => true, + 'whitespace_after_comma_in_array' => true, + 'constant_case' => ['case' => 'lower'], + 'psr_autoloading' => true, + 'trailing_comma_in_multiline' => ['elements' => ['arrays']], + 'binary_operator_spaces' => [ + 'default' => 'single_space', + ], + 'types_spaces' => [ + 'space' => 'none', + ], + 'blank_line_before_statement' => [ + 'statements' => ['return'], + ], + 'class_definition' => [ + 'multi_line_extends_each_single_line' => true, + 'single_item_single_line' => true, + 'single_line' => true, + ], + 'ordered_imports' => [ + 'sort_algorithm' => 'alpha', + ], + 'no_unneeded_control_parentheses' => [ + 'statements' => ['break', 'clone', 'continue', 'echo_print', 'return', 'switch_case', 'yield'], + ], + 'no_spaces_around_offset' => [ + 'positions' => ['inside', 'outside'], + ], + 'visibility_required' => [ + 'elements' => ['property', 'method', 'const'], + ], +]; + +$finder = Finder::create() + ->in([ + __DIR__.'/src', + __DIR__.'/tests', + ]) + ->name('*.php') + ->notName('*.blade.php') + ->ignoreDotFiles(true) + ->ignoreVCS(true); + +return (new Config) + ->setRules($rules) + ->setFinder($finder) + ->setRiskyAllowed(true) + ->setUsingCache(true); diff --git a/composer.json b/composer.json index c7eae85..570c59a 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,7 @@ }, "require-dev": { "dms/phpunit-arraysubset-asserts": "^0.4.0", + "friendsofphp/php-cs-fixer": "^3.7", "mockery/mockery": "^1.5", "orchestra/testbench": "^v6.24|^7.1", "phpunit/phpunit": "^9.5" @@ -57,20 +58,22 @@ } }, "scripts": { - "composer-validate": "@composer validate --no-check-all --strict --ansi", + "composer:validate": "@composer validate --no-check-all --strict --ansi", "test": "vendor/bin/phpunit", - "test-lowest": [ - "composer update --prefer-lowest --prefer-dist --no-interaction --ansi", + "lint": "vendor/bin/php-cs-fixer fix --dry-run --diff --ansi", + "fix": "vendor/bin/php-cs-fixer fix --ansi", + "check": [ + "@composer:validate", + "@lint", "@test" ], - "test-stable": [ - "composer update --prefer-stable --prefer-dist --no-interaction --ansi", - "@test" + "check-lowest": [ + "composer update --prefer-lowest --prefer-dist --no-interaction --ansi", + "@check" ], - "check": [ - "@composer-validate", - "@test" + "check-stable": [ + "composer update --prefer-stable --prefer-dist --no-interaction --ansi", + "@check" ] } } - diff --git a/config/flow.php b/config/flow.php deleted file mode 100644 index ca5d8ed..0000000 --- a/config/flow.php +++ /dev/null @@ -1,5 +0,0 @@ - Date: Tue, 8 Mar 2022 12:38:31 +0100 Subject: [PATCH 18/45] Format code --- src/HasBooleanDates.php | 2 -- tests/Feature/BooleanArrayTest.php | 4 ++-- tests/Feature/BooleanAttributeTest.php | 20 ++++++++++---------- tests/Feature/BooleanDateTest.php | 6 +++--- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/HasBooleanDates.php b/src/HasBooleanDates.php index a3c8539..25ceb2f 100644 --- a/src/HasBooleanDates.php +++ b/src/HasBooleanDates.php @@ -14,8 +14,6 @@ trait HasBooleanDates * * Keys and values should be in the format: `'boolean_field' => * 'internal_timestamp_field'`. - * - * @var array */ protected array $booleanDates = []; diff --git a/tests/Feature/BooleanArrayTest.php b/tests/Feature/BooleanArrayTest.php index 835a55c..151f21e 100644 --- a/tests/Feature/BooleanArrayTest.php +++ b/tests/Feature/BooleanArrayTest.php @@ -16,7 +16,7 @@ class BooleanArrayTest extends TestCase /** * @test */ - public function it returns all boolean dates() : void + public function it returns all boolean dates(): void { $model = new TestModel; @@ -35,7 +35,7 @@ public function it returns all boolean dates() : void /** * @test */ - public function it returns all attributes() : void + public function it returns all attributes(): void { Carbon::setTestNow('2018-01-01 10:42:06'); diff --git a/tests/Feature/BooleanAttributeTest.php b/tests/Feature/BooleanAttributeTest.php index 8b42b4e..6b15309 100644 --- a/tests/Feature/BooleanAttributeTest.php +++ b/tests/Feature/BooleanAttributeTest.php @@ -13,7 +13,7 @@ class BooleanAttributeTest extends TestCase /** * @test */ - public function it skips returning invalid fields() : void + public function it skips returning invalid fields(): void { $model = new TestModel; @@ -26,7 +26,7 @@ public function it skips returning invalid fields() : void /** * @test */ - public function it leaves other attributes untouched() : void + public function it leaves other attributes untouched(): void { $model = new TestModel; @@ -41,7 +41,7 @@ public function it leaves other attributes untouched() : void /** * @test */ - public function it sets the date from a true boolean() : void + public function it sets the date from a true boolean(): void { $model = new TestModel; @@ -56,7 +56,7 @@ public function it sets the date from a true boolean() : void /** * @test */ - public function it sets the date from a non empty string() : void + public function it sets the date from a non empty string(): void { $model = new TestModel; @@ -71,7 +71,7 @@ public function it sets the date from a non empty string() : void /** * @test */ - public function it sets the date from a positive integer value() : void + public function it sets the date from a positive integer value(): void { $model = new TestModel; @@ -86,7 +86,7 @@ public function it sets the date from a positive integer value() : void /** * @test */ - public function it sets the date from a positive integer string value() : void + public function it sets the date from a positive integer string value(): void { $model = new TestModel; @@ -101,7 +101,7 @@ public function it sets the date from a positive integer string value() /** * @test */ - public function it clears the date from a false boolean() : void + public function it clears the date from a false boolean(): void { $model = new TestModel; @@ -113,7 +113,7 @@ public function it clears the date from a false boolean() : void /** * @test */ - public function it clears the date from null() : void + public function it clears the date from null(): void { $model = new TestModel; @@ -125,7 +125,7 @@ public function it clears the date from null() : void /** * @test */ - public function it clears the date from a false string value() : void + public function it clears the date from a false string value(): void { $model = new TestModel; @@ -137,7 +137,7 @@ public function it clears the date from a false string value() : void /** * @test */ - public function it clears the date from an empty string value() : void + public function it clears the date from an empty string value(): void { $model = new TestModel; diff --git a/tests/Feature/BooleanDateTest.php b/tests/Feature/BooleanDateTest.php index 1575981..021cdab 100644 --- a/tests/Feature/BooleanDateTest.php +++ b/tests/Feature/BooleanDateTest.php @@ -13,7 +13,7 @@ class BooleanDateTest extends TestCase /** * @test */ - public function it leaves other date attributes untouched() : void + public function it leaves other date attributes untouched(): void { $model = new TestModel; @@ -28,7 +28,7 @@ public function it leaves other date attributes untouched() : void /** * @test */ - public function it returns a date object from a true attribute() : void + public function it returns a date object from a true attribute(): void { $model = new TestModel; @@ -48,7 +48,7 @@ public function it returns a date object from a true attribute() : void /** * @test */ - public function it returns null from a false attribute() : void + public function it returns null from a false attribute(): void { $model = new TestModel; From ff38d9aba2c44044d7c16dd8fe6add452c34cbae Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 12:47:59 +0100 Subject: [PATCH 19/45] WIP --- src/HasBooleanDates.php | 9 --------- tests/resources/TestModel.php | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/HasBooleanDates.php b/src/HasBooleanDates.php index 25ceb2f..e28d395 100644 --- a/src/HasBooleanDates.php +++ b/src/HasBooleanDates.php @@ -8,15 +8,6 @@ trait HasBooleanDates { - /** - * Set the date of fields to the current date and time if a counterpart - * boolean field is true-ish. - * - * Keys and values should be in the format: `'boolean_field' => - * 'internal_timestamp_field'`. - */ - protected array $booleanDates = []; - public function initializeHasBooleanDates(): void { $this->dates = array_unique( diff --git a/tests/resources/TestModel.php b/tests/resources/TestModel.php index c275eee..2ddcd8d 100644 --- a/tests/resources/TestModel.php +++ b/tests/resources/TestModel.php @@ -11,6 +11,15 @@ class TestModel extends Model { use HasBooleanDates; + /** + * Set the date of fields to the current date and time if a counterpart + * boolean field is true-ish. + * + * Keys and values should be in the format: `'boolean_field' => + * 'internal_timestamp_field'`. + * + * @var array + */ protected array $booleanDates = [ 'has_accepted_terms_and_conditions' => 'accepted_terms_at', 'allows_data_processing' => 'accepted_processing_at', From b42f85900c8cbaee1d3e3765dccb92c4c330df9e Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 13:07:20 +0100 Subject: [PATCH 20/45] Drop support for Laravel 8 --- CHANGELOG.md | 2 +- composer.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15ddd6b..a6a4b5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip ### Removed - Dropped support for PHP 7.x -- Dropped support for Laravel 7 +- Dropped support for Laravel 7 and 8 - Removed requirements for `nesbot/carbon` ## 5.0.0 (2020-10-19) diff --git a/composer.json b/composer.json index 570c59a..d12037c 100644 --- a/composer.json +++ b/composer.json @@ -26,13 +26,13 @@ ], "require": { "php": "^8.0|^8.1", - "illuminate/support": "^8.0|^9.0" + "illuminate/support": "^9.0" }, "require-dev": { "dms/phpunit-arraysubset-asserts": "^0.4.0", "friendsofphp/php-cs-fixer": "^3.7", "mockery/mockery": "^1.5", - "orchestra/testbench": "^v6.24|^7.1", + "orchestra/testbench": "^7.1", "phpunit/phpunit": "^9.5" }, "autoload": { From 26d12ac3effef1074f7d78f3b94228f39f861f01 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 13:21:58 +0100 Subject: [PATCH 21/45] WIP --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index c451dda..7d38cf2 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,5 +14,5 @@ trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false -[*.yml] +[*.{yml,yaml}] indent_size = 2 From e778dcbfa8fcb899cf64a99cd7d6a7a23dc96ea5 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 13:22:01 +0100 Subject: [PATCH 22/45] WIP --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index d12037c..89b02d4 100644 --- a/composer.json +++ b/composer.json @@ -58,7 +58,7 @@ } }, "scripts": { - "composer:validate": "@composer validate --no-check-all --strict --ansi", + "composer:validate": "@composer validate --strict --ansi", "test": "vendor/bin/phpunit", "lint": "vendor/bin/php-cs-fixer fix --dry-run --diff --ansi", "fix": "vendor/bin/php-cs-fixer fix --ansi", From 993e64a3cfea0869a104fe638e8f49d559a785b0 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 13:22:11 +0100 Subject: [PATCH 23/45] Add GH Actions test workflow --- .github/workflows/test.yml | 57 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..e8a0258 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,57 @@ +name: Check code + +on: + push: + pull_request: + +jobs: + + check: + name: Run PHP tests - PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - ${{ matrix.dependency-version }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + php: [8.0, 8.1] + laravel: [9.*] + dependency-version: [prefer-lowest, prefer-stable] + os: [ubuntu-latest] + + steps: + - name: Check out code + uses: actions/checkout@v2 + + - name: Cache PHP dependencies + uses: actions/cache@v2 + with: + path: '**/vendor' + key: ${{ runner.os }}-vendor-cache-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-vendor-cache- + + - name: Cache Composer dependencies + uses: actions/cache@v2 + with: + path: ~/.composer/cache/files + key: composer-${{ runner.os }}-php-${{ matrix.php }}-laravel-${{ matrix.laravel }}-${{ hashFiles('composer.json') }} + + - name: Validate Composer configuration file + run: composer validate --strict + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: mbstring + coverage: none + + - name: Install dependencies + run: | + composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-progress --no-update --no-suggest + composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader + + - name: Lint code + run: vendor/bin/php-cs-fixer fix --dry-run --diff + + - name: Run tests + run: vendor/bin/phpunit From f93efce0d0abeb34f471f2a37cbcb48f33e0fc61 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 13:25:18 +0100 Subject: [PATCH 24/45] Remove deprecating Composer option --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e8a0258..a4378f6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,8 +47,8 @@ jobs: - name: Install dependencies run: | - composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-progress --no-update --no-suggest - composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-progress --no-suggest --optimize-autoloader + composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-progress --no-update + composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-progress --optimize-autoloader - name: Lint code run: vendor/bin/php-cs-fixer fix --dry-run --diff From d7c16498197effc74d25af9440a6c6054ac9fe00 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 13:28:41 +0100 Subject: [PATCH 25/45] Use Illuminate\Support\Carbon --- tests/Feature/BooleanArrayTest.php | 2 +- tests/Feature/BooleanAttributeTest.php | 2 +- tests/Feature/BooleanDateTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Feature/BooleanArrayTest.php b/tests/Feature/BooleanArrayTest.php index 151f21e..8cf3598 100644 --- a/tests/Feature/BooleanArrayTest.php +++ b/tests/Feature/BooleanArrayTest.php @@ -4,8 +4,8 @@ namespace SebastiaanLuca\BooleanDates\Tests\Feature; -use Carbon\Carbon; use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts; +use Illuminate\Support\Carbon; use SebastiaanLuca\BooleanDates\Tests\resources\TestModel; use SebastiaanLuca\BooleanDates\Tests\TestCase; diff --git a/tests/Feature/BooleanAttributeTest.php b/tests/Feature/BooleanAttributeTest.php index 6b15309..0a67c4f 100644 --- a/tests/Feature/BooleanAttributeTest.php +++ b/tests/Feature/BooleanAttributeTest.php @@ -4,7 +4,7 @@ namespace SebastiaanLuca\BooleanDates\Tests\Feature; -use Carbon\Carbon; +use Illuminate\Support\Carbon; use SebastiaanLuca\BooleanDates\Tests\resources\TestModel; use SebastiaanLuca\BooleanDates\Tests\TestCase; diff --git a/tests/Feature/BooleanDateTest.php b/tests/Feature/BooleanDateTest.php index 021cdab..4434581 100644 --- a/tests/Feature/BooleanDateTest.php +++ b/tests/Feature/BooleanDateTest.php @@ -4,7 +4,7 @@ namespace SebastiaanLuca\BooleanDates\Tests\Feature; -use Carbon\Carbon; +use Illuminate\Support\Carbon; use SebastiaanLuca\BooleanDates\Tests\resources\TestModel; use SebastiaanLuca\BooleanDates\Tests\TestCase; From b31743813fbe6e43086c9b10ce326ef6ca711996 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 13:41:57 +0100 Subject: [PATCH 26/45] Update changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a6a4b5f..1809359 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All Notable changes to `sebastiaanluca/laravel-boolean-dates` will be documented Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles. -## 6.0.0 (2022-03-09) +## 6.0.0 (2022-03-08) ### Added @@ -12,8 +12,9 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip ### Changed -- Cleaned up code internally - Switched to using `\Illuminate\Support\Carbon` instead of `\Carbon\Carbon` +- Switched to using `$casts` internally as `$dates` is deprecated +- Cleaned up code internally ### Removed From 50b0229d4920aaa36b83b6a2d571f670414626dd Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 15:50:49 +0100 Subject: [PATCH 27/45] WIP --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1809359..342d10c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,8 +12,8 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip ### Changed -- Switched to using `\Illuminate\Support\Carbon` instead of `\Carbon\Carbon` - Switched to using `$casts` internally as `$dates` is deprecated +- Switched to using `\Illuminate\Support\Carbon` and `\Carbon\CarbonImmutable` instead of `\Carbon\Carbon` - Cleaned up code internally ### Removed From 76c7aac97ee11c755409aaef9d1d6eccdfd2279b Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Tue, 8 Mar 2022 16:49:11 +0100 Subject: [PATCH 28/45] Update changelog --- CHANGELOG.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 342d10c..5dd5124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All Notable changes to `sebastiaanluca/laravel-boolean-dates` will be documented Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles. -## 6.0.0 (2022-03-08) +## Unreleased ### Added @@ -12,7 +12,6 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip ### Changed -- Switched to using `$casts` internally as `$dates` is deprecated - Switched to using `\Illuminate\Support\Carbon` and `\Carbon\CarbonImmutable` instead of `\Carbon\Carbon` - Cleaned up code internally From 67f5ced59e715141d076730e5287961dded1fb82 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 13:35:42 +0100 Subject: [PATCH 29/45] Add BooleanDateAttribute class --- src/BooleanDateAttribute.php | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/BooleanDateAttribute.php diff --git a/src/BooleanDateAttribute.php b/src/BooleanDateAttribute.php new file mode 100644 index 0000000..3de1eda --- /dev/null +++ b/src/BooleanDateAttribute.php @@ -0,0 +1,30 @@ + $attributes[$column] !== null, + set: static fn (bool $value, array $attributes): array => static::setBooleanDate($value, $attributes, $column), + ); + } + + private static function setBooleanDate(bool $value, array $attributes, string $column): array + { + // Only update the field if it's never been set before or when it's being "disabled" + + if ($value === false || ! array_key_exists($column, $attributes) || $attributes[$column] === null) { + return [$column => $value === false ? null : CarbonImmutable::now()]; + } + + return []; + } +} From 92b655a6960eb9993787a31d06c9759d31e07175 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 13:35:46 +0100 Subject: [PATCH 30/45] Update readme --- README.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 747a52b..4329c8f 100644 --- a/README.md +++ b/README.md @@ -71,27 +71,60 @@ $user->accepted_terms_and_conditions_at; composer require sebastiaanluca/laravel-boolean-dates ``` -**Require the `HasBooleanDates` trait** in your Eloquent model, then add the `$booleanDates` field: +**Set up your Eloquent model** by: + +1. Adding your datetime columns to `$casts` +2. Adding the boolean attributes to `$appends` +3. Creating attribute accessors mutators for each field ```php 'accepted_terms_at', - 'allows_data_processing' => 'accepted_processing_at', - 'has_agreed_to_something' => 'agreed_to_something_at', + /** + * The attributes that should be cast to native types. + * + * @var array + */ + protected $casts = [ + 'accepted_terms_at' => 'immutable_datetime', + 'allowed_data_processing_at' => 'immutable_datetime', + 'subscribed_to_newsletter_at' => 'immutable_datetime', + ]; + + /** + * The accessors to append to the model's array form. + * + * @var array + */ + protected $appends = [ + 'has_accepted_terms', + 'has_allowed_data_processing', + 'has_subscribed_to_newsletter', ]; + + protected function hasAcceptedTerms(): Attribute + { + return BooleanDateAttribute::for('accepted_terms_at'); + } + + protected function hasAllowedDataProcessing(): Attribute + { + return BooleanDateAttribute::for('allowed_data_processing_at'); + } + + protected function hasSubscribedToNewsletter(): Attribute + { + return BooleanDateAttribute::for('subscribed_to_newsletter_at'); + } } ``` -To wrap up, create a **migration** to create a new table or alter your existing table to add the timestamp fields: +Optionally, if your database table hasn't got the datetime columns yet, create a **migration** to create a new table or alter your existing table to add the timestamp fields: ```php timestamp('accepted_terms_at')->nullable(); - $table->timestamp('accepted_processing_at')->nullable(); - $table->timestamp('agreed_to_something_at')->nullable(); + $table->timestamp('allowed_data_processing_at')->nullable(); + $table->timestamp('subscribed_to_newsletter_at')->nullable(); }); } }; @@ -136,6 +169,22 @@ $user->save(); All fields should now contain a datetime similar to `2018-05-10 16:24:22`. +Note that the date stored in the database column **is immutable, i.e. it's only set once**. Any following updates will not change the stored date(time), unless you update the date column manually or if you set it to `false` and back to `true`. + +```php +$user = new User; + +$user->has_accepted_terms_and_conditions = true; +$user->save(); + +// `accepted_terms_at` column will contain `2022-03-13 13:20:00` + +$user->has_accepted_terms_and_conditions = true; +$user->save(); + +// `accepted_terms_at` column will still contain the original `2022-03-13 13:20:00` date +``` + ### Clearing saved values Of course you can also remove the saved date and time, for instance if a user retracts their approval: From 725d33e0aa1ec3cf27204c75f56cc4176e98266a Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:07:32 +0100 Subject: [PATCH 31/45] Support mixed input --- src/BooleanDateAttribute.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BooleanDateAttribute.php b/src/BooleanDateAttribute.php index 3de1eda..1056af7 100644 --- a/src/BooleanDateAttribute.php +++ b/src/BooleanDateAttribute.php @@ -13,11 +13,11 @@ public static function for(string $column): static { return parent::make( get: static fn (?string $value, array $attributes): bool => $attributes[$column] !== null, - set: static fn (bool $value, array $attributes): array => static::setBooleanDate($value, $attributes, $column), + set: static fn (mixed $value, array $attributes): array => static::setBooleanDate($value, $attributes, $column), ); } - private static function setBooleanDate(bool $value, array $attributes, string $column): array + private static function setBooleanDate(mixed $value, array $attributes, string $column): array { // Only update the field if it's never been set before or when it's being "disabled" From b05307ded607112a75ea8ae8b7f845cd83ff8f3e Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:07:36 +0100 Subject: [PATCH 32/45] Update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dd5124..78a0857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip ## Unreleased +⚠️ This release is a complete rewrite and changes the way it has to be used. Please consult the [README](README.md) for instructions. + ### Added - Added support for Laravel 9 @@ -14,12 +16,14 @@ Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) princip - Switched to using `\Illuminate\Support\Carbon` and `\Carbon\CarbonImmutable` instead of `\Carbon\Carbon` - Cleaned up code internally +- Added `BooleanDateAttribute` ### Removed - Dropped support for PHP 7.x - Dropped support for Laravel 7 and 8 - Removed requirements for `nesbot/carbon` +- Removed `HasBooleanDates` trait ## 5.0.0 (2020-10-19) From 5a8132b5ba8c0feebefbb15d4a3a6d7490c81082 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:09:35 +0100 Subject: [PATCH 33/45] Allow truth-y false-y values --- src/BooleanDateAttribute.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/BooleanDateAttribute.php b/src/BooleanDateAttribute.php index 1056af7..ac508b8 100644 --- a/src/BooleanDateAttribute.php +++ b/src/BooleanDateAttribute.php @@ -21,8 +21,8 @@ private static function setBooleanDate(mixed $value, array $attributes, string $ { // Only update the field if it's never been set before or when it's being "disabled" - if ($value === false || ! array_key_exists($column, $attributes) || $attributes[$column] === null) { - return [$column => $value === false ? null : CarbonImmutable::now()]; + if (! $value || ! array_key_exists($column, $attributes) || $attributes[$column] === null) { + return [$column => ! $value ? null : CarbonImmutable::now()]; } return []; From 98af496aebe46a59a2d3208810d44b4fcf02b772 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:12:20 +0100 Subject: [PATCH 34/45] Handle boolean date attribute not being set yet --- src/BooleanDateAttribute.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/BooleanDateAttribute.php b/src/BooleanDateAttribute.php index ac508b8..39132ef 100644 --- a/src/BooleanDateAttribute.php +++ b/src/BooleanDateAttribute.php @@ -12,11 +12,16 @@ class BooleanDateAttribute extends Attribute public static function for(string $column): static { return parent::make( - get: static fn (?string $value, array $attributes): bool => $attributes[$column] !== null, + get: static fn (?string $value, array $attributes): bool => static::getBooleanDate($value, $attributes, $column), set: static fn (mixed $value, array $attributes): array => static::setBooleanDate($value, $attributes, $column), ); } + private static function getBooleanDate(mixed $value, array $attributes, string $column): bool + { + return array_key_exists($column, $attributes) && $attributes[$column] !== null; + } + private static function setBooleanDate(mixed $value, array $attributes, string $column): array { // Only update the field if it's never been set before or when it's being "disabled" From 0647a12e6347ebc113e26851483f02b793afc0ef Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:24:55 +0100 Subject: [PATCH 35/45] Update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78a0857..601908d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All Notable changes to `sebastiaanluca/laravel-boolean-dates` will be documented Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles. -## Unreleased +## 6.0.0 (2022-03-13) ⚠️ This release is a complete rewrite and changes the way it has to be used. Please consult the [README](README.md) for instructions. From 2fc52e1bc5f8f3fa7ece0555265c2822cd68ec38 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:25:12 +0100 Subject: [PATCH 36/45] Update composer.json and remove test packages --- composer.json | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/composer.json b/composer.json index 89b02d4..b54415e 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,6 @@ "type": "library", "description": "Automatically convert Eloquent model boolean attributes to dates (and back).", "keywords": [ - "php", "bool", "boolean", "convert", @@ -12,6 +11,7 @@ "eloquent", "laravel", "model", + "php", "timestamps" ], "homepage": "https://github.com/sebastiaanluca/laravel-boolean-dates", @@ -20,7 +20,7 @@ { "name": "Sebastiaan Luca", "email": "hello@sebastiaanluca.com", - "homepage": "https://www.sebastiaanluca.com", + "homepage": "https://sebastiaanluca.com", "role": "Author" } ], @@ -29,9 +29,7 @@ "illuminate/support": "^9.0" }, "require-dev": { - "dms/phpunit-arraysubset-asserts": "^0.4.0", "friendsofphp/php-cs-fixer": "^3.7", - "mockery/mockery": "^1.5", "orchestra/testbench": "^7.1", "phpunit/phpunit": "^9.5" }, From 13ead806e2b2fcf932dbce325edc417581fa49c6 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:25:16 +0100 Subject: [PATCH 37/45] Format code --- src/BooleanDateAttribute.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/BooleanDateAttribute.php b/src/BooleanDateAttribute.php index 39132ef..3ad1847 100644 --- a/src/BooleanDateAttribute.php +++ b/src/BooleanDateAttribute.php @@ -25,7 +25,6 @@ private static function getBooleanDate(mixed $value, array $attributes, string $ private static function setBooleanDate(mixed $value, array $attributes, string $column): array { // Only update the field if it's never been set before or when it's being "disabled" - if (! $value || ! array_key_exists($column, $attributes) || $attributes[$column] === null) { return [$column => ! $value ? null : CarbonImmutable::now()]; } From 215036f18b53774085cd1cfa4a08321f35be8e0a Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:25:32 +0100 Subject: [PATCH 38/45] Remove deprecated classes --- src/BooleanDatesServiceProvider.php | 11 --- src/HasBooleanDates.php | 119 ---------------------------- 2 files changed, 130 deletions(-) delete mode 100644 src/BooleanDatesServiceProvider.php delete mode 100644 src/HasBooleanDates.php diff --git a/src/BooleanDatesServiceProvider.php b/src/BooleanDatesServiceProvider.php deleted file mode 100644 index b40da05..0000000 --- a/src/BooleanDatesServiceProvider.php +++ /dev/null @@ -1,11 +0,0 @@ -dates = array_unique( - array_merge( - $this->dates, - array_values($this->getBooleanDates()) - ) - ); - } - - public function attributesToArray(): array - { - $attributes = parent::attributesToArray(); - - return $this->addBooleanDateAttributesToArray($attributes); - } - - public function getAttribute($key) - { - if (! $key) { - return null; - } - - if ($this->hasBooleanDate($key)) { - return $this->getBooleanDate($key); - } - - return parent::getAttribute($key); - } - - public function setAttribute($key, $value) - { - if ($this->hasBooleanDate($key)) { - $this->setBooleanDate($key, $value); - - return $this; - } - - return parent::setAttribute($key, $value); - } - - public function getBooleanDates(): array - { - return $this->booleanDates ?? []; - } - - protected function getBooleanDateAttributes(): array - { - return array_intersect_key( - $this->getAttributes(), - array_flip($this->getBooleanDates()) - ); - } - - protected function getBooleanDate(string $key): bool - { - return parent::getAttribute($this->getBooleanDateField($key)) !== null; - } - - protected function setBooleanDate(string $key, mixed $value): void - { - // Only update the timestamp if the value is true and if it's not yet set - // or if the value is false and we need to unset the field. - if (! $value || ($value && $this->currentBooleanDateFieldValueIsNotYetSet($key))) { - // Set the value directly on the attributes array, don't use - // setAttribute, and don't receive $200. (\) (°,,,°) (/) - // This allows us to format and set the datetime ourselves, - // and makes using the $dates field optional. - $this->attributes[$this->getBooleanDateField($key)] = $this->getNewBooleanDateValue($value); - } - } - - protected function hasBooleanDate(string $key): bool - { - return array_key_exists($key, $this->getBooleanDates()); - } - - protected function currentBooleanDateFieldValueIsNotYetSet(string $key): bool - { - if (! array_key_exists($this->getBooleanDateField($key), $this->getAttributes())) { - return true; - } - - return parent::getAttribute($this->getBooleanDateField($key)) === null; - } - - protected function getBooleanDateField(string $key): string - { - return $this->booleanDates[$key]; - } - - protected function getNewBooleanDateValue(mixed $value): ?string - { - return $value ? $this->fromDateTime(Carbon::now()) : null; - } - - protected function addBooleanDateAttributesToArray(array $attributes): array - { - foreach ($this->getBooleanDates() as $booleanField => $date) { - if (! array_key_exists($date, $attributes)) { - continue; - } - - $attributes[$booleanField] = $this->getBooleanDate($booleanField); - } - - return $attributes; - } -} From cb1e9cc5031e3f7330e846748fd308f72d4b7658 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:25:47 +0100 Subject: [PATCH 39/45] Update tests --- composer.json | 8 - phpunit.xml.dist | 2 +- tests/BooleanAttributeTest.php | 266 +++++++++++++++++++++++++ tests/Feature/BooleanArrayTest.php | 69 ------- tests/Feature/BooleanAttributeTest.php | 148 -------------- tests/Feature/BooleanDateTest.php | 59 ------ tests/TestCase.php | 16 +- tests/TestModel.php | 54 +++++ tests/resources/TestModel.php | 28 --- 9 files changed, 322 insertions(+), 328 deletions(-) create mode 100644 tests/BooleanAttributeTest.php delete mode 100644 tests/Feature/BooleanArrayTest.php delete mode 100644 tests/Feature/BooleanAttributeTest.php delete mode 100644 tests/Feature/BooleanDateTest.php create mode 100644 tests/TestModel.php delete mode 100644 tests/resources/TestModel.php diff --git a/composer.json b/composer.json index b54415e..aee3ac4 100644 --- a/composer.json +++ b/composer.json @@ -30,7 +30,6 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.7", - "orchestra/testbench": "^7.1", "phpunit/phpunit": "^9.5" }, "autoload": { @@ -48,13 +47,6 @@ }, "minimum-stability": "dev", "prefer-stable": true, - "extra": { - "laravel": { - "providers": [ - "SebastiaanLuca\\BooleanDates\\BooleanDatesServiceProvider" - ] - } - }, "scripts": { "composer:validate": "@composer validate --strict --ansi", "test": "vendor/bin/phpunit", diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9a29d1a..a753534 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -20,7 +20,7 @@ - tests/Feature + tests diff --git a/tests/BooleanAttributeTest.php b/tests/BooleanAttributeTest.php new file mode 100644 index 0000000..95f1bcb --- /dev/null +++ b/tests/BooleanAttributeTest.php @@ -0,0 +1,266 @@ + 1, + 'subscribed_to_newsletter_at' => now(), + ]); + + $this->assertInstanceOf(CarbonImmutable::class, $model->accepted_terms_at); + $this->assertTrue($model->has_accepted_terms); + + $this->assertInstanceOf(Carbon::class, $model->subscribed_to_newsletter_at); + $this->assertTrue($model->is_subscribed_to_newsletter); + } + + /** + * @test + */ + public function it can handle empty initial values(): void + { + $model = new TestModel; + + $this->assertNull($model->accepted_terms_at); + $this->assertFalse($model->has_accepted_terms); + } + + /** + * @test + */ + public function it can enable a boolean attribute(): void + { + $model = new TestModel; + + $model->has_accepted_terms = false; + + $this->assertNull($model->accepted_terms_at); + $this->assertFalse($model->has_accepted_terms); + + $model->has_accepted_terms = true; + + $this->assertInstanceOf(CarbonImmutable::class, $model->accepted_terms_at); + $this->assertTrue($model->has_accepted_terms); + } + + /** + * @test + */ + public function it can disable a boolean attribute(): void + { + $model = new TestModel; + + $model->has_accepted_terms = true; + + $this->assertInstanceOf(CarbonImmutable::class, $model->accepted_terms_at); + $this->assertTrue($model->has_accepted_terms); + + $model->has_accepted_terms = false; + + $this->assertNull($model->accepted_terms_at); + $this->assertFalse($model->has_accepted_terms); + } + + /** + * @test + */ + public function it cannot enable a boolean attribute twice and change its date(): void + { + Carbon::setTestNow('2022-03-13 14:31:00'); + + $model = new TestModel; + + $model->has_accepted_terms = true; + + $this->assertInstanceOf(CarbonImmutable::class, $model->accepted_terms_at); + $this->assertSame('2022-03-13 14:31:00', $model->accepted_terms_at->toDateTimeString()); + $this->assertTrue($model->has_accepted_terms); + + $model->has_accepted_terms = true; + + $this->assertInstanceOf(CarbonImmutable::class, $model->accepted_terms_at); + $this->assertSame('2022-03-13 14:31:00', $model->accepted_terms_at->toDateTimeString()); + $this->assertTrue($model->has_accepted_terms); + } + + /** + * @test + */ + public function it can enable a boolean attribute twice if it was disabled(): void + { + Carbon::setTestNow('2022-03-13 14:00:00'); + + $model = new TestModel; + + $model->is_subscribed_to_newsletter = true; + + $this->assertInstanceOf(Carbon::class, $model->subscribed_to_newsletter_at); + $this->assertSame('2022-03-13 14:00:00', $model->subscribed_to_newsletter_at->toDateTimeString()); + $this->assertTrue($model->is_subscribed_to_newsletter); + + Carbon::setTestNow('2022-03-20 15:00:00'); + + $model->is_subscribed_to_newsletter = false; + + $this->assertNull($model->subscribed_to_newsletter_at); + $this->assertFalse($model->is_subscribed_to_newsletter); + + $model->is_subscribed_to_newsletter = true; + + $this->assertInstanceOf(Carbon::class, $model->subscribed_to_newsletter_at); + $this->assertSame('2022-03-20 15:00:00', $model->subscribed_to_newsletter_at->toDateTimeString()); + $this->assertTrue($model->is_subscribed_to_newsletter); + } + + /** + * @test + */ + public function it can enable a boolean attribute from a boolean(): void + { + $model = new TestModel; + + $model->has_accepted_terms = true; + + $this->assertInstanceOf(CarbonImmutable::class, $model->accepted_terms_at); + + $this->assertSame( + Carbon::now()->format('Y-m-d H:i'), + $model->accepted_terms_at->format('Y-m-d H:i') + ); + } + + /** + * @test + */ + public function it can enable a boolean attribute from a string(): void + { + $model = new TestModel; + + $model->has_accepted_terms = 'yes'; + + $this->assertSame( + Carbon::now()->format('Y-m-d H:i'), + $model->accepted_terms_at->format('Y-m-d H:i') + ); + } + + /** + * @test + */ + public function it can enable a boolean attribute from an integer string(): void + { + $model = new TestModel; + + $model->has_accepted_terms = '1'; + + $this->assertSame( + Carbon::now()->format('Y-m-d H:i'), + $model->accepted_terms_at->format('Y-m-d H:i') + ); + } + + /** + * @test + */ + public function it can enable a boolean attribute from an integer(): void + { + $model = new TestModel; + + $model->is_subscribed_to_newsletter = 1; + + $this->assertSame( + Carbon::now()->format('Y-m-d H:i'), + $model->subscribed_to_newsletter_at->format('Y-m-d H:i') + ); + } + + /** + * @test + */ + public function it can disable a boolean attribute from a boolean(): void + { + $model = new TestModel; + + $model->allows_data_processing = false; + + $this->assertNull($model->accepted_processing_at); + } + + /** + * @test + */ + public function it can disable a boolean attribute from null(): void + { + $model = new TestModel; + + $model->has_agreed_to_something = null; + + $this->assertNull($model->agreed_to_something_at); + } + + /** + * @test + */ + public function it can disable a boolean attribute from an integer string(): void + { + $model = new TestModel; + + $model->has_accepted_terms = '0'; + + $this->assertNull($model->accepted_terms_at); + } + + /** + * @test + */ + public function it can disable a boolean attribute from an integer(): void + { + $model = new TestModel; + + $model->has_accepted_terms = 0; + + $this->assertNull($model->accepted_terms_at); + } + + /** + * @test + */ + public function it returns all attributes(): void + { + Carbon::setTestNow('2018-01-01 10:42:06'); + + $model = new TestModel; + + $model->something = 'something'; + + $model->has_accepted_terms = 0; + $model->is_subscribed_to_newsletter = 1; + + $expected = [ + 'something' => 'something', + + 'accepted_terms_at' => null, + 'subscribed_to_newsletter_at' => '2018-01-01T10:42:06.000000Z', + + 'has_accepted_terms' => false, + 'is_subscribed_to_newsletter' => true, + ]; + + $this->assertSame( + $expected, + $model->toArray(), + ); + } +} diff --git a/tests/Feature/BooleanArrayTest.php b/tests/Feature/BooleanArrayTest.php deleted file mode 100644 index 8cf3598..0000000 --- a/tests/Feature/BooleanArrayTest.php +++ /dev/null @@ -1,69 +0,0 @@ - 'accepted_terms_at', - 'allows_data_processing' => 'accepted_processing_at', - 'has_agreed_to_something' => 'agreed_to_something_at', - ]; - - $this->assertSame( - $expected, - $model->getBooleanDates() - ); - } - - /** - * @test - */ - public function it returns all attributes(): void - { - Carbon::setTestNow('2018-01-01 10:42:06'); - - $model = new TestModel; - - $model->something = 'something'; - $model->tested_at = Carbon::now(); - - $model->has_accepted_terms_and_conditions = false; - $model->allows_data_processing = true; - $model->has_agreed_to_something = '0'; - - $expected = [ - 'something' => 'something', - 'tested_at' => '2018-01-01 10:42:06', - - 'has_accepted_terms_and_conditions' => false, - 'allows_data_processing' => true, - 'has_agreed_to_something' => false, - - 'accepted_terms_at' => null, - 'accepted_processing_at' => '2018-01-01T10:42:06.000000Z', - 'agreed_to_something_at' => null, - ]; - - ArraySubsetAsserts::assertArraySubset( - $expected, - $model->toArray() - ); - } -} diff --git a/tests/Feature/BooleanAttributeTest.php b/tests/Feature/BooleanAttributeTest.php deleted file mode 100644 index 0a67c4f..0000000 --- a/tests/Feature/BooleanAttributeTest.php +++ /dev/null @@ -1,148 +0,0 @@ -assertNull($model->getAttribute(null)); - $this->assertNull($model->getAttribute(false)); - $this->assertNull($model->getAttribute('')); - $this->assertNull($model->getAttribute('0')); - } - - /** - * @test - */ - public function it leaves other attributes untouched(): void - { - $model = new TestModel; - - $model->something = 'something'; - - $this->assertSame( - 'something', - $model->something - ); - } - - /** - * @test - */ - public function it sets the date from a true boolean(): void - { - $model = new TestModel; - - $model->has_accepted_terms_and_conditions = true; - - $this->assertSame( - Carbon::now()->format('Y-m-d H:i'), - $model->accepted_terms_at->format('Y-m-d H:i') - ); - } - - /** - * @test - */ - public function it sets the date from a non empty string(): void - { - $model = new TestModel; - - $model->has_accepted_terms_and_conditions = 'yes'; - - $this->assertSame( - Carbon::now()->format('Y-m-d H:i'), - $model->accepted_terms_at->format('Y-m-d H:i') - ); - } - - /** - * @test - */ - public function it sets the date from a positive integer value(): void - { - $model = new TestModel; - - $model->has_agreed_to_something = 1; - - $this->assertSame( - Carbon::now()->format('Y-m-d H:i'), - $model->agreed_to_something_at->format('Y-m-d H:i') - ); - } - - /** - * @test - */ - public function it sets the date from a positive integer string value(): void - { - $model = new TestModel; - - $model->has_accepted_terms_and_conditions = '1'; - - $this->assertSame( - Carbon::now()->format('Y-m-d H:i'), - $model->accepted_terms_at->format('Y-m-d H:i') - ); - } - - /** - * @test - */ - public function it clears the date from a false boolean(): void - { - $model = new TestModel; - - $model->allows_data_processing = false; - - $this->assertNull($model->accepted_processing_at); - } - - /** - * @test - */ - public function it clears the date from null(): void - { - $model = new TestModel; - - $model->has_agreed_to_something = null; - - $this->assertNull($model->agreed_to_something_at); - } - - /** - * @test - */ - public function it clears the date from a false string value(): void - { - $model = new TestModel; - - $model->has_accepted_terms_and_conditions = '0'; - - $this->assertNull($model->accepted_terms_at); - } - - /** - * @test - */ - public function it clears the date from an empty string value(): void - { - $model = new TestModel; - - $model->has_accepted_terms_and_conditions = '0'; - - $this->assertNull($model->accepted_terms_at); - } -} diff --git a/tests/Feature/BooleanDateTest.php b/tests/Feature/BooleanDateTest.php deleted file mode 100644 index 4434581..0000000 --- a/tests/Feature/BooleanDateTest.php +++ /dev/null @@ -1,59 +0,0 @@ -tested_at = Carbon::now('+5 days'); - - $this->assertSame( - Carbon::now('+5 days')->format('Y-m-d H:i:s'), - $model->tested_at->format('Y-m-d H:i:s') - ); - } - - /** - * @test - */ - public function it returns a date object from a true attribute(): void - { - $model = new TestModel; - - $model->allows_data_processing = true; - - $this->assertInstanceOf( - Carbon::class, - $model->accepted_processing_at - ); - - $this->assertEquals( - Carbon::now()->format('Y-m-d H:i:s'), - $model->accepted_processing_at->format('Y-m-d H:i:s') - ); - } - - /** - * @test - */ - public function it returns null from a false attribute(): void - { - $model = new TestModel; - - $model->allows_data_processing = false; - - $this->assertNull($model->accepted_processing_at); - } -} diff --git a/tests/TestCase.php b/tests/TestCase.php index 9fa82c4..34e1718 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -4,22 +4,8 @@ namespace SebastiaanLuca\BooleanDates\Tests; -use Orchestra\Testbench\TestCase as BaseTestCase; -use SebastiaanLuca\BooleanDates\BooleanDatesServiceProvider; +use PHPUnit\Framework\TestCase as BaseTestCase; class TestCase extends BaseTestCase { - /** - * Get package providers. - * - * @param \Illuminate\Foundation\Application $app - * - * @return array - */ - protected function getPackageProviders($app): array - { - return [ - BooleanDatesServiceProvider::class, - ]; - } } diff --git a/tests/TestModel.php b/tests/TestModel.php new file mode 100644 index 0000000..7673bdb --- /dev/null +++ b/tests/TestModel.php @@ -0,0 +1,54 @@ + + */ + protected $casts = [ + 'id' => 'integer', + 'accepted_terms_at' => 'immutable_datetime', + 'subscribed_to_newsletter_at' => 'datetime', + ]; + + /** + * @var array + */ + protected $appends = [ + 'has_accepted_terms', + 'is_subscribed_to_newsletter', + ]; + + protected function hasAcceptedTerms(): Attribute + { + return BooleanDateAttribute::for('accepted_terms_at'); + } + + protected function isSubscribedToNewsletter(): Attribute + { + return BooleanDateAttribute::for('subscribed_to_newsletter_at'); + } +} diff --git a/tests/resources/TestModel.php b/tests/resources/TestModel.php deleted file mode 100644 index 2ddcd8d..0000000 --- a/tests/resources/TestModel.php +++ /dev/null @@ -1,28 +0,0 @@ - - * 'internal_timestamp_field'`. - * - * @var array - */ - protected array $booleanDates = [ - 'has_accepted_terms_and_conditions' => 'accepted_terms_at', - 'allows_data_processing' => 'accepted_processing_at', - 'has_agreed_to_something' => 'agreed_to_something_at', - ]; -} From cf5db28cb66de36c8101f71614132e93d8e0f9e9 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 14:59:43 +0100 Subject: [PATCH 40/45] Require illuminate/database --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index aee3ac4..8207be9 100644 --- a/composer.json +++ b/composer.json @@ -26,6 +26,7 @@ ], "require": { "php": "^8.0|^8.1", + "illuminate/database": "^9.0", "illuminate/support": "^9.0" }, "require-dev": { From 297fdacaa2dd483e0eaa8b284b8ad2386e063435 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 15:00:30 +0100 Subject: [PATCH 41/45] Fix test --- tests/BooleanAttributeTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/BooleanAttributeTest.php b/tests/BooleanAttributeTest.php index 95f1bcb..f11cb7c 100644 --- a/tests/BooleanAttributeTest.php +++ b/tests/BooleanAttributeTest.php @@ -16,7 +16,7 @@ public function it can handle initial values(): void { $model = new TestModel([ 'accepted_terms_at' => 1, - 'subscribed_to_newsletter_at' => now(), + 'subscribed_to_newsletter_at' => Carbon::now(), ]); $this->assertInstanceOf(CarbonImmutable::class, $model->accepted_terms_at); From 0fd9e425101697b7db008146e671d5d0489f4cd0 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 15:01:11 +0100 Subject: [PATCH 42/45] Update Composer scripts --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 8207be9..e3e4403 100644 --- a/composer.json +++ b/composer.json @@ -58,11 +58,11 @@ "@lint", "@test" ], - "check-lowest": [ + "check:lowest": [ "composer update --prefer-lowest --prefer-dist --no-interaction --ansi", "@check" ], - "check-stable": [ + "check:stable": [ "composer update --prefer-stable --prefer-dist --no-interaction --ansi", "@check" ] From b86c4401da271bb290a182c6d9cb90cb87ca3e3d Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 15:04:20 +0100 Subject: [PATCH 43/45] Require Laravel ^9.2 --- .github/workflows/test.yml | 9 +++------ README.md | 2 +- composer.json | 4 ++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a4378f6..dfd061a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,13 +7,12 @@ on: jobs: check: - name: Run PHP tests - PHP ${{ matrix.php }} - Laravel ${{ matrix.laravel }} - ${{ matrix.dependency-version }} + name: Run PHP tests - PHP ${{ matrix.php }} - ${{ matrix.dependency-version }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: php: [8.0, 8.1] - laravel: [9.*] dependency-version: [prefer-lowest, prefer-stable] os: [ubuntu-latest] @@ -33,7 +32,7 @@ jobs: uses: actions/cache@v2 with: path: ~/.composer/cache/files - key: composer-${{ runner.os }}-php-${{ matrix.php }}-laravel-${{ matrix.laravel }}-${{ hashFiles('composer.json') }} + key: composer-${{ runner.os }}-php-${{ matrix.php }}-${{ hashFiles('composer.json') }} - name: Validate Composer configuration file run: composer validate --strict @@ -46,9 +45,7 @@ jobs: coverage: none - name: Install dependencies - run: | - composer require "laravel/framework:${{ matrix.laravel }}" --no-interaction --no-progress --no-update - composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-progress --optimize-autoloader + run: composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction --no-progress --optimize-autoloader - name: Lint code run: vendor/bin/php-cs-fixer fix --dry-run --diff diff --git a/README.md b/README.md index 4329c8f..7d428db 100644 --- a/README.md +++ b/README.md @@ -61,7 +61,7 @@ $user->accepted_terms_and_conditions_at; ## Requirements - PHP 8 or 8.1 -- Laravel 8 or 9 +- Laravel ^9.2 ## How to install diff --git a/composer.json b/composer.json index e3e4403..2ec80b4 100644 --- a/composer.json +++ b/composer.json @@ -26,8 +26,8 @@ ], "require": { "php": "^8.0|^8.1", - "illuminate/database": "^9.0", - "illuminate/support": "^9.0" + "illuminate/database": "^9.2", + "illuminate/support": "^9.2" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.7", From ca7eeaa8b533c544984e8766a2bbb38e450e0677 Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 15:18:59 +0100 Subject: [PATCH 44/45] Update readme --- README.md | 77 +++++++++++++++++++++++++------------------------------ 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 7d428db..31d7463 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,8 @@ User registration controller: $input = request()->input(); $user = User::create([ - 'has_accepted_terms_and_conditions' => $input['terms'], - 'allows_data_processing' => $input['data_processing'], - 'has_agreed_to_something' => $input['something'], + 'has_accepted_terms' => $input['terms'], + 'is_subscribed_to_newsletter' => $input['newsletter'], ]); ``` @@ -33,10 +32,10 @@ Anywhere else in your code: ```php // true or false (boolean) -$user->has_accepted_terms_and_conditions; +$user->has_accepted_terms; // 2018-05-10 16:24:22 (Carbon instance) -$user->accepted_terms_and_conditions_at; +$user->accepted_terms_at; ``` ## Table of contents @@ -75,11 +74,13 @@ composer require sebastiaanluca/laravel-boolean-dates 1. Adding your datetime columns to `$casts` 2. Adding the boolean attributes to `$appends` -3. Creating attribute accessors mutators for each field +3. Creating attribute accessors and mutators for each field ```php 'immutable_datetime', - 'allowed_data_processing_at' => 'immutable_datetime', - 'subscribed_to_newsletter_at' => 'immutable_datetime', + 'subscribed_to_newsletter_at' => 'datetime', ]; /** @@ -103,8 +103,7 @@ class User extends Model */ protected $appends = [ 'has_accepted_terms', - 'has_allowed_data_processing', - 'has_subscribed_to_newsletter', + 'is_subscribed_to_newsletter', ]; protected function hasAcceptedTerms(): Attribute @@ -112,12 +111,7 @@ class User extends Model return BooleanDateAttribute::for('accepted_terms_at'); } - protected function hasAllowedDataProcessing(): Attribute - { - return BooleanDateAttribute::for('allowed_data_processing_at'); - } - - protected function hasSubscribedToNewsletter(): Attribute + protected function isSubscribedToNewsletter(): Attribute { return BooleanDateAttribute::for('subscribed_to_newsletter_at'); } @@ -140,7 +134,6 @@ return new class extends Migration { { Schema::table('users', static function (Blueprint $table): void { $table->timestamp('accepted_terms_at')->nullable(); - $table->timestamp('allowed_data_processing_at')->nullable(); $table->timestamp('subscribed_to_newsletter_at')->nullable(); }); } @@ -152,34 +145,38 @@ return new class extends Migration { ### Saving dates -If a boolean date field's value is true, it'll be automatically converted to the current datetime: +If a boolean date field's value is true-ish, it'll be automatically converted to the current datetime. You can use anything like booleans, strings, positive integers, and so on. ```php $user = new User; // Setting values explicitly -$user->has_accepted_terms_and_conditions = true; -$user->allows_data_processing = 'yes'; +$user->has_accepted_terms = true; +$user->has_accepted_terms = 'yes'; +$user->has_accepted_terms = '1'; +$user->has_accepted_terms = 1; // Or using attribute filling -$user->fill(['has_agreed_to_something' => 1]); +$user->fill(['is_subscribed_to_newsletter' => 'yes']); $user->save(); ``` All fields should now contain a datetime similar to `2018-05-10 16:24:22`. -Note that the date stored in the database column **is immutable, i.e. it's only set once**. Any following updates will not change the stored date(time), unless you update the date column manually or if you set it to `false` and back to `true`. +Note that the date stored in the database column **is immutable, i.e. it's only set once**. Any following updates will not change the stored date(time), unless you update the date column manually or if you set it to `false` and back to `true` (disabling, then enabling it). + +For example: ```php $user = new User; -$user->has_accepted_terms_and_conditions = true; +$user->has_accepted_terms = true; $user->save(); // `accepted_terms_at` column will contain `2022-03-13 13:20:00` -$user->has_accepted_terms_and_conditions = true; +$user->has_accepted_terms = true; $user->save(); // `accepted_terms_at` column will still contain the original `2022-03-13 13:20:00` date @@ -192,13 +189,12 @@ Of course you can also remove the saved date and time, for instance if a user re ```php $user = User::findOrFail(42); -$user->has_accepted_terms_and_conditions = false; -// $user->has_accepted_terms_and_conditions = null; - -$user->allows_data_processing = 0; -// $user->allows_data_processing = '0'; - -$user->has_agreed_to_something = ''; +$user->has_accepted_terms = false; +$user->has_accepted_terms = null; +$user->has_accepted_terms = '0'; +$user->has_accepted_terms = 0; +$user->has_accepted_terms = ''; +// $user->has_accepted_terms = null; $user->save(); ``` @@ -214,9 +210,8 @@ Use a boolean field's defined _key_ to access its boolean value: ```php $user = User::findOrFail(42); -$user->has_accepted_terms_and_conditions; - // true or false (boolean) +$user->has_accepted_terms; ``` #### Retrieving fields as datetimes @@ -226,16 +221,16 @@ Use a boolean field's defined _value_ to explicitly access its (Carbon) datetime ```php $user = User::findOrFail(42); -// 2018-05-10 16:24:22 (Carbon instance) +// 2018-05-10 16:24:22 (Carbon or CarbonImmutable instance) $user->accepted_terms_at; // null -$user->accepted_processing_at; +$user->is_subscribed_to_newsletter; ``` ### Array conversion -When converting a model to an array, all boolean fields ánd their datetimes will be included: +When converting a model to an array, the boolean fields will be included if you've added them to the `$appends` array in your model. ```php $user = User::findOrFail(42); @@ -246,12 +241,10 @@ $user->toArray(); * Which will return something like: * * [ - * 'accepted_terms_at' => \Illuminate\Support\Carbon('2018-05-10 16:24:22'), - * 'accepted_processing_at' => NULL, - * 'agreed_to_something_at' => \Illuminate\Support\Carbon('2018-05-10 16:24:22'), - * 'accepted_terms_and_conditions' => true, - * 'allows_data_processing' => false, - * 'agreed_to_something' => true, + * 'accepted_terms_at' => \Carbon\CarbonImmutable('2018-05-10 16:24:22'), + * 'subscribed_to_newsletter_at' => \Illuminate\Support\Carbon('2018-05-10 16:24:22'), + * 'has_accepted_terms' => true, + * 'is_subscribed_to_newsletter' => true, * ]; */ ``` From d105e85e203477021860ab2f7a568a3072b35faa Mon Sep 17 00:00:00 2001 From: Sebastiaan Luca Date: Sun, 13 Mar 2022 15:19:04 +0100 Subject: [PATCH 45/45] Add test --- tests/BooleanAttributeTest.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/BooleanAttributeTest.php b/tests/BooleanAttributeTest.php index f11cb7c..75c253f 100644 --- a/tests/BooleanAttributeTest.php +++ b/tests/BooleanAttributeTest.php @@ -234,6 +234,18 @@ public function it can disable a boolean attribute from an integer(): vo $this->assertNull($model->accepted_terms_at); } + /** + * @test + */ + public function it can disable a boolean attribute from an empty string(): void + { + $model = new TestModel; + + $model->has_accepted_terms = ''; + + $this->assertNull($model->accepted_terms_at); + } + /** * @test */