File: D:/HostingSpaces/SBogers10/eleo.komma.nl/vendor/komma/kms/src/Core/Sections/SectionService.php
<?php declare(strict_types=1);
namespace Komma\KMS\Core\Sections;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Komma\KMS\Core\Attributes\Attribute;
use Komma\KMS\Core\Attributes\Interfaces\HasLabelInterface;
use Komma\KMS\Core\Sections\Tabs\SectionTab;
use Komma\KMS\Globalization\Languages\Models\Language;
use Komma\KMS\Sites\HasSiteInterface;
use Komma\KMS\Sites\HasSitesInterface;
use Komma\KMS\Sites\SiteServiceInterface;
/**
* Class SectionService
*
* Responsible for setting up the section.
* Like the tabs, and attributes
*
* @package Komma\KMS\Core\Sections
*/
class SectionService
{
private Section $section;
private SiteServiceInterface $siteService;
private string $classModelName;
/**
* SectionService constructor.
*
* @param Section $section
* @param SiteServiceInterface $siteService
*/
public function __construct(Section $section, SiteServiceInterface $siteService)
{
$this->section = $section;
$this->siteService = $siteService;
}
/**
* @param string $classModelName
*/
public function setModelClassName(string $classModelName)
{
$this->classModelName = $classModelName;
}
/**
* @param Model|null $model
* @throws \Exception
*/
public function generateAttributesAndAddThemToTabs(Model $model = null)
{
$this->section->defineAttributesAndTabs($model);
$this->section->getTabs()->assignUndefinedAttributesTo(Attribute::ValueFromModel);
// Validate that there are tabs and attributes defined in the section, else the Controller does not need to extend from the SectionController.
if($this->section->getTabs()->count() === 0) throw new \BadFunctionCallException(self::class.': No tabs have been defined in the section. Define tabs with attributes or remove the Section(Controller) logic.');
if($this->section->getAttributes()->count() === 0) throw new \BadFunctionCallException(self::class.': One or more tabs have been defined but there are not attributes in them. Define attributes or remove the Section(Controller) logic.');
// Get the available language
$languagesForClassModel = $this->getAvailableLanguagesForClassModel();
// This will duplicate the attribute outside the languageTabs
$this->assignLanguagesToTranslationAttributeWithinTabs($languagesForClassModel);
// If we don't have a language tab, we can already return
if(!$this->section->getTabs()->hasLanguageTabTemplate()) return;
// Get the attributes needed for the Language Tab
$languageTabAttributes = $this->section->getTabs()->pullLanguageTabTemplate()->getItems();
// Set get ValueFrom to TranslationModel if null
foreach ($languageTabAttributes as $languageTabAttribute)
if($languageTabAttribute->getsValueFrom() === null) $languageTabAttribute->setEntity(Attribute::ValueFromTranslationModel);
foreach ($languagesForClassModel as $language)
{
$languageTab = $this->section->getTabs()->makeTab(strtoupper($language->iso_2));
/** @var Attribute $attribute */
foreach ($languageTabAttributes as $attribute) {
$clone = clone $attribute;
$clone->setAssociatedLanguage($language);
$languageTab->addItem($clone);
}
}
}
/**
* Get the possible needed languages.
* This will look at the defined site relation of the model and return the needed set of languages.
*
* @return Collection
*/
private function getAvailableLanguagesForClassModel(): Collection
{
// If model belong to a site, load all the language of that site
if(is_a($this->classModelName, HasSiteInterface::class, true)) {
return $this->siteService->getSiteLanguages();
}
// Else the models can belong many site or has not site relation.
// Therefor we return all the languages defined to any sites.
return $this->siteService->languagesHavingSites()->get();
}
/**
* Loop over the tabs that aren't language tabs
* and assign and possible clone the attributes for each language.
*
* @param Collection $languages
* @throws \Exception
*/
private function assignLanguagesToTranslationAttributeWithinTabs(Collection $languages)
{
/** @var SectionTab $tab */
foreach ($this->section->getTabs() as $tab) {
if( $tab->isLanguageTabTemplate()) continue;
$remappedAttributes = collect();
/** @var Attribute $tabAttribute */
foreach ($tab->getItems() as $key => $tabAttribute) {
// All the other can directly be append to the remappedAttributes
if($tabAttribute->getsValueFrom() !== Attribute::ValueFromTranslationModel) {
$remappedAttributes->push($tabAttribute);
continue;
}
foreach ($languages as $language)
{
/** @var Attribute $clone */
$clone = clone $tabAttribute;
$clone->setAssociatedLanguage($language);
// If HasLabelInterface append the iso before the current label, if count is larger then one
if(is_a($clone, HasLabelInterface::class) && $languages->count() > 1)
$clone->setLabelText($language->iso_2 . ': ' . $clone->getLabelText());
$remappedAttributes->push($clone);
}
}
$tab->setItems($remappedAttributes);
}
}
}