├── .php_cs.dist.php ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── config └── save_model.php ├── database ├── factories │ └── UserFactory.php └── migrations │ └── create_users_table.php.stub ├── resources ├── stubs │ └── field.php.stub └── views │ └── .gitkeep └── src ├── Commands ├── MakeFieldCommand.php └── SaveModelConfigPublishCommand.php ├── Contracts └── CanBeSavedContract.php ├── Exceptions └── FieldDoesNotExistException.php ├── Fields ├── BooleanField.php ├── DateField.php ├── DatetimeField.php ├── Field.php ├── FileField.php ├── IntegerField.php ├── PasswordField.php ├── StringField.php └── TimeField.php ├── SaveModel.php └── SaveModelServiceProvider.php /.php_cs.dist.php: -------------------------------------------------------------------------------- 1 | in([ 5 | __DIR__ . '/src', 6 | __DIR__ . '/tests', 7 | ]) 8 | ->name('*.php') 9 | ->notName('*.blade.php') 10 | ->ignoreDotFiles(true) 11 | ->ignoreVCS(true); 12 | 13 | return (new PhpCsFixer\Config()) 14 | ->setRules([ 15 | '@PSR12' => true, 16 | 'array_syntax' => ['syntax' => 'short'], 17 | 'ordered_imports' => ['sort_algorithm' => 'alpha'], 18 | 'no_unused_imports' => true, 19 | 'not_operator_with_successor_space' => true, 20 | 'trailing_comma_in_multiline' => true, 21 | 'phpdoc_scalar' => true, 22 | 'unary_operator_spaces' => true, 23 | 'binary_operator_spaces' => true, 24 | 'blank_line_before_statement' => [ 25 | 'statements' => ['break', 'continue', 'declare', 'return', 'throw', 'try'], 26 | ], 27 | 'phpdoc_single_line_var_spacing' => true, 28 | 'phpdoc_var_without_name' => true, 29 | 'class_attributes_separation' => [ 30 | 'elements' => [ 31 | 'method' => 'one', 32 | ], 33 | ], 34 | 'method_argument_space' => [ 35 | 'on_multiline' => 'ensure_fully_multiline', 36 | 'keep_multiple_spaces_after_comma' => true, 37 | ], 38 | 'single_trait_insert_per_statement' => true, 39 | ]) 40 | ->setFinder($finder); 41 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `save-model` will be documented in this file. 4 | 5 | ## 1.0.0 - 202X-XX-XX 6 | 7 | - initial release 8 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) asdh 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Save Model 2 | 3 | Save Model is a Laravel package that allows you to save data in the database in a new way. No need to worry about `$guarded` and `$fillable` properties in the model anymore. Just relax an use `Save Model` package. 4 | 5 | --- 6 | 7 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/asdh/save-model.svg?style=flat-square)](https://packagist.org/packages/asdh/save-model) 8 | [![GitHub Tests Action Status](https://img.shields.io/github/workflow/status/asdh/save-model/run-tests?label=tests)](https://github.com/asdh/save-model/actions?query=workflow%3Arun-tests+branch%3Amain) 9 | [![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/asdh/save-model/Check%20&%20fix%20styling?label=code%20style)](https://github.com/asdh/save-model/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain) 10 | [![Total Downloads](https://img.shields.io/packagist/dt/asdh/save-model.svg?style=flat-square)](https://packagist.org/packages/asdh/save-model) 11 | 12 | --- 13 | 14 | ## Installation 15 | 16 | You can install the package via composer: 17 | 18 | ```bash 19 | composer require asdh/save-model 20 | ``` 21 | 22 | You can publish the config file with: 23 | ```bash 24 | php artisan save-model:publish 25 | 26 | or 27 | 28 | php artisan vendor:publish --provider="Asdh\SaveModel\SaveModelServiceProvider" 29 | ``` 30 | 31 | This is the contents of the published config file: 32 | 33 | ```php 34 | // config/save_model.php 35 | 36 | return [ 37 | /** 38 | * The directory name where the files should be stored 39 | * This can be changed via 'saveableFields' method on model 40 | */ 41 | 'file_upload_directory' => 'files', 42 | ]; 43 | ``` 44 | 45 | ## Usage 46 | 47 | ```php 48 | // In controller 49 | 50 | use Asdh\SaveModel\SaveModel; 51 | 52 | SaveModel::new( 53 | new User, 54 | $request->only(['name', 'email', 'password', 'image']) 55 | )->execute(); 56 | 57 | // OR 58 | 59 | (new SaveModel( 60 | new User, 61 | $request->only(['name', 'email', 'password', 'image']) 62 | )->execute(); 63 | ``` 64 | 65 | You just do this and a new user will be created and saved to the 'users' table. The password will be automatically hashed, and uploading of the image will also be automatically handled. 66 | 67 | To update a model, you just have to pass the model that you want to update. 68 | 69 | ```php 70 | // In controller 71 | 72 | use Asdh\SaveModel\SaveModel; 73 | 74 | $user = User::find(1); 75 | 76 | SaveModel::new( 77 | $user, 78 | $request->only(['name', 'email']) 79 | )->execute(); 80 | ``` 81 | Only name and email will be updated and no other columns will be touched. 82 | 83 | **For this to work, you need to do these things:** 84 | 85 | Go to User model class or any other model class and add `CanBeSavedContract` class to it. In this example, I will use User model. 86 | 87 | ```php 88 | use Asdh\SaveModel\Contracts\CanBeSavedContract; 89 | 90 | class User extends Authenticatable implements CanBeSavedContract 91 | { 92 | 93 | } 94 | ``` 95 | 96 | After adding this, you need to add `saveableFields` method to the User model and map every columns of the users table like so: 97 | 98 | ```php 99 | use Asdh\SaveModel\Contracts\CanBeSavedContract; 100 | use Asdh\SaveModel\Fields\DatetimeField; 101 | use Asdh\SaveModel\Fields\FileField; 102 | use Asdh\SaveModel\Fields\PasswordField; 103 | use Asdh\SaveModel\Fields\StringField; 104 | 105 | class User extends Authenticatable implements CanBeSavedContract 106 | { 107 | public function saveableFields(): array 108 | { 109 | return [ 110 | 'name' => StringField::new(), 111 | 'email' => StringField::new(), 112 | 'email_verified_at' => DatetimeField::new(), 113 | 'password' => PasswordField::new(), 114 | 'image' => FileField::new(), 115 | ]; 116 | } 117 | } 118 | ``` 119 | 120 | After doing this you are good to go. In the controller, you just need to get the data and use the `SaveModel` class 121 | 122 | ```php 123 | use Asdh\SaveModel\SaveModel; 124 | 125 | SaveModel::new( 126 | new User, 127 | $request->only(['name', 'email', 'password', 'image']) 128 | )->execute(); 129 | 130 | // OR 131 | 132 | (new SaveModel( 133 | new User, 134 | $request->only(['name', 'email', 'password', 'image']) 135 | )->execute(); 136 | ``` 137 | 138 | The files will be uploaded using the default `Laravel's filesystem`. Which means that you can directly configure to upload the files directly to the `S3` as well or any other that Laravel supports. 139 | 140 | Also, the files will be uploaded to the `files` directory by default. You can change that globally by changing the value of `file_upload_directory` on the `save_model.php` configuration file. 141 | 142 | You can also change it per model like so: 143 | 144 | ```php 145 | // app/Models/User.php 146 | 147 | public function saveableFields(): array 148 | { 149 | return [ 150 | 'image' => FileField::new()->setDirectory('images'), 151 | ]; 152 | } 153 | ``` 154 | 155 | It will now store the `image` of the user to the `images` directory and for every other `Models`, it will use from the `save_model.php` config file. 156 | 157 | You can also, choose the Laravel Filesystem's `disk` per model like so: 158 | 159 | ```php 160 | // app/Models/User.php 161 | 162 | public function saveableFields(): array 163 | { 164 | return [ 165 | 'image' => FileField::new() 166 | ->setDirectory('images') 167 | ->setDisk('s3'), 168 | ]; 169 | } 170 | ``` 171 | 172 | By default `random name` will be generated for the uploaded files, but you can change that also. You just have to pass closure on the `setFileName` method and you will get access to the uploaded file there. And whatever you return from here will be saved to the database as the file name. 173 | 174 | This example shows how to return the original file name. 175 | 176 | ```php 177 | // app/Models/User.php 178 | 179 | use Illuminate\Http\UploadedFile; 180 | 181 | public function saveableFields(): array 182 | { 183 | return [ 184 | 'image' => FileField::new() 185 | ->setDirectory('images') 186 | ->setFileName(function (UploadedFile $uploadedFile) { 187 | return $uploadedFile->getClientOriginalName(); 188 | }), 189 | ]; 190 | } 191 | ``` 192 | 193 | If you want to upload the file as the original name then you can do this: 194 | 195 | ```php 196 | // app/Models/User.php 197 | 198 | use Illuminate\Http\UploadedFile; 199 | 200 | public function saveableFields(): array 201 | { 202 | return [ 203 | 'image' => FileField::new() 204 | ->setDirectory('images') 205 | ->uploadAsOriginalName(), 206 | ]; 207 | } 208 | ``` 209 | 210 | One thing to keep in mind that the `setFileName` method will take precedence over `uploadAsOriginalName` if both methods are being used. 211 | 212 | Not only this, the deletion of the file will also be automatically handled when updating a model. By default, when a model is updated, the old file will be automatically deleted if a new file is being uploaded. If you don't want the old images to be deleted then you can chain `dontDeleteOldFileOnUpdate` method. 213 | 214 | ```php 215 | // app/Models/User.php 216 | 217 | use Illuminate\Http\UploadedFile; 218 | 219 | public function saveableFields(): array 220 | { 221 | return [ 222 | 'image' => FileField::new() 223 | ->setDirectory('images') 224 | ->dontDeleteOldFileOnUpdate(), 225 | ]; 226 | } 227 | ``` 228 | 229 | ## Available Fields 230 | ```php 231 | Asdh\SaveModel\Fields\StringField::class 232 | Asdh\SaveModel\Fields\IntegerField::class 233 | Asdh\SaveModel\Fields\DatetimeField::class 234 | Asdh\SaveModel\Fields\DateField::class 235 | Asdh\SaveModel\Fields\TimeField::class 236 | Asdh\SaveModel\Fields\PasswordField::class 237 | Asdh\SaveModel\Fields\FileField::class 238 | Asdh\SaveModel\Fields\BooleanField::class 239 | ``` 240 | 241 | Other field will be added in the future and I am open to pull requests. 242 | 243 | ## Creating your own model field class 244 | 245 | You can create your own field class as well. To create one, you need to run an artisan command 246 | 247 | ```bash 248 | php artisan make:field BooleanField 249 | ``` 250 | 251 | This will create a `BooleanField` class inside `App\ModelFields` directory and it will look like this: 252 | 253 | ```php 254 | value) 267 | } 268 | } 269 | ``` 270 | 271 | It is not necessary that `BooleanField` class must be inside `App\ModelFields` directory. You can place it wherever you like. 272 | 273 | You will have access to the data passed from the controller as `$this->value`. Then you can do whatever you want to do and return the value that you want to save in the database. In above case, we can do it like so: 274 | 275 | ```php 276 | value, [1, '1', true, 'true', 'on', 'yes']); 287 | } 288 | } 289 | 290 | ``` 291 | If the input is any one of these, then we will consider it to be true and for every one of these values, we will save `true` (which will be `1` when stored in database) to the database. 292 | 293 | Then you can easily use your own field in the model's `saveableFields` method. You can now use this `BooleanField` along with other fields like this: 294 | 295 | ```php 296 | use Asdh\SaveModel\Contracts\CanBeSavedContract; 297 | use Asdh\SaveModel\Fields\DatetimeField; 298 | use Asdh\SaveModel\Fields\FileField; 299 | use Asdh\SaveModel\Fields\PasswordField; 300 | use Asdh\SaveModel\Fields\StringField; 301 | use App\ModelFields\BooleanField; 302 | 303 | class User extends Authenticatable implements CanBeSavedContract 304 | { 305 | public function saveableFields(): array 306 | { 307 | return [ 308 | 'name' => StringField::new(), 309 | 'email' => StringField::new(), 310 | 'email_verified_at' => DatetimeField::new(), 311 | 'password' => PasswordField::new(), 312 | 'image' => FileField::new(), 313 | 'is_admin' => Boolean::new(), 314 | ]; 315 | } 316 | } 317 | 318 | ``` 319 | Make sure you add the namespace correctly as shown above. 320 | 321 | ## Testing 322 | 323 | ```bash 324 | composer test 325 | ``` 326 | 327 | ## Changelog 328 | 329 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 330 | 331 | ## Contributing 332 | 333 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details. 334 | 335 | ## License 336 | 337 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 338 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "asdh/save-model", 3 | "description": "Just a new way to save data in the database", 4 | "keywords": [ 5 | "asdh", 6 | "laravel", 7 | "save-model" 8 | ], 9 | "homepage": "https://github.com/asdh/save-model", 10 | "license": "MIT", 11 | "authors": [ 12 | { 13 | "name": "Ashish Dhamala", 14 | "email": "aashish201030@gmail.com", 15 | "role": "Developer" 16 | } 17 | ], 18 | "require": { 19 | "php": "^8.0", 20 | "spatie/laravel-package-tools": "^1.4.3", 21 | "illuminate/contracts": "^8.37" 22 | }, 23 | "require-dev": { 24 | "brianium/paratest": "^6.2", 25 | "nunomaduro/collision": "^5.3", 26 | "orchestra/testbench": "^6.15", 27 | "phpunit/phpunit": "^9.3", 28 | "spatie/laravel-ray": "^1.23", 29 | "vimeo/psalm": "^4.8" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "Asdh\\SaveModel\\": "src", 34 | "Asdh\\SaveModel\\Database\\Factories\\": "database/factories" 35 | } 36 | }, 37 | "autoload-dev": { 38 | "psr-4": { 39 | "Asdh\\SaveModel\\Tests\\": "tests" 40 | } 41 | }, 42 | "scripts": { 43 | "psalm": "vendor/bin/psalm", 44 | "test": "./vendor/bin/testbench package:test --parallel --no-coverage", 45 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage" 46 | }, 47 | "config": { 48 | "sort-packages": true 49 | }, 50 | "extra": { 51 | "laravel": { 52 | "providers": [ 53 | "Asdh\\SaveModel\\SaveModelServiceProvider" 54 | ] 55 | } 56 | }, 57 | "minimum-stability": "dev", 58 | "prefer-stable": true 59 | } 60 | -------------------------------------------------------------------------------- /config/save_model.php: -------------------------------------------------------------------------------- 1 | 'files', 8 | ]; 9 | -------------------------------------------------------------------------------- /database/factories/UserFactory.php: -------------------------------------------------------------------------------- 1 | $this->faker->name, 21 | 'email' => $this->faker->unique()->safeEmail, 22 | 'email_verified_at' => now(), 23 | 'password' => bcrypt('password'), 24 | 'image' => null, 25 | 'remember_token' => \Illuminate\Support\Str::random(10), 26 | ]; 27 | } 28 | } -------------------------------------------------------------------------------- /database/migrations/create_users_table.php.stub: -------------------------------------------------------------------------------- 1 | id(); 18 | $table->string('name'); 19 | $table->string('email')->unique(); 20 | $table->timestamp('email_verified_at')->nullable(); 21 | $table->string('password'); 22 | $table->string('image')->nullable(); 23 | $table->rememberToken(); 24 | $table->timestamps(); 25 | }); 26 | } 27 | 28 | /** 29 | * Reverse the migrations. 30 | * 31 | * @return void 32 | */ 33 | public function down() 34 | { 35 | Schema::dropIfExists('users'); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /resources/stubs/field.php.stub: -------------------------------------------------------------------------------- 1 | value) 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /resources/views/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Laratipsofficial/save-model/46d06f0b2f4995500f4ce43a7ea5d92782284308/resources/views/.gitkeep -------------------------------------------------------------------------------- /src/Commands/MakeFieldCommand.php: -------------------------------------------------------------------------------- 1 | field = (string) Str::of($this->argument('field'))->trim()->replace('\\', '/'); 22 | 23 | $fieldName = Str::afterLast($this->field, '/'); 24 | 25 | if (! Str::slug($fieldName)) { 26 | $this->error('Invalid field name.'); 27 | 28 | return; 29 | } 30 | 31 | $this->fieldClass = Str::studly($fieldName); 32 | 33 | (new Filesystem())->ensureDirectoryExists(app_path($this->destinationDirectory())); 34 | 35 | if ($this->classAlreadyExists()) { 36 | $this->error("{$this->fieldClass} already exists!"); 37 | 38 | return; 39 | } 40 | 41 | $this->generateClass(); 42 | 43 | $this->comment('Model field created successfully.'); 44 | } 45 | 46 | private function destinationDirectory(): string 47 | { 48 | $directory = 'ModelFields'; 49 | 50 | if (str_contains($this->field, '/')) { 51 | $directory .= '/' . Str::beforeLast($this->field, '/'); 52 | } 53 | 54 | return $directory; 55 | } 56 | 57 | private function destination(): string 58 | { 59 | return app_path("{$this->destinationDirectory()}/{$this->fieldClass}.php"); 60 | } 61 | 62 | private function source(): string 63 | { 64 | return __DIR__ . '/../../resources/stubs/field.php.stub'; 65 | } 66 | 67 | private function classAlreadyExists(): bool 68 | { 69 | return (new Filesystem())->exists($this->destination()); 70 | } 71 | 72 | private function generateClass(): void 73 | { 74 | (new Filesystem())->put( 75 | $this->destination(), 76 | str_replace([ 77 | '{{FieldClass}}', 78 | '{{namespace}}', 79 | ], [ 80 | $this->fieldClass, 81 | $this->namespace(), 82 | ], file_get_contents($this->source())) 83 | ); 84 | } 85 | 86 | private function namespace(): string 87 | { 88 | return 'App\\' . str_replace('/', '\\', $this->destinationDirectory()); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/Commands/SaveModelConfigPublishCommand.php: -------------------------------------------------------------------------------- 1 | error('save_model.php is already exist. config file publish failed.!'); 17 | $answer = $this->ask('Are you sure you want to replace the save_model config file ? [y/N]', 'N'); 18 | if ($answer == 'y' || $answer == 'Y') { 19 | copy(__DIR__ . '/../../config/save_model.php', config_path('save_model.php')); 20 | $this->info('Config file re-published successfully.!'); 21 | } 22 | 23 | return; 24 | } 25 | $this->call('vendor:publish', ['--tag' => "savemodel-config"]); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Contracts/CanBeSavedContract.php: -------------------------------------------------------------------------------- 1 | value, [true, 'true', 1, '1', 'on', 'yes'], true); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Fields/DateField.php: -------------------------------------------------------------------------------- 1 | value) { 12 | return $this->value; 13 | } 14 | 15 | return Carbon::parse($this->value)->toDateString(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Fields/DatetimeField.php: -------------------------------------------------------------------------------- 1 | value) { 12 | return $this->value; 13 | } 14 | 15 | return Carbon::parse($this->value)->toDateTimeString(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Fields/Field.php: -------------------------------------------------------------------------------- 1 | value = $value; 25 | 26 | return $this; 27 | } 28 | 29 | public function onColumn(string $column): static 30 | { 31 | $this->column = $column; 32 | 33 | return $this; 34 | } 35 | 36 | public function ofModel(Model $model): static 37 | { 38 | $this->model = $model; 39 | 40 | return $this; 41 | } 42 | 43 | public function isUpdateMode(): bool 44 | { 45 | return $this->model->exists; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Fields/FileField.php: -------------------------------------------------------------------------------- 1 | value) { 24 | return $this->value; 25 | } 26 | 27 | if (! ($this->value instanceof UploadedFile)) { 28 | return $this->value; 29 | } 30 | 31 | $this->deleteOldFileIfNecessary(); 32 | 33 | $fileName = $this->getFileName(); 34 | 35 | return $fileName 36 | ? $this->value->storeAs($this->directoryName(), $fileName, $this->diskName()) 37 | : $this->value->store($this->directoryName(), $this->diskName()); 38 | } 39 | 40 | public function setDirectory(string $directory): self 41 | { 42 | $this->directory = $directory; 43 | 44 | return $this; 45 | } 46 | 47 | public function setDisk(string $disk): self 48 | { 49 | $this->disk = $disk; 50 | 51 | return $this; 52 | } 53 | 54 | public function setFileName(Closure $closure): self 55 | { 56 | $this->fileNameClosure = $closure; 57 | 58 | return $this; 59 | } 60 | 61 | public function dontDeleteOldFileOnUpdate(): self 62 | { 63 | $this->deleteOldFileOnUpdate = false; 64 | 65 | return $this; 66 | } 67 | 68 | public function uploadAsOriginalName(): self 69 | { 70 | $this->uploadAsOriginalName = true; 71 | 72 | return $this; 73 | } 74 | 75 | private function diskName(): string 76 | { 77 | return $this->disk ?? config('filesystems.default'); 78 | } 79 | 80 | private function directoryName(): string 81 | { 82 | return $this->directory ?? config('save_model.file_upload_directory'); 83 | } 84 | 85 | private function deleteOldFileIfNecessary(): void 86 | { 87 | $fileName = $this->model->getRawOriginal($this->column); 88 | 89 | if ($this->deleteOldFileOnUpdate && $this->isUpdateMode() && $fileName) { 90 | Storage::disk($this->diskName())->delete($fileName); 91 | } 92 | } 93 | 94 | private function getFileName(): ?string 95 | { 96 | $fileName = null; 97 | 98 | if ($this->uploadAsOriginalName) { 99 | $fileName = $this->value->getClientOriginalName(); 100 | } 101 | 102 | if ($this->fileNameClosure) { 103 | $fileName = ($this->fileNameClosure)($this->value); 104 | } 105 | 106 | return $fileName; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/Fields/IntegerField.php: -------------------------------------------------------------------------------- 1 | value; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Fields/PasswordField.php: -------------------------------------------------------------------------------- 1 | value) { 12 | return $this->value; 13 | } 14 | 15 | return Hash::make($this->value); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Fields/StringField.php: -------------------------------------------------------------------------------- 1 | value; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Fields/TimeField.php: -------------------------------------------------------------------------------- 1 | value) { 12 | return $this->value; 13 | } 14 | 15 | return Carbon::parse($this->value)->toTimeString(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/SaveModel.php: -------------------------------------------------------------------------------- 1 | saveableFieldExists($column)) { 23 | throw new FieldDoesNotExistException("The field '{$column}' does not exist on the 'saveableFields' method of {$modelClassName}"); 24 | } 25 | } 26 | } 27 | 28 | public static function new(Model $model, array $data): static 29 | { 30 | return new static($model, $data); 31 | } 32 | 33 | private function saveableFieldExists(string $column): bool 34 | { 35 | return array_key_exists($column, $this->model->saveableFields()); 36 | } 37 | 38 | public function execute(): Model 39 | { 40 | foreach ($this->data as $column => $value) { 41 | $this->model->{$column} = $this 42 | ->saveableField($column) 43 | ->setValue($value) 44 | ->onColumn($column) 45 | ->ofModel($this->model) 46 | ->execute(); 47 | } 48 | 49 | $this->model->save(); 50 | 51 | return $this->model; 52 | } 53 | 54 | private function saveableField($column): Field 55 | { 56 | return $this->model->saveableFields()[$column]; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/SaveModelServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->runningInConsole()) { 18 | $this->publishes([ 19 | __DIR__ . '/../config/save_model.php' => config_path('save_model.php'), 20 | ], 'savemodel-config'); 21 | 22 | // Registering package commands. 23 | $this->commands([ 24 | SaveModelConfigPublishCommand::class, 25 | MakeFieldCommand::class, 26 | ]); 27 | } 28 | } 29 | 30 | public function configurePackage(Package $package): void 31 | { 32 | /* 33 | * This class is a Package Service Provider 34 | * 35 | * More info: https://github.com/spatie/laravel-package-tools 36 | */ 37 | $package 38 | ->name('save-model') 39 | ->hasConfigFile('save_model'); 40 | } 41 | } 42 | --------------------------------------------------------------------------------