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]);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|