File: D:/HostingSpaces/SBogers10/ste.komma.pro/app/Kms/RelatedModelService.php
<?php declare(strict_types=1);
namespace App\Kms;
use Komma\KMS\Core\AbstractModelHandler;
use Komma\KMS\Core\Attributes\Attribute;
use Komma\KMS\Core\RelatedModelServiceInterface;
use Komma\KMS\Sites\Kms\SiteService;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
/**
* Class ModelService
*
* Does know how to work with eloquent models and their hasmany relations.
*
* @package App\Kms\Core
*/
class RelatedModelService extends AbstractModelHandler implements RelatedModelServiceInterface
{
/** @var string */
protected $modelClassName = null;
/** @var SiteService */
protected $siteService;
/**
* Puts the values of attributes in an Eloquent model. And then saves that model.
*
* @param Model $model
* @param Collection $attributes
* @return Model
*/
public function save(Model $model, Collection $attributes = null): Model
{
if($attributes === null) return $model;
$attributes->each(function(Attribute $attribute) use(&$model) {
if($attribute->getsValueFrom() !== Attribute::ValueFromModelHasManyRelation) return;
$valueReference = $attribute->getsValueFromReference();
$value = $attribute->getValue();
$data = explode('|', $valueReference);
$valueRelationMethod = $data[0];
if(method_exists($model, $valueRelationMethod) === false) throw new \RuntimeException("The value reference method name ('".$valueRelationMethod."') does not exist on the model with class name: ".(get_class($model)).". Please check the attribute configuration in the section.");
if(count($data) != 2) throw new \InvalidArgumentException("The value reference from attribute '".get_class($attribute)."' must be a pipe seperated relation|relationAttribute pair. But now it contains more pipes and that is not allowed.");
if($attribute->isSortable() && !in_array('sort_order', $model->$valueRelationMethod()->getPivotColumns())) {
throw new \BadMethodCallException("Attribute has been enabled as sortable, but the relation is missing the required 'sort_order' pivot column.");
}
$values = explode(',', $value);
if($value != "") {
if($attribute->isSortable()) {
$syncData = [];
foreach($values as $sortOrder => $value) {
$syncData[(int) $value] = ['sort_order' => $sortOrder]; //Fills an extra sort order column on the pivot table.
}
}
else $syncData = $values;
$model->$valueRelationMethod()->sync($syncData);
}
else
$model->$valueRelationMethod()->detach();
});
return $model;
}
/**
* Gets the values of an Eloquent model and passes them to a collection of attributes
*
* @param Model $model
* @param Collection $attributes
* @return mixed
*/
public function load(Model $model, Collection $attributes = null): Collection
{
if($attributes == null) return new Collection();
return $attributes->map(function(Attribute $attribute) use($model) {
$valueFrom = $attribute->getsValueFrom();
$valueReference = $attribute->getsValueFromReference();
if ($valueFrom !== Attribute::ValueFromModelHasManyRelation) return $attribute;
if(!method_exists($model, $valueReference) === false) throw new \RuntimeException("The value reference method name ('".$valueReference."') does not exist or is not a HasMany relation on the model with class name: ".(get_class($model)).". Please check the attribute configuration in the section.");
$data = explode('|', $valueReference);
if(count($data) != 2) throw new \InvalidArgumentException("The value reference from attribute '".get_class($attribute)."' must be a pipe seperated relation|relationAttribute pair. But was not: '".$valueReference."'.");
$relationMethod = $data[0];
$relationFieldId = $data[1];
$collection = $model->$relationMethod()->get();
$valueToProcess = [];
$self = $this;
$collection->each(function($item, $key) use (&$valueToProcess, $relationFieldId, $attribute, $relationMethod, $self) {
if(strpos((string) $item->$relationFieldId, ',') !== false) throw new \RuntimeException("The relation method '".$relationMethod."' returned a value with a , character in it which is not allowed. See Attribute configuration of attribute '".get_class($attribute)."' in section '".get_class($self)."'");
$valueToProcess[] = $item->$relationFieldId;
});
$value = implode(',', $valueToProcess);
$attribute->setValue($value);
return $attribute;
});
}
/**
* Destroys the appropriate related models for a given model.
* Those related models must be the responsibility of this service
*
* @param Model $model
*/
public function destroyForModel(Model $model)
{
throw new \RuntimeException('Not implemented');
}
/**
* @param string $modelClassName
*/
public function setModelClassName(string $modelClassName): void
{
$this->modelClassName = $modelClassName;
}
}