121 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
| <?php namespace Aweos\Resizer\Traits;
 | |
| 
 | |
| use Str;
 | |
| use Backend\Classes\FormField;
 | |
| use October\Rain\Halcyon\Model as HalcyonModel;
 | |
| 
 | |
| /**
 | |
|  * Implements special logic for processing form data, typically from from postback, and
 | |
|  * filling the model attributes and attributes of any related models. This is a
 | |
|  * customized, safer and simplified version of `$model->push()`.
 | |
|  *
 | |
|  * @package october\backend
 | |
|  * @author Alexey Bobkov, Samuel Georges
 | |
|  */
 | |
| trait ResponsiveSaver
 | |
| {
 | |
|     /**
 | |
|      * @var array List of prepared models that require saving.
 | |
|      */
 | |
|     protected $modelsToSave = [];
 | |
| 
 | |
|     /**
 | |
|      * Takes a model and fills it with data from a multidimensional array.
 | |
|      * If an attribute is found to be a relationship, that relationship
 | |
|      * is also filled.
 | |
|      *
 | |
|      *     $modelsToSave = $this->prepareModelsToSave($model, [...]);
 | |
|      *
 | |
|      *     foreach ($modelsToSave as $modelToSave) {
 | |
|      *         $modelToSave->save();
 | |
|      *     }
 | |
|      *
 | |
|      * @param \October\Rain\Database\Model $model Model to fill.
 | |
|      * @param array $saveData Attribute values to fill model.
 | |
|      * @return array The collection of models to save.
 | |
|      */
 | |
|     protected function prepareModelsToSave($model, $saveData)
 | |
|     {
 | |
|         $this->modelsToSave = [];
 | |
|         $this->setModelAttributes($model, $saveData);
 | |
|         $this->modelsToSave = array_reverse($this->modelsToSave);
 | |
|         return $this->modelsToSave;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Sets a data collection to a model attributes, relations are also set.
 | |
|      *
 | |
|      * @param \October\Rain\Database\Model $model Model to fill.
 | |
|      * @param array $saveData Attribute values to fill model.
 | |
|      * @return void
 | |
|      */
 | |
|     protected function setModelAttributes($model, $saveData)
 | |
|     {
 | |
|         $this->modelsToSave[] = $model;
 | |
| 
 | |
|         if (!is_array($saveData)) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         if ($model instanceof HalcyonModel) {
 | |
|             $model->fill($saveData);
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         $attributesToPurge = [];
 | |
|         $singularTypes = ['belongsTo', 'hasOne', 'morphTo', 'morphOne'];
 | |
| 
 | |
|         foreach ($saveData as $attribute => $value) {
 | |
|             $isNested = $attribute == 'pivot' || (
 | |
|                 $model->hasRelation($attribute) &&
 | |
|                 in_array($model->getRelationType($attribute), $singularTypes)
 | |
|             );
 | |
| 
 | |
|             if ($isNested && is_array($value)) {
 | |
|                 $this->setModelAttributes($model->{$attribute}, $value);
 | |
|             }
 | |
|             elseif ($value !== FormField::NO_SAVE_DATA) {
 | |
|                 if (Str::startsWith($attribute, '_')) {
 | |
|                     $attributesToPurge[] = $attribute;
 | |
|                 }
 | |
|                 $model->{$attribute} = $value;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if ($attributesToPurge) {
 | |
|             $this->deferPurgedSaveAttributes($model, $attributesToPurge);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Removes an array of attributes from the model. If the model implements
 | |
|      * the Purgeable trait, this is preferred over the internal logic.
 | |
|      *
 | |
|      * @param \October\Rain\Database\Model $model Model to adjust.
 | |
|      * @param array $attributesToPurge Attribute values to remove from the model.
 | |
|      * @return void
 | |
|      */
 | |
|     protected function deferPurgedSaveAttributes($model, $attributesToPurge)
 | |
|     {
 | |
|         if (!is_array($attributesToPurge)) {
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         /*
 | |
|          * Compatibility with Purgeable trait:
 | |
|          * This will give the ability to restore purged attributes
 | |
|          * and make them available again if necessary.
 | |
|          */
 | |
|         if (method_exists($model, 'getPurgeableAttributes')) {
 | |
|             $model->addPurgeable($attributesToPurge);
 | |
|         }
 | |
|         else {
 | |
|             $model->bindEventOnce('model.saveInternal', function () use ($model, $attributesToPurge) {
 | |
|                 foreach ($attributesToPurge as $attribute) {
 | |
|                     unset($model->attributes[$attribute]);
 | |
|                 }
 | |
|             });
 | |
|         }
 | |
|     }
 | |
| }
 |