sebastiaanluca / laravel-boolean-dates
Automatically convert Eloquent model boolean attributes to dates (and back).
Installs: 66 859
Dependents: 1
Suggesters: 0
Security: 0
Stars: 34
Watchers: 2
Forks: 1
Open Issues: 1
Requires
- php: ~8.2|~8.3
- illuminate/database: ^10.0|^11.0
- illuminate/support: ^10.0|^11.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.50
- laravel/pint: ^1.14
- phpunit/phpunit: ^11.0.3
- rector/rector: ^1.0.1
- roave/security-advisories: dev-latest
README
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.
Example
User registration controller:
$input = request()->input(); $user = User::create([ 'has_accepted_terms' => $input['terms'], 'is_subscribed_to_newsletter' => $input['newsletter'], ]);
Anywhere else in your code:
// true or false (boolean) $user->has_accepted_terms; // 2018-05-10 16:24:22 (Carbon instance) $user->accepted_terms_at;
Table of contents
- Requirements
- How to install
- How to use
- License
- Change log
- Testing
- Contributing
- Security
- Credits
- About
Requirements
- PHP 8.1 or 8.2
- Laravel 10
How to install
Add the package to your project using composer:
composer require sebastiaanluca/laravel-boolean-dates
Set up your Eloquent model by:
- Adding your datetime columns to the
$casts
property orcasts()
method - Adding the boolean attributes to
$appends
- Creating attribute accessors and mutators for each field
<?php declare(strict_types=1); use Illuminate\Database\Eloquent\Model; use SebastiaanLuca\BooleanDates\BooleanDateAttribute; class User extends Model { /** * The attributes that should be cast to native types. * * @var array<string, string> */ protected $casts = [ 'accepted_terms_at' => 'immutable_datetime', 'subscribed_to_newsletter_at' => 'datetime', ]; /** * The accessors to append to the model's array form. * * @var array<int, string> */ 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'); } }
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 declare(strict_types=1); use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::table('users', static function (Blueprint $table): void { $table->timestamp('accepted_terms_at')->nullable(); $table->timestamp('subscribed_to_newsletter_at')->nullable(); }); } };
How to use
Saving dates
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.
$user = new User; // Setting values explicitly $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(['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
(disabling, then enabling it).
For example:
$user = new User; $user->has_accepted_terms = true; $user->save(); // `accepted_terms_at` column will contain `2022-03-13 13:20:00` $user->has_accepted_terms = 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:
$user = User::findOrFail(42); $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();
False or false-y values are converted to NULL
.
Retrieving values
Retrieving fields as booleans
Use a boolean field's defined key to access its boolean value:
$user = User::findOrFail(42); // true or false (boolean) $user->has_accepted_terms;
Retrieving fields as datetimes
Use a boolean field's defined value to explicitly access its (Carbon) datetime value:
$user = User::findOrFail(42); // 2018-05-10 16:24:22 (Carbon or CarbonImmutable instance) $user->accepted_terms_at; // null $user->is_subscribed_to_newsletter;
Array conversion
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.
$user = User::findOrFail(42); $user->toArray(); /* * Which will return something like: * * [ * '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, * ]; */
License
This package operates under the MIT License (MIT). Please see LICENSE for more information.
Change log
Please see CHANGELOG for more information what has changed recently.
Testing
composer install
composer test
Contributing
Please see CONTRIBUTING and CONDUCT for details.
Security
If you discover any security related issues, please email hello@sebastiaanluca.com instead of using the issue tracker.
Credits
About
My name is Sebastiaan and I'm a freelance back-end developer specializing in building custom Laravel applications. Check out my portfolio for more information, my blog for the latest tips and tricks, and my other packages to kick-start your next project.
Have a project that could use some guidance? Send me an e-mail at hello@sebastiaanluca.com!