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/SBogers95/rentman.io/app/Komma/OneSky/OneSkyImporterService.php
<?php

namespace App\Komma\OneSky;

use App\Komma\Dynamic\ComponentArea\ComponentAreaServiceInterface;
use App\Komma\Dynamic\ComponentType\ComponentTypeFactory;
use App\Komma\Dynamic\ComponentType\ComponentTypes;
use App\Komma\Kms\Core\Attributes\Attribute;
use App\Komma\Kms\Core\Attributes\ComponentArea;
use App\Komma\Languages\Models\Language;
use App\Komma\Packages\Models\Package;
use App\Komma\Pages\Models\Page;
use App\Komma\PricingLabels\Models\PricingLabel;
use App\Komma\ProductGroups\Models\ProductGroup;
use App\Komma\Products\Models\Product;
use App\Komma\Sites\Models\Site;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\Console\Output\ConsoleOutput;

class OneSkyImporterService
{
    /** @var Language */
    private $language;

    private $forModel;

    private $componentAreaAttributeKeyAsString = 'dynamic_group_sections';

    public function runByBrowser()
    {
        $json = json_decode(file_get_contents(storage_path('App/OneSkyImport/es_packages.json'), true));
//        $json = json_decode(file_get_contents(storage_path('App/OneSkyImport/es_pages.json'), true));
//        $json = json_decode(file_get_contents(storage_path('App/OneSkyImport/es_pricing-labels.json'), true));
//        $json = json_decode(file_get_contents(storage_path('App/OneSkyImport/es_product-groups.json'), true));
//        $json = json_decode(file_get_contents(storage_path('App/OneSkyImport/es_products.json'), true));
        $this->runImport('es', 'packages', $json);
    }

    public function runImport($language, $modelString, $json)
    {
        //Set runImport variable, so some application parts will be skipped
        Config::set('runImport', true);

        // Convert to language model
        $this->language = Language::where('iso_2', $language)->first();

        // Set the correct model for the import
        $this->forModel = $this->convertStringToModel($modelString);

        // Check if we first have to append a new language on the site
        $site = Site::find(1);
        if ($site->languages()->where('language_id', $this->language->id)->count() == 0) {
            $output = new ConsoleOutput();
            $output->writeln("<info>OneSkyImporterService: Created new language '".$language."' on site</info>");
            $site->languages()->save($this->language);
        }

        $componentAreaService = \App::make(ComponentAreaServiceInterface::class);

        foreach ($json as $key => $translatables) {
            $model = $this->getModel($key);

            if (! isset($model)) {
                Log::warning('OneSkyImporter: THe following key has not been found "'.$key.'"');
                continue;
            }

            // Find or create the translation
            $translation = $model->translations()->firstOrCreate(['language_id' => $this->language->id]);

            // Set the active and preview value on the needed models
            if (in_array($this->forModel, [Page::class, Product::class])) {
                $translation->active = 1;
                $translation->preview = 0;
            }

            // Loop through the translatables and append them to the translation
            foreach ($translatables as $variableKey => $translatable) {
                // We skip the 'Component' that has its own function
                if ($variableKey == 'components') {
                    continue;
                }
                $translation->{$variableKey} = $translatable;

                // If variable is name we also generate a slug
                if ($variableKey == 'name' && in_array($this->forModel, [Page::class, Product::class])) {
                    $translation->slug = Str::slug($translatable);
                }
            }

            $translation->save();

            // Create route for pages
            if (is_a($model, Page::class)) {
                $englishTranslation = $model->translations()->where('language_id', 40)->first();

                $translation->route()->firstOrCreate([
                    'route' => $englishTranslation->route->route,
                    'alias' => ($englishTranslation->route->route != 'pages/2' ? $this->language->iso_2.'/'.$translation->slug : $this->language->iso_2),
                    'site_id' => $englishTranslation->route->site_id,
                    'language_id' => $this->language->id,
                ]);
            }

            // Create components
            if (isset($translatables->components)) {
                // Change the component area attribute key
                if (is_a($model, Product::class)) {
                    $this->componentAreaAttributeKeyAsString = 'product_components';
                }

                $componentAreaAttributeValue = $this->convertIntoComponents($translatables->components, $this->language);

                $componentAreaAttribute = (new ComponentArea())
                    ->disableBackgroundOption()
                    ->setSubFolder($modelString.'_component_data')
                    ->setComponentTypes(ComponentTypes::getAsArray())
                    ->mapValueFrom(Attribute::ValueFromComponents, $this->componentAreaAttributeKeyAsString)
                    ->setAssociatedLanguage($this->language)
                    ->setValue(json_encode($componentAreaAttributeValue));

                $componentAreaService->saveOrUpdateComponentAreaForAttribute($translation, $componentAreaAttribute);
            }
        }
    }

    /**
     * @param string $modelString
     * @return string
     */
    private function convertStringToModel(string $modelString)
    {
        switch ($modelString) {
            case 'pages':
                return Page::class;

            case 'packages':
                return Package::class;

            case 'pricing-labels':
                return PricingLabel::class;

            case 'product-groups':
                return ProductGroup::class;

            case 'products':
                return Product::class;
        }

        return null;
    }

    private function getModel($key)
    {
        if (in_array($this->forModel, [Page::class, Package::class, PricingLabel::class])) {
            return $this->forModel::where('code_name', $key)->first();
        }

        if (in_array($this->forModel, [ProductGroup::class, Product::class])) {
            // Explode the keys on _
            $keys = explode('_', $key);
            $id = end($keys);

            // The last one is the id of the to find model
            return $this->forModel::find($id);
        }

        return null;
    }

    private function convertIntoComponents($components, $language)
    {
        $componentAreaAttributeValue = [];
        $componentCounter = 0;

        // Get the components id by name
        $componentTypesKeysByName = [];
        $componentTypes = ComponentTypeFactory::make();
        foreach ($componentTypes as $componentType) {
            $componentTypesKeyedByName[$componentType->getName()] = $componentType->getId();
        }

        foreach ($components as $key => $values) {
            // Because we used the id as unique value as last part of the component identifiers  we have to remove it before we know which component it is
            // We don't know if some name have underscore so we explode remove the last key and implode it back together
            $componentExplodedKey = explode('_', $key);
            array_pop($componentExplodedKey);
            $componentTypeKey = implode('_', $componentExplodedKey);

            // Make the component
            $componentModel = ComponentTypeFactory::make($componentTypesKeyedByName[$componentTypeKey]);

//            dd($values, $componentModel);

            $componentData = [];
            foreach ($values as $valueKey => $value) {
                $componentData['ComponentArea|'.$this->componentAreaAttributeKeyAsString.'|C'.$componentCounter.'|'.$valueKey.'|'.$language->iso_2] = $value;
            }

            $componentAreaAttributeValue[] = (object) [
                'id'                => ($componentCounter * -1),
                'version'           => '0.9.1',
                'componentTypeId'   => $componentTypesKeyedByName[$componentTypeKey],
                'data'              => (object) $componentData,
                'componentableData' => (object) [],
                'sortOrder'         => $componentCounter,
            ];
            $componentCounter++;
        }

        return $componentAreaAttributeValue;
    }
}