├── LICENSE ├── README.md ├── composer.json └── src ├── ChronosServiceProvider.php └── Eloquent ├── Chronos.php ├── Concerns ├── ChronosGetPivotClass.php ├── ChronosInteractsWithPivotTable.php ├── ChronosRelations.php └── ChronosTimestamps.php ├── Model.php └── Relations ├── BelongsToMany.php ├── MorphPivot.php ├── MorphToMany.php └── Pivot.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Ricardo Cino 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Chronos 2 | 3 | Build Status 4 | Code Coverage 5 | Code Coverage 6 | 7 | This package is for enabling the usage of Chronos in Laravel, this will not cover all cases but at least gives you Chronos instances in favor of Carbon, most of the time. (You'll see that in the Laravel source there are enough cases where it calls Carbon directly.) 8 | 9 | 10 | ## Installation 11 | 12 | The preferred method of installation is via [Composer](). Run the following 13 | command to install the package and add it as a requirement to your project's 14 | `composer.json`: 15 | 16 | ```bash 17 | composer require cino/laravel-chronos 18 | ``` 19 | 20 | ## Usage 21 | 22 | There are now 2 options to add this behaviour to your models. Either of the options will override functions to return a Chronos object instead of a Carbon object, the first and preferred option is to use the Chronos trait from \Cino\LaravelChronos\Eloquent\Chronos like below: 23 | 24 | ### Trait 25 | ```php 26 | use Cino\LaravelChronos\Eloquent\Chronos; 27 | use Illuminate\Database\Eloquent\Model; 28 | 29 | class User extends Model 30 | { 31 | use Chronos; 32 | } 33 | ``` 34 | 35 | ### Extending model 36 | The second option is to change your models to extend the Model class from \Cino\LaravelChronos\Eloquent\Model which actually also uses the trait from above. 37 | 38 | ```php 39 | 40 | use Cino\LaravelChronos\Eloquent\Model; 41 | 42 | class MyModel extends Model 43 | { 44 | 45 | } 46 | ``` 47 | 48 | ## License 49 | This open-source software is licenced under the [MIT license](LICENSE.md). 50 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cino/laravel-chronos", 3 | "description": "Replaces Carbon in Laravel by CakePHP's Chronos library", 4 | "type": "library", 5 | "license": "MIT", 6 | "keywords": [ 7 | "laravel", 8 | "lumen", 9 | "eloquent", 10 | "chronos", 11 | "carbon", 12 | "carbon-replacement", 13 | "date" 14 | ], 15 | "authors": [ 16 | { 17 | "name": "Ricardo Cino", 18 | "homepage": "https://github.com/cino" 19 | } 20 | ], 21 | "support": { 22 | "issues": "https://github.com/cino/laravel-chronos/issues", 23 | "source": "https://github.com/cino/laravel-chronos" 24 | }, 25 | "require": { 26 | "php": "^7.2", 27 | "illuminate/database": "6.* || 7.*", 28 | "illuminate/support": "6.* || 7.*", 29 | "cakephp/chronos": "1.* || 2.*" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "Cino\\LaravelChronos\\": "src/" 34 | } 35 | }, 36 | "autoload-dev": { 37 | "psr-4": { 38 | "Cino\\LaravelChronos\\Tests\\": "tests/" 39 | } 40 | }, 41 | "config": { 42 | "sort-packages": true 43 | }, 44 | "extra": { 45 | "laravel": { 46 | "providers": [ 47 | "\\Cino\\LaravelChronos\\ChronosServiceProvider" 48 | ] 49 | } 50 | }, 51 | "minimum-stability": "stable", 52 | "require-dev": { 53 | "mockery/mockery": "^1.3", 54 | "phpunit/phpunit": "^8.4 || ^9.0" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/ChronosServiceProvider.php: -------------------------------------------------------------------------------- 1 | exists) { 43 | return $this; 44 | } 45 | 46 | $this->setRawAttributes( 47 | static::newQueryWithoutScopes()->findOrFail($this->getKey())->attributes 48 | ); 49 | 50 | $this->load(Collection::make($this->relations)->reject(function ($relation) { 51 | return $relation instanceof Pivot; 52 | })->keys()->all()); 53 | 54 | $this->syncOriginal(); 55 | 56 | return $this; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Eloquent/Concerns/ChronosGetPivotClass.php: -------------------------------------------------------------------------------- 1 | using ?? Pivot::class; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Eloquent/Concerns/ChronosInteractsWithPivotTable.php: -------------------------------------------------------------------------------- 1 | newPivotQuery()->get()->map(function ($record) { 17 | $class = $this->using ? $this->using : Pivot::class; 18 | 19 | $pivot = $class::fromRawAttributes($this->parent, (array)$record, $this->getTable(), true); 20 | 21 | return $pivot->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey); 22 | }); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Eloquent/Concerns/ChronosRelations.php: -------------------------------------------------------------------------------- 1 | asDateTime($value)->startOfDay(); 20 | } 21 | 22 | /** 23 | * Return a timestamp as DateTime object. 24 | * 25 | * @param mixed $value 26 | * @return \Cake\Chronos\Chronos 27 | */ 28 | public function asDateTime($value) 29 | { 30 | // If this value is already a Chronos instance, we shall just return it as is. 31 | // This prevents us having to re-instantiate a Chronos instance when we know 32 | // it already is one, which wouldn't be fulfilled by the DateTime check. 33 | if ($value instanceof ChronosInterface) { 34 | return $value; 35 | } 36 | 37 | // If the value is already a DateTime instance, we will just skip the rest of 38 | // these checks since they will be a waste of time, and hinder performance 39 | // when checking the field. We will just return the DateTime right away. 40 | if ($value instanceof DateTimeInterface) { 41 | return Chronos::instance($value); 42 | } 43 | 44 | // If this value is an integer, we will assume it is a UNIX timestamp's value 45 | // and format a Carbon object from this timestamp. This allows flexibility 46 | // when defining your date fields as they might be UNIX timestamps here. 47 | if (is_numeric($value)) { 48 | return Chronos::createFromTimestamp($value); 49 | } 50 | 51 | // If the value is in simply year, month, day format, we will instantiate the 52 | // Chronos instances from that format. Again, this provides for simple date 53 | // fields on the database. 54 | if ($this->isStandardDateFormat($value)) { 55 | return Chronos::createFromFormat('Y-m-d', $value)->startOfDay(); 56 | } 57 | 58 | // If everything else try parsing. 59 | return Chronos::parse($value); 60 | } 61 | 62 | /** 63 | * @return \Cake\Chronos\Chronos 64 | */ 65 | public function freshTimestamp() 66 | { 67 | return new Chronos; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Eloquent/Model.php: -------------------------------------------------------------------------------- 1 | using; 24 | 25 | $pivot = $using 26 | ? $using::fromRawAttributes($this->parent, $attributes, $this->table, $exists) 27 | : MorphPivot::fromAttributes($this->parent, $attributes, $this->table, $exists); 28 | 29 | $pivot->setPivotKeys($this->foreignPivotKey, $this->relatedPivotKey) 30 | ->setMorphType($this->morphType) 31 | ->setMorphClass($this->morphClass); 32 | 33 | return $pivot; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Eloquent/Relations/Pivot.php: -------------------------------------------------------------------------------- 1 |