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/kommabasic.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);
        }
    }
}