File: D:/HostingSpaces/Neopoints/momsecurity.be/app/Komma/Components/ComponentService.php
<?php
/**
* Created by PhpStorm.
* User: mike
* Date: 27/07/2018
* Time: 15:22
*/
namespace App\Komma\Components;
use App\Komma\Dynamic\Component\Component;
use App\Komma\Dynamic\Component\ComponentAttributeKey;
use App\Komma\Dynamic\ComponentType\ComponentType;
use App\Komma\Dynamic\ComponentType\SaveState\SaveStateInterface;
use App\Komma\Dynamic\ComponentType\SaveState\SaveStateResolver;
use App\Komma\Kms\Core\Attributes\Attribute;
use App\Komma\Kms\Core\Attributes\Models\Traits\SubFolderTrait;
use Illuminate\Support\Collection;
class ComponentService
{
use SubFolderTrait;
/**
* Prepare the components for usage
* - Prepare the encoded data string for usage
* - Make sure all the components attributes are prepared (f.e. a Documents attribute)
* - Find a matching view for the component
*
* @param Collection $components
* @return Collection
*/
public function prepare(Collection $components)
{
// Create empty collection which we will return
$preparedComponents = collect();
// Eager load componentTypes
$components->load('componentType');
/** @var Component $component */
foreach($components as $component)
{
/** @var ComponentType $componentType */
$componentType = $component->componentType;
// We need to set a new save state for each component
/** @var SaveStateInterface $componentSaveState */
$componentSaveState = SaveStateResolver::resolve($componentType->save_state);
$componentType->setSaveStateInstanceAttribute($componentSaveState);
/** @var Collection $componentTypeAttributeInstances */
$componentTypeAttributeInstances = $componentType->save_state_instance->getAttributeInstances();
// Convert component data to array
// todo: use Laravel Casts function on model, therefor we also need to refactor the backend
$attributeValues = json_decode($component->data,true);
// Fill type attributes with data
$component->data = $this->fillAttributeInstances($componentTypeAttributeInstances,$attributeValues);
// Define view
$component->view = $this->setDefaultView($component);
// Add to collection
$preparedComponents->push($component);
}
$preparedComponents = $preparedComponents->sortBy('sort_order');
return $preparedComponents;
}
/**
* Check for each attribute whether it needs to be prepared
* For example: a Documents attribute has a encoded value, which needs to be decoded
*
* @param Collection $attributeInstances
* @param array $attributeValues
* @return Collection
*/
private function fillAttributeInstances(Collection $attributeInstances, Array $attributeValues)
{
$attributes = collect();
$count = 0;
foreach($attributeValues as $attributeKey => $attributeValue)
{
/** @var Attribute $attributeInstance */
$attributeInstance = $attributeInstances->get($count);
// Side node: no data preparation here, for setValue can only accept a string
$attributeInstance->setValue($attributeValue);
/** @var ComponentAttributeKey $attributeKeyInstance */
$attributeKeyInstance = ComponentAttributeKey::createInstanceFromString($attributeKey);
$attributes->put($attributeKeyInstance->getAttributeReference(),$attributeInstance);
$count++;
}
return $attributes;
}
/**
* Set default view for a component
* @param Component $component
* @return string
*/
private function setDefaultView(Component $component)
{
$component->view = 'site.components';
// Add sub-folder if is set
if( ! empty($this->getSubFolder())) $component->view .= '.' . $this->getSubFolder();
// Add typeSlug as default file name
$component->view .= '.' . camel_case($component->componentType->name);
return $component->view;
}
}