HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
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;
    }
}