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/lmbm.komma.pro/app/KommaApp/Kms/Core/Sections/KmsSection.php
<?php
///**
// *
// *
// * @author      Komma <info@komma.pro>
// * @copyright   (c) 2012-2016, Komma
// */
//
//namespace App\KommaApp\Kms\Core\Sections;
//
//use App\KommaApp\Images\ImageService;
//use App\KommaApp\Kms\Core\Attributes\Attribute;
//use App\KommaApp\Kms\Core\Attributes\ImageableAttribute;
//use App\KommaApp\Kms\Core\Attributes\Password;
//use App\KommaApp\Kms\Core\Attributes\Traits\LabelTrait;
//use App\KommaApp\Languages\Models\Language;
//use Illuminate\Database\Eloquent\Model;
//use Illuminate\Database\Eloquent\Collection;
//use Illuminate\Support\ViewErrorBag;
//use App\KommaApp\Kms\Core\Kms;
//use App\KommaApp\Kms\Core\KmsRepository;
//use Illuminate\View\View;
//
///**
// * Class KmsSection
// *
// * @package App\KommaApp\Kms\Core\Sections
// * @deprecated Replaced by Section
// * @see Section
// */
//abstract class KmsSection
//{
//    protected $kms;
//
//    /**
//     * @var KmsRepository
//     */
//    protected $repository;
//
//    protected $eventListeners = [];
//
//    /**
//     * @var SectionTabsCollectionInterface
//     */
//    private $sectionTabDirector;
//
//    /** @var Collection The AbstractSectionTabItem instances that belong to a sectionTab. Todo: this should be the sectionTab instead. If we edit this like i described then we must modify related code too*/
//    protected $sectionTabItems;
//
//    private $proccessedAttributes = [];
//
//    /** @var Model $model */
//    private $model = null;
//    protected $models = [];
//
//    //True if the models uses an eav
//    protected $eav = false;
//
//    protected $errors = [];
//
//    protected $title = "";
//    protected $subTitle = "";
//    protected $slug = "";
//
//    public $submitButtonLabel = "save";
//    public $submitRoute = null;
//
//    public $type = 'model';
//
//    public $keyAsArray = false;
//    public $keyArrayKey = '';
//
//    /*
//     * Protected actions
//     * options:
//     * all - can be accessed by everybody
//     * admin - can be accessed only by super admins
//     * none - can be accessed by nobody
//     */
//    public $showSave = 'all';
//    public $showDelete = 'all';
//    public $showCreate = 'all';
//
//    //When this var is true, the right pane will be generated
//    public $showEntity = true;
//
////    function __construct (Kms $kms, KmsRepository $repository, AbstractSectionTabsDirector $sectionTabDirector)
//    function __construct (Kms $kms, SectionService $siteService, AbstractSectionTabsDirector $sectionTabDirector)
//    {
//        $this->kms = $kms;
//        $this->repository = $siteService;
//        $this->sectionTabDirector = $sectionTabDirector;
//        $this->sectionTabDirector->buildTabs();
//
//        $this->initializeEventListeners();
//
//        //localize
//        $this->submitButtonLabel = \Lang::get('kms/global.save');
//    }
//
//    protected function initializeEventListeners()
//    {
//        foreach ($this->eventListeners as $listenerKey => $listenerValue) {
//            Event::listen('*', function ($listenerKey, array $listenerValue) {
//                //
//            });
//        }
//    }
//
//    public function getRepository()
//    {
//        return $this->repository;
//    }
//
//    public function getTitle()
//    {
//        return $this->title;
//    }
//
//    public function getSubTitle()
//    {
//        return $this->subTitle;
//    }
//
//    public function getSlug()
//    {
//        return $this->slug;
//    }
//
//    public function getEntities()
//    {
//        return $this->models;
//    }
//
//    public function setKeyAsArray($keyAsArray)
//    {
//        $this->keyAsArray = $keyAsArray;
//    }
//
//    public function setKeyArrayKey($keyArrayKey)
//    {
//        $this->keyArrayKey = $keyArrayKey;
//
//    }
//
//
//    /**
//     * This method will generate the list of models.
//     * These are used in the sidebar.
//     *
//     * @return mixed
//     */
//    public function loadModels()
//    {
//        \Log::debug("KmsSection:153 ");
//        //If getSortable() returns true, dont load the models, they are loaded via Ajax
//        if ($this->getSortable()) return null;
//
//        return $this->models = $this->repository->getModels();
//    }
//
//    /**
//     * This method returns the thumbnail for the top bar
//     *
//     * @return string
//     */
//    public function getThumbnail()
//    {
//        //Check if a thumbnail is set
//        if (isset($this->model->thumbnail)) {
//            //If there is an image_url set, return with image tags
//            if (isset($this->model->thumbnail['image_url'])) {
//                return '<img src="' . $this->model->thumbnail['image_url'] . '"/>';
//            }
//            //If there is a string set as array, return only the string
//            elseif (isset($this->model->thumbnail['string'])) {
//                return $this->model->thumbnail['string'];
//            }
//            //return thumbnail
//            else return '';
//        }
//        //Return empty string
//        return '';
//    }
//
//
//    /**
//     * This method is called when an model is called
//     * eg. for the edit form via the controller
//     *
//     * @param null $idOrModel
//     * @return null
//     */
//    public function loadModel($idOrModel = null)
//    {
////        \Log::debug("KmsSection:191 loadModel");
//
//        if(is_numeric($idOrModel) || is_null($idOrModel)) {
//            $this->model = $this->repository->getModel($idOrModel);
//        }
//        elseif(gettype($idOrModel) == "object" && is_a($idOrModel, Model::class))
//        {
//            $this->model = $idOrModel;
//            $this->repository->setThumbnail($idOrModel);
//        } else {
//            throw new \InvalidArgumentException("KmsSection loadModel expected a variable of type int or numeric string or eloquent model but got a variable of type: ".gettype($idOrModel));
//        }
//
//        return $this->model;
//    }
//
//    public function setOrCreateModel($model)
//    {
//        if ($model == null) {
//            $this->model = $this->repository->newModel();
//        } else {
//            $this->model = $model;
//        }
//
//        return $this->model;
//    }
//
//    /**
//     * This method returns the model id.
//     * When there is no model it returns false.
//     *
//     * @return mixed False, model id
//     */
//    public function getModelId()
//    {
//        //Check if there is an model, return false
//        if (!$this->model) return false;
//        //Return the model id
//        return $this->model->id;
//    }
//
//    /**
//     * Gets the model name
//     */
//    public function getModelName($stripModelSuffix = true)
//    {
//        if(!$this->model) return '';
//
//        $reflect = new \ReflectionClass($this->model);
//
//        $className = $reflect->getShortName();
//
//        if($stripModelSuffix) $className = str_ireplace('model', '', $className);
//
//        return $className;
//    }
//
//    public function getModel()
//    {
////        if($this->model) \Log::debug("KmsSection:250 getModel (exists)"); else \Log::debug("KmsSection:250 (does not exist)");
//        return $this->model;
//    }
//
//
//    /**
//     * This method returns the title of the model
//     * It will check if there is an model title
//     * or returns new {type}
//     *
//     * @return string
//     */
//    public function getModelTitle()
//    {
//        //If there is an title set use this
//        if ($this->model && $this->model->exists && ($this->model->title || $this->model->title != "")) {
//            return $this->model->title;
//        }
//
//        //No model title return new {type}
//        return ucfirst(\Lang::get('kms/global.new')) . ' ' . lcfirst(\Lang::get('kms/' . $this->slug . '.type'));
//    }
//
//    /**
//     * Generates the attributes for this section. They all must extend the App\KommaApp\Kms\Core\Attributes\Attribute class
//     *
//     * @return Collection A collection of SectionTabItems
//     */
//    abstract protected function generateAttributes(): Collection;
//
//
//    /**
//     * Generates the attributes for the section using the sections generatesAttributes method
//     * and adds them to the appropriate tabs
//     *
//     * @return void
//     */
//    public function generateAttributesAndAddThemToTabs()
//    {
//        \Log::debug("KmsSection:292 ");
//
//        $this->sectionTabItems = $this->generateAttributes();
//        $this->addAttributesToTabs();
//    }
//
//    /**K
//     * Returns a rendered view
//     *
//     * @return \Illuminate\View\View
//     */
//    public function render()
//    {
//        \Log::debug("KmsSection:300 render");
//        if($this->showEntity) $this->generateAttributesAndAddThemToTabs();
//
//        \Log::debug("KmsSection:308 render");
//        if(!$this->getModel()) return $this->makeView(); //Return a view since we can't fill it with data because the model is not set.
//
//        \Log::debug("KmsSection:311");
//        $this->getRepository()->fillAttributesWithData($this->sectionTabItems, $this->getModel());
//
//        \Log::debug("KmsSection:314");
//        return $this->makeView();
//    }
//
//    /**
//     * Makes the view and returns it
//     */
//    private function makeView(): View
//    {
//        return \View::make('kms/section.index', [
//            'kms' => $this->kms,
//            'section' => $this
//        ]);
//    }
//
//    /**
//     * This method will trigger the save method
//     *
//     * @param $id
//     * @throws \Exception
//     */
//    public function update($id)
//    {
//        $this->generateAttributesAndAddThemToTabs();
//        $this->save($id);
//    }
//
//    /**
//     * This method creates or updates a model.
//     * Based on the input data of the form.
//     *
//     * @param Model $model
//     * @return $id
//     * @throws \Exception
//     */
//    public function save(Model $model = null)
//    {
//        $this->fillAttributesFromInput();
//
//        //This will trigger the repository saveModel method
//        $model = $this->repository->saveModel($model, $this->sectionTabItems);
//
//        $this->processImageableAttributesFromInput($model);
//
//        //Fire the event saved method
//        \Event::fire('kms.entity.saved.' . $this->slug, $this->model);
//
//        //Return the id
//        return $model;
//    }
//
//    /**
//     * This method calls the destroyModel method
//     * from the give repository class.
//     *
//     * @param $id
//     * @return mixed
//     * @throws \Exception
//     */
//    public function destroy($id)
//    {
//        return $this->repository->destroyModel($id);
//    }
//
//    /**
//     * Thhis method creates a error list / attribute
//     *
//     * @param ViewErrorBag|null $errors
//     */
//    public function setErrors(ViewErrorBag $errors = null)
//    {
//        //If errors are empty; return
//        if (!$errors) return;
//        //Get the errors from the error
//        $this->errors = $errors->getMessages();
//
//        if(!$this->sectionTabItems) return;
//
//        $this->sectionTabItems->each(function($sectionTabItem, $key) {
//            /** @var SectionTabItem $sectionTabItem */
//            $attribute = $sectionTabItem->getAttribute();
//
//            if (isset($errors)) {
//                $errors = $this->errors[$attribute->getKey().''];
//                $attribute->getValidationSet()->setErrors($errors);
//            }
//        });
//    }
//
//    /**
//     * Iterates over all sectionTabItem instances and builds a Validator
//     * from the rules and messages in them.
//     *
//     * @param array $input The input to validate. The function wil retrieve the input itself if you don't specify this.
//     * If you specify it must be an associative array containing input names as keys and values as values from
//     * those inputs.
//     *
//     * @return \Validator
//     */
//    public function validateInputAndReturnValidator(array $input = [])
//    {
//        $this->extendValidator();
//
//        if(empty($input)) $input = \Input::all();
//
//        $rules = [];
//        $messages = [];
//
//        /** @var AbstractSectionTabItem $sectionTabItem */
//        foreach($this->sectionTabItems as $sectionTabItem)
//        {
//            $attribute = $sectionTabItem->getAttribute();
//            $set = $attribute->getValidationSet();
//
//            if(!$set->hasRulesAndMessages()) continue;
//
//            //prepend the attribute key in front of each message rule followed by a dot to make sure the message is unique for each attribute.
//            $set->prefixMessageRulesWith((string)$attribute->getKey());
//
//            //And replace :attribute with the label text of the attribute
//            if(in_array(LabelTrait::class, class_uses($attribute))) $set->modifyMessages(":attribute", $attribute->getLabelText());
//
//            $rules = array_merge($rules, [(string)$attribute->getKey() => $set->getRules()]);
//            $messages = array_merge($messages, $set->getMessages());
//        }
//
////        dd($rules);
//        $validator = \Validator::make($input, $rules, $messages);
//
//        return $validator;
//    }
//
//
//    /**
//     * This method is used to show/hide the create button
//     * Based on the user and the settings it will return true or false
//     *
//     * @return bool
//     */
//    public function showCreate()
//    {
//        if (is_array($this->showCreate)) {
//            return in_array(\Auth::user()->role->id, $this->showCreate);
//        }
//
//        return $this->showCreate == 'all' || ($this->showCreate == 'admin' && \Auth::user()->role->id == 1);
//    }
//
//    /**
//     * This method is used to show/hide the delete button (delete possible)
//     * Based on the user and the settings it will return true or false
//     *
//     * @return bool
//     */
//    public function showDelete()
//    {
//        if (is_array($this->showDelete)) {
//            return in_array(\Auth::user()->role->id, $this->showDelete);
//        }
//
//        return $this->showDelete == 'all' || ($this->showDelete == 'admin' && \Auth::user()->role->id == 1);
//    }
//
//    /**
//     * This method is used to show/hide the save button (update possible)
//     * Based on the user and the settings it will return true or false
//     *
//     * @return bool
//     */
//    public function showSave()
//    {
//        if (is_array($this->showSave)) {
//            return in_array(\Auth::user()->role->id, $this->showSave);
//        }
//
//        return $this->showSave == 'all' || ($this->showSave == 'admin' && \Auth::user()->role->id == 1);
//    }
//
//    /**
//     * Create a list with KmsAttribute Objects, based on $this->modelAttributes
//     * The data is from the modelSection file
//     *
//     * @return array
//     */
//    protected function parseModelAttributesData($test = false)
//    {
//        //TODO JULES: REBUILD THIS OOP. THIS METHOD PROBABLE CAN BE DELETED IN THE FUTURE
//
//        //Create  empty attributes
//        $this->sectionTabItems = [];
//
//
//        foreach ($this->sectionTabItems as $attributeKey => $attribute) {
//            if(is_object($attribute)) {
//                //Detected a new type of object! This branch is used for transitioning from not so OOP objects to OOP and will become obsolete in the future
//
//                $this->sectionTabItems[] = $attribute;
////                $this->tabDirector->addItem($attribute, \Config::get('kms.main.defaultTabName')); TODO: This is now done in the section constructor
//            } else {
//                if (isset($attribute['role']) && !in_array(\Auth::user()->role->id, $attribute['role'] )) continue;
//
//                //Set the specific type of foreach
//                $forEach = isset($attribute['forEach']) ? $attribute['forEach'] : null;
//
//                //TODO JULES MAYBE WE SHOULD CREATE FACTORYS / BUIDERS FOR THIS STUFF BELOW
//                // create attributes
//                switch ($forEach) {
//                    case "CurrentSiteLanguages":
////                        $this->createAttributeForCurrentSiteLanguages($attributeKey, $attribute);
//                        $this->createAttributeForCurrentSiteLanguages($attributeKey, $attribute);
//                        break;
//                    case "AllLanguages":
//                        $this->createAttributeForAllLanguages($attributeKey, $attribute);
//                        break;
//                    case "AllSites":
//                        $this->createAttributeForAllSites($attributeKey, $attribute);
//                        break;
//                    case "AllSitesAsSub":
//                        $this->createAttributeForAllSites($attributeKey, $attribute, true);
//                        break;
//                    case "AllSitesAndLanguages":
//                        $this->createAttributeForAllSitesAndLanguages($attributeKey, $attribute);
//                        break;
//                    case'AllForeachModels':
//                        $this->createAttributeForAllForeachModel($attributeKey, $attribute);
//                        break;
//                    case'AllForeachModelsForAllSites':
//                        $this->createAttributeForAllForeachModel($attributeKey, $attribute, 'AllSites');
//                        break;
//                    case 'AllForeachModelsForAllSitesAndLanguages':
//                        $this->createAttributeForAllForeachModel($attributeKey, $attribute, 'AllSitesAndLanguages');
//                        break;
//                    default:
//                        $this->createAttribute($attributeKey, $attribute);
//                        break;
//                }
//            }
//        }
//
////        dd($this->attributes);
//        return $this->sectionTabItems;
//    }
//
////    /**
////     * This method will create the field for the normal attributes
////     *
////     * @param $key
////     * @param $attributeData
////     */
////    protected function createAttribute($key, $attributeData)
////    {
////        //NOTE: METHOD IS DEPRECATED. Don't use it anymore
////
////        //Set the value, check if the model is set and has an $key parameter, set this or set null
////        $value = isset($this->model) && $this->model->$key ? $this->model->$key : null;
////
////        //Check if there is an releated attribute
////        if ($relatedAttribute = $this->getRelatedAttribute($key, $attributeData)) $value = $relatedAttribute;
////
////        //Set the options check if there is an attributeDatap['options'], parse this, or set an empty array
////        $options = isset($attributeData['options']) ? $this->parseOptions($attributeData['options']) : [];
////        //Check if an specific tab is set, if not set to the default tab
////        $tab = isset($attributeData['tab']) ? $attributeData['tab'] : \Config::get('kms.main.defaultTabName');
////
////
////        $key = $this->generateKey($key);
////
////        //create a new AttributeDAta based on the given values and set these in item and add this to the attributes array
////        $item = $this->attributes[] = new $attributeData['type']($key, $value, $options, [], null, null, $this);
////        //Set the item to the tab
//////        $this->tabDirector->addItem($item, $tab);
////    }
////
////    /**
////     * This method will create the fields for the given languages
////     *
////     * @param $key
////     * @param $attributeData
////     * @param $languages
////     * @return null
////     */
////    protected function createAttributeForLanguages($key, $attributeData, $languages)
////    {
////        //NOTE: METHOD IS DEPRECATED. Don't use it anymore
////
////
////        //Check if the key populate exist and its value is false; this is an field that is just info, return NULL
////        if (isset($attributeData['populate']) && $attributeData['populate'] === false) return NULL;
////
////
////
////        //Loop trough each language of the current site
////        foreach ($languages as $language) {
////
////            //Set the default value to an empty string (new model, or modeltranslation)
////            $value = '';
////
////            //Set translation to null
////            $translation = null;
////            //Check if there is an translation with the current language_id coupled to the model
////            if ($this->model != null && method_exists($this->model, 'translations')) {
////                $translation = $this->model->translations()->where('language_id', '=', $language->id)->first();
////            }
////            elseif ($this->model != null && $this->model->translations != null) {
////                $translation = $this->model->translations->where('locale', $language->iso_2)->first();
////            }
////            elseif ($this->model != null && $this->model->translations != null) {
////                $translation = $this->model->translations->where('language_id', $language->id)->first();
////            }
////
////            if ($translation) {
////                //NOTE: Debug code. Works for kmsslug for example
//////                if(isset($translation->$key))
//////                {
//////                    dd($translation);
//////                }
////
////                //Switch the function with the attribute key
////                $value = isset($translation->$key) ? $translation->$key : null;
////
////                if ($relatedAttribute = $this->getRelatedAttribute($key, $attributeData, $this->kms->getSiteId(), $language->id)) {
////                    $value = $relatedAttribute;
////                }
////                if (isset($attributeData['model'])) {
////                    $value = $this->getSubModelValue($key, $attributeData, $this->kms->getSiteId(), $language->id);
////                };
////            }
////            //If the options are set, parse these options with the language_id, if not options is an empty array()
////            $options = isset($attributeData['options']) ? $this->parseOptions($attributeData['options'], $language->id) : [];
////
////
////            $tab = isset($attributeData['tab']) ? $attributeData['tab'] : $language->iso_2;
////
////            $currentKey = $this->generateKey([$key, $language->id]);
////
//////            if($attributeData['type'] == KmsDynamic::class) dd($value);
////
////            $sectionItem = new $attributeData['type']($currentKey, $value, $options, [], null, $language->id, $this);
////            $this->attributes[] = $sectionItem;
////
//////            $this->tabDirector->addItem($sectionItem, $tab);
////        }
////    }
//
//
//    /**
//     * Creates copies of the $baseAttribute for each language given.
//     * Also retrieves the translation that belongs to the model based on each language that is being processed.
//     * The translation is stored inside if it exists the attribute to later on check at which tab in a section it belongs.
//     *
//     * @param Attribute $baseAttribute
//     * @param $languages
//     * @return array with the created attributes
//     */
//    private function createAttributesFromBaseAttributeForTheGivenLanguages(Attribute $baseAttribute, $languages) //TODO: Replace old method (createAttributeForLanguages) with this one when done rewriting the attributes
//    {
//        $createdAttributes = [];
//
//        //Loop trough each language of the current site
//        foreach ($languages as $language) {
//            //Get the translation of the model
//
//            $clone = clone $baseAttribute;
//
//            if($language) $clone->setAssociatedLanguage($language);
//
//            $createdAttributes[] = $clone;
//        }
//
//        return $createdAttributes;
//    }
//
//
//    /**
//     * This method create copies of the attributes you pass it for all current site languages and
//     * injects translations via another method
//     *
//     * @param $baseAttributes
//     * @return array
//     */
//    protected function createAttributesFromExistingAttributeForCurrentSiteLanguages(Array $baseAttributes)
//    {
//        //Get the languages
//        $languages = $this->kms->getSiteLanguages();
//
//        $attributes = [];
//        foreach($baseAttributes as $baseAttribute) {
//            $attributesCreatedFromBaseAttribute = $this->createAttributesFromBaseAttributeForTheGivenLanguages($baseAttribute, $languages);
//            $attributes = array_merge($attributes, $attributesCreatedFromBaseAttribute);
//        }
//        return $attributes;
//    }
//
//    /**
//     * This method will create the fields for all the Languages
//     *
//     * @param $key
//     * @param $attributeData
//     * @return null
//     */
//    protected function createAttributeForAllLanguages($key, $attributeData)
//    {
//        //Get the languages
//        $languages = $this->kms->getAvailableLanguages();
//        $this->createAttributeForLanguages($key, $attributeData, $languages);
//    }
//
//    /**
//     * This method will create the fields for all the Languages
//     *
//     * @return null
//     */
//    protected function createAttributeFromExistingAttributeForAllLanguagesNew(Array $baseAttributes) //TODO: wil replace createAttributeForCurrentSiteLanguages when done rewriting attributes
//    {
//        //Get the languages
//        $languages = $this->kms->getAvailableLanguages();
//
//
//        $attributes = [];
//        foreach($baseAttributes as $baseAttribute) {
//            $this->createAttributeForLanguages($key, $attributeData, $languages);
//        }
//    }
//
//
//    /**
//     * This method creates the fields for all the languages in all the sites
//     *
//     * @param $key
//     * @param $attributeData
//     */
//    protected function createAttributeForAllSitesAndLanguages($key, $attributeData)
//    {
//        //NOTE: METHOD IS DEPRECATED. Don't use it anymore
//
//
//        //Loop trough the sites
//        foreach ($this->kms->getSites() as $site) {
//
//
//            //Check if There is an sub models set, and load this.
//            if (!isset($attributeData['model']) || !$subModel = $this->getSubModel($this->model, $attributeData['model'], $attributeData, 'site_id', $site->id)) {
//                //Set the default model to submodel
//                $subModel = $this->model;
//            }
//
//            //Loop trough the site languages
//            foreach ($site->languages as $language) {
//
//                //Load the ModelTranslation
//                if (!$modelTranslation = $this->getModelTranslation($subModel, $language->id)) {
//                    //set the submodel to the ModelTranslation
//                    $modelTranslation = $subModel;
//                }
//
//                //Set the value
//                $value = isset($modelTranslation->$key) ? $modelTranslation->$key : null;
//
//                if ($relatedAttribute = $this->getRelatedAttribute($key, $attributeData, $site->id, $language->id)) $value = $relatedAttribute;
//
//                //Parse the options
//                $options = isset($attributeData['options']) ? $this->parseOptions($attributeData['options'], $language->id, $site->id) : [];
//                //Create the site tab
//                $tab = $site->short_name;
//                //Create the sub tab based on the language
//                $subTab = $language->iso_2;
//                //Set the key to $key_language_id_site_id
//                $currentKey = $key . '_' . $language->id . '_' . $site->id;
//                //Create a new attributes
//                $item = $this->sectionTabItems[] = new $attributeData['type']($currentKey, $value, $options, [], $site->id, $language->id, $this);
//                //Add the item to the tab
////                $this->tabDirector->addItem($item, $tab, $subTab);
//            }
//        }
//    }
//
//    /**
//     * This method creates the fields for all the sites
//     *
//     * @param $key
//     * @param $attributeData
//     */
//    protected function createAttributeForAllSites($key, $attributeData, $subTab = false)
//    {
//        //NOTE: METHOD IS DEPRECATED. Don't use it anymore
//
//        if ($key == 'site_label') return;
//
//        //Loop trough the site
//        foreach ($this->kms->getSites() as $site) {
//
//            $value = isset($this->model) && isset($this->model->$key) ? $this->model->$key : null;
//
//            //GEt the value by the related attribute
//            if ($relatedAttribute = $this->getRelatedAttribute($key, $attributeData, $site->id)) $value = $relatedAttribute;
//            //Check if there is an model set, load the model sorted by the site_id
//            elseif (isset($attributeData['model']) && $subModel = $this->getSubModel($this->model, $attributeData['model'], $attributeData, 'site_id', $site->id)) {
//                $value = (isset($subModel->$key) ? $subModel->$key : $value);
//            }
//
//
//            //parse the options
//            $tab = $site->short_name;
//            $options = isset($attributeData['options']) ? $this->parseOptions($attributeData['options'], null, $site->id) : [];
//            //Create the site tab
//            //Create the ket from $key and site id
//            $currentKey = $key . '_' . $site->id;
//
//            //Check if there is an attribute foreach, set this to $foreach
//            if (isset($attributeData['forEach'])) $foreach = $attributeData['forEach'];
//            //Create a new attributes
//            $item = $this->sectionTabItems[] =
//                new $attributeData['type']($currentKey, $value, $options, [], $site->id, null, $this, $foreach);
//            //Add the item to the tab
//
//            if ($subTab) {
////                $this->tabDirector->addItem($item, null, $tab);
//            } else {
////                $this->tabDirector->addItem($item, $tab);
//
//            }
//        }
//    }
//
//    /**
//     * This method creates the fields for all the instances of the given model.
//     *
//     * @param $key
//     * @param $attributeData
//     */
//    public function createAttributeForAllForeachModel($key, $attributeData, $repeat = null)
//    {
//        //NOTE: METHOD IS DEPRECATED. Don't use it anymore
//
//
//        //Check if the foreachmodel is set, if not abort 500, with the corresponding error.
//        if (!isset($attributeData['forEachModel']))
//            return \App::abort(500, 'ForeachModel for ' . $key . ' not set!');
//
//        //Set the foreach model to an array
//        $foreachModel = $attributeData['forEachModel'];
//
//        //Check if the model has the releatedForeachModel, if not abort 500, with the corresponding error.
//        if (!$foreachModels = $this->model->$foreachModel)
//            return \App::abort(500, $foreachModel . ' not found on ' . get_class($this->model) . '!');
//
//        //Check if the relatedModel count is 0
//        if ($foreachModels->count() == 0) {
//            //Get the foreachModel als relation
//            $modelRelation = $this->model->$foreachModel();
//            //Set the empty related model (the foreachModel) to the foreachModels
//            $foreachModels[] = $modelRelation->getRelated();
//        }
//
//
//        //We got foreachModels, let start to work
//        foreach ($foreachModels as $loopKey => $model) {
//
//            //Count  = $loopkey +1
//            $count = $loopKey++;
//
//            //Set the current key with Key and the Count
//            $currentKey = $key . '_' . $count;
//
//            $foreach = null;
//
//
//            $tabName = isset($attributeData['tab']) ? $attributeData['tab'] : \lang::get('kms/global.foreach_name.' . $foreachModel);
//
//            if (isset($attributeData['forEachTab']) && $attributeData['forEachTab'] === false) {
//                $tabName = $tabName;
//            } elseif (isset($attributeData['forEachTabKey']) && $model->$attributeData['forEachTabKey'] != null) {
//                $tabName .= ' ' . $model->$attributeData['forEachTabKey'];
//            } else {
//                $tabName .= ' ' . $count;
//            }
//
//
//            switch ($repeat) {
//                case 'AllSites':
//                    $this->forEachModelAllSites($key, $attributeData, $model, $count, $tabName);
//                    break;
//                case 'AllSitesAndLanguages':
//                    $this->forEachModelAllSitesAndLanguages($key, $attributeData, $model, $count, $tabName);
//                    break;
//                default:
//                    $options = isset($attributeData['options']) ? $this->parseOptions($attributeData['options'], null, null, $loopKey, $model->id) : [];
//
//                    //Get the value for the given key
//                    $value = $this->getItemValue($key, $attributeData, null, null, $model);
//                    $item = $this->sectionTabItems[] =
//                        new $attributeData['type']($currentKey, $model, $options, [], $model->id, null, $this, $loopKey);
////                    $this->tabDirector->addItem($item, $tabName);
//            }
//
//        }
//    }
//
//    public function forEachModelAllSites($key, $attributeData, $model, $count, $tabName)
//    {
//        //NOTE: METHOD IS DEPRECATED. Don't use it anymore
//
//
//        foreach ($this->kms->getSites() as $site) {
//            $currentKey = $key . '_' . $count . '_' . $site->id;
//            $value = $this->getRelatedAttribute($key, $attributeData, $site->id, null, $model);
//            $options = isset($attributeData['options']) ? $this->parseOptions($attributeData['options'], null, $site->id, $count, $model->id) : [];
//
//
//            $item = $this->sectionTabItems[] =
//                new $attributeData['type']($currentKey, $value, $options, [], $site->id, null, $this, null);
////            $this->tabDirector->addItem($item, $tabName, $site->short_name);
//        }
//    }
//
//    public function forEachModelAllSitesAndLanguages($key, $attributeData, $model, $count, $tabName)
//    {
//        //NOTE: METHOD IS DEPRECATED. Don't use it anymore
//
//
//        foreach ($this->kms->getSites() as $site) {
//            foreach ($this->kms->getSiteLanguages($site->id) as $language) {
//                $currentKey = $key . '_' . $count . '_' . $site->id . '_' . $language->id;
//                $value = $this->getRelatedAttribute($key, $attributeData, $site->id, $language->id, $model);
//                $options = isset($attributeData['options']) ? $this->parseOptions($attributeData['options'], $language->id, $site->id, $count, $model->id) : [];
//
//
//                $item = $this->sectionTabItems[] =
//                    new $attributeData['type']($currentKey, $value, $options, [], $site->id, $language->id, $this, null);
////                $this->tabDirector->addItem($item, $tabName, $site->short_name, $language->iso_2);
//            }
//        }
//    }
//
//
//    public function getItemValue($key, $attributeData, $siteId = null, $languageId = null, $model = null)
//    {
//
//        //Set the value in the most basic way
//        if (isset($model->$key)) return $model->$key;
//        //Check if there is an relatedAttribute
//        if ($value = $this->getRelatedAttribute($key, $attributeData, $siteId, $languageId, $model)) return $value;
//
//        //Return the model when nothing is found
//        return $model;
//    }
//
//
////    TODO: We should not need this. We may implement related attribtutes as embeded child attributes in attributes themselves.
////    public function getRelatedAttribute($key, $attributeData, $siteId = null, $languageId = null, $model = null)
////    {
////        //Check if it has the parameter relatedAttribute and is true
////        if (!isset($attributeData['relatedAttribute']) || !$attributeData['relatedAttribute']) return null;
////
////        //Set the $this->model to the model
////        if ($model == null) $model = $this->model;
////
////        //Check if there is an submodel and it exist
////        if (isset($attributeData['model'])) {
////            $models = explode('->', $attributeData['model']);
////            foreach ($models as $countKey => $deeperLevel) {
////
////                $keyId = (isset($attributeData['relatedAttributeOptions'][$countKey]['keyId']) ? $this->replaceModelStrings($attributeData['relatedAttributeOptions'][$countKey]['keyId'], $siteId, $languageId, $model) : null);
////                $keyBy = (isset($attributeData['relatedAttributeOptions'][$countKey]['keyBy']) ? $attributeData['relatedAttributeOptions'][$countKey]['keyBy'] : null);
////                //Check if it is an method
////                if (preg_match('/([a-z0-9_]+)\((.*)\)/i', $deeperLevel, $matches)) {
////                    //If the method doesn't exist exit to a 500 page
////                    if (!method_exists($model, $matches[1])) return \App::abort(500, 'Method ' . $matches[1] . ' doesn\'t exist on section-key: ' . $key);
////
////                    $parameters = (!empty($matches[2]) ? explode(',', $matches[2]) : []);
////
////                    $model = call_user_func_array([$model, $matches[1]], $parameters);
////
////                } else {
////                    $model = $this->getSubModel($model, $deeperLevel, $attributeData, $keyBy, $keyId);
////                }
////
////            }
////            if (!$model) return false;
////
////            //if KeyBy is is not set, return the current model (or collection)
////            if (!isset($keyBy)) return $model;
////        }
////
////        //Check if the model exists, if not return false
////        if (!$model) return false;
////
////        //Get the value of the model
////        return $model->getValue($key, $siteId, $languageId);
////
////    }
//
////    TODO: We should not need this. We may implement related attribtutes as embeded child attributes in attributes themselves.
////    public function getSubModelValue($key, $attributeData, $siteId = null, $languageId = null, $model = null)
////    {
////
////        $model = $this->getSubModelExtended($key, $attributeData, $siteId, $languageId, $model);
////
////        if (is_string($model)) return $model;
////
////        if ($model && $model->$key) return $model->$key;
////
////        return $model;
////    }
//
////    TODO: We should not need this. We may implement related attribtutes as embeded child attributes in attributes themselves.
////    public function getSubModelExtended($key, $attributeData, $siteId = null, $languageId = null, $model = null)
////    {
////        //Set the $this->model to the model
////        if ($model == null) $model = $this->model;
////
////        //Check if there is an submodel and it exist
////        if (!isset($attributeData['model'])) return false;
////
////        //Split the model by ->
////        $models = explode('->', $attributeData['model']);
////        //loop trough the models and keep the dept of the level ($countKey)
////
////        foreach ($models as $countKey => $deeperLevel) {
////
////            //Set the KeyId if exist
////            $keyId = (isset($attributeData['relatedAttributeOptions'][$countKey]['keyId']) ? $this->replaceModelStrings($attributeData['relatedAttributeOptions'][$countKey]['keyId'], $siteId, $languageId, $model) : null);
////            //Set the KeyBy if exist
////            $keyBy = (isset($attributeData['relatedAttributeOptions'][$countKey]['keyBy']) ? $attributeData['relatedAttributeOptions'][$countKey]['keyBy'] : null);
////
////            //Check if the "model" is an method
////            if (preg_match('/([a-z0-9_]+)\((.*)\)/i', $deeperLevel, $matches)) {
////
////                //If the method doesn't exist exit to a 500 page
////                if (!method_exists($model, $matches[1])) return \App::abort(500, 'Method ' . $matches[1] . ' doesn\'t exist on section-key: ' . $key);
////
////                //  Explode the found $parameters, if they exist. or an empty []
////                $parameters = (!empty($matches[2]) ? explode(',', $matches[2]) : []);
////                //Call the method with call_user_func_array, so we can add the parameters as an array
////
////                $model = call_user_func_array([$model, $matches[1]], $parameters);
////            } else {
////                //No method, check if it is an subModel (or value)
////                $orgModel = $model;
////
////                $model = $this->getSubModel($model, $deeperLevel, $attributeData, $keyBy, $keyId);
////                if(!$model && $orgModel) {
////                     //throw new \RuntimeException("Could not get subModel '".$deeperLevel."' from ".get_class($orgModel));
////                }
////            }
////
////        }
////
//////        if(!$model) throw new \RuntimeException("Model wasn't found for key: ".$key." Models: ".$attributeData['model']);
////
////        return $model;
////    }
//
//
//    /**
//     * This method loads the subModel from the $this->model colleciton.
//     * It uses the modelName and an sort field and the specific key.
//     *
//     * @param $attributeData
//     * @param $keyBy | Db field that is used to map the array
//     * @param $keyId | the id of the key we want
//     * @return mixed
//     */
//    public function getSubModel($model, $subModelName, $attributeData, $keyBy = 'id', $keyId = null)
//    {
//        if (!$keyId) $keyId = $this->model->id;
//
//
//        if (isset($attributeData['relatedAttributeOptions'])) {
//            $keyBy = (isset($attributeData['relatedAttributeOptions']['keyBy']) ? $attributeData['relatedAttributeOptions']['keyBy'] : $keyBy);
//            $keyId = (isset($attributeData['relatedAttributeOptions']['keyId']) ? $this->replaceModelStrings($attributeData['relatedAttributeOptions']['keyId']) : $keyId);
//        }
//
//        //Check if the model exists, if not return false
//        if (!$model) return false;
//        //Check if the model has the given model, if not return false
//
//        if (!$subModelCollection = $model->$subModelName) return false;
//
//        //If $keyBy is not set. return the entire collection
//        if (!isset($keyBy)) {
//            return $model->$subModelName;
//        }
//
//        //Sort the collection by the given keyBy parameter
//        $subModelCollection = $model->$subModelName->keyBy($keyBy);
//
//        //Return the wanted collection model based on the keyId, or false
//        $collection = $subModelCollection->get($keyId);
//
////        if($subModelName == "routes") { dd($subModelCollection); }
//
//        return $collection;
//    }
//
//    /**
//     * This method loads the translation from a given model colletion
//     *
//     * @param        $model | The model were we want to get the translation from
//     * @param        $language_id | the language id of the translation we want
//     * @param string $translationModel | the translation model default {translations}
//     * @param string $keyBy | Db field that is used to map the array defaukt {language_id}
//     * @return bool
//     */
//    public function getModelTranslation($model, $language_id, $translationModel = 'translations', $keyBy = 'language_id')
//    {
//        //Check if the model has the translationModel, if not return false
//        if (!$modelTranslations = $model->$translationModel) return false;
//        //Key the modelTranslations by the given key_by parameter
//        $modelTranslations = $modelTranslations->keyBy($keyBy);
//        //Get the wanted language model, or false
//        return $modelTranslations->get($language_id);
//    }
//
//
//    /**
//     * Set the section attributes by $this->currentEntities
//     * @param array /object $data
//     */
//    protected function populateAttributes()
//    {
//
//        //mooi('dit is niet gebruikt denk ik');
//        foreach ($this->sectionTabItems as $attribute) {
//            if ($attribute->getOption('populate') === false) continue;
//            $key = $attribute->getKey();
//            $value = $attribute->getValue();
//
//            $attribute->setValue($value);
//        }
//        $this->processAttributes();
//    }
//
//    /**
//     * Fills the model with the processed values form the attributes array.
//     * Processing happens in each attributes by $attribute->getValue()
//     * Eg. Hash::make in the Password attribute
//     */
//    protected function processAttributes()
//    {
//        foreach ($this->sectionTabItems as $key => $attribute) {
//            $attribute->process();
//            $this->proccessedAttributes[$attribute->getKey()] = $attribute;
//        }
//    }
//
//
////  //TODO Jules: We don't need this mess anymore because we handle this stuff in attributes them self via getters and setters in a more clear and concise way
////    /**
////     * Parse the options
////     *
////     * @param      $options
////     * @param null $languageId
////     * @param null $siteId
////     * @return mixed
////     */
////    private function parseOptions($options, $languageId = null, $siteId = null, $foreachCounter = null, $foreachModelId = null)
////    {
////
////        if ($siteId) $site = Site::find($siteId);
////        else {
////            $site = $this->kms->getSite();
////
////        }
////        if ($languageId) $language = Language::find($languageId);
////        foreach ($options as $key => $option) {
////
////            // Call recursively if the option is an array.
////            if (is_array($option)) $options[$key] = $this->parseOptions($option, $languageId, $siteId, $foreachCounter, $foreachModelId);
////
////            // Skip if option if isn't a string.
////            if (!is_string($option)) continue;
////
////            //Parse static strings to the value
////            if (isset($this->model->id)) {
////
////                //Replace the [[modelId]] to the model id
////                $options[$key] = $option = $this->model->id ?
////                    str_replace('[[modelId]]', $this->model->id, $option) : str_replace('[[modelId]]', '', $option);
////            }
////
////            if (isset($site)) {
////                //Replace [[siteName]] to the site name
////                $options[$key] = $option = str_replace('[[siteName]]', $site->name, $option);
////
////                //Replace [[siteId]] to the site id
////                $options[$key] = $option = str_replace('[[siteId]]', $site->id, $option);
////            }
////            if (isset($language)) {
////                //replace the [[languageId]] to the current language id
////                $options[$key] = $option = str_replace('[[languageId]]', $language->id, $option);
////                //replace the [[LanguageIso2]] to the current language id
////                $options[$key] = $option = str_replace('[[LanguageName]]', \Lang::get('languages.' . $language->iso_2), $option);
////                //replace the [[LanguageIso2]] to the current language iso
////                $options[$key] = $option = str_replace('[[languageIso]]', $language->iso_2, $option);
////            }
////            if (isset($foreachModelId)) {
////                //replace the [[foreachModelId]] to the current foreachModel id
////                $options[$key] = $option = str_replace('[[foreachModelId]]', $foreachModelId, $option);
////            }
////            if (isset($foreachCounter)) {
////                //replace the [[foreachModelId]] to the current foreachModel id
////                $options[$key] = $option = str_replace('[[foreachCounter]]', $foreachCounter, $option);
////            }
////
////            //Replace [[status]] with the status if it exist
////            if (isset($this->model->id) && $this->model->status) {
////                $options[$key] = $option = str_replace('[[status]]', $this->model->status, $option);
////            }
////
////            $options[$key] = $option = str_replace('[[key]]', $key, $option);
////
////            if (isset($this->model->id)) {
////
////                if(isset($this->model->translations)){
////                    // Replace routable id in validation rule
////                    $translations = $this->model->translations->keyBy('language_id');
////                }
////
////                if(isset($translations[$languageId]))
////                {
////                    $translationId = $translations[$languageId]->id;
////                    $options[$key] = $option = str_replace('[[routeableId]]', $translationId, $option);
////                }
////
////                foreach (get_class_methods($this->model) as $methodName) {
////                    // check if the method name is in the template to prevent automatic method calls
////                    $pos = strpos($option, '[[' . $methodName . ']]');
////                    if ($pos !== false) {
////                        $options[$key] = $option = str_replace('[[' . $methodName . ']]', $this->model->$methodName($siteId, $languageId), $option);
////                    }
////                }
////
////                // replace with a property in the model
////                foreach (get_object_vars($this->model) as $property => $value)
////                {
////                    if (is_string($value)) {
////                        $options[$key] = $option = str_replace('[[' . $property . ']]', $value, $option);
////                    }
////                }
////            }
////
////            //If the option starts with lang_get:, call the \Lang::get method with the option as parameter
////            if (preg_match('/^lang_get:([a-z0-9\/._\-]+)#?(.*)/i', $option, $match)) {
////
////                $options[$key] = $option = \Lang::get($match[1], ['value' => $match[2]]);
////            }
////            if (preg_match('/^config_get:([a-z0-9\/._\-]+)#?(.*)/i', $option, $match)) {
////
////                $options[$key] = $option = \Config::get($match[1], ['value' => $match[2]]);
////            }
////        }
////
////        return $options;
////    }
//
//
//    /**
//     * Fills all attributes with values from the forms / session
//     *
//     * @return void
//     * @throws \Exception
//     */
//    public function fillAttributesFromInput()
//    {
////        $imageService = new ImageService();
//
//        /** @var AbstractSectionTabItem $sectionTabItem */
//        foreach ($this->sectionTabItems as $sectionTabItem) {
//            //Insert the the appropriate value in the attribute
//            $attribute = $sectionTabItem->getAttribute();
//            $input = \Input::get((string)$attribute->getKey());
//
//            if($input) {
//                $attribute->setValue($input);
//            }
//
//            //Insert the associated language (if any) into the attribute
//            if($attribute->getKey()->getTranslationIso2() != '')
//            {
//                //get the language associated with the attribute]
//                $language = Language::where('iso_2', $attribute->getKey()->getTranslationIso2())->first();
//
//                $attribute->setAssociatedLanguage($language);
//            }
//        }
//    }
//
//    /**
//     * Iterates over all attributes and checks if they are have Imageable interfaces.
//     * If they do, it checks if the input contains an image for them and adds them to
//     *
//     * @param Model $model
//     * @throws \Exception
//     */
//    public function processImageableAttributesFromInput(Model $model)
//    {
//        $imageService = new ImageService();
//
//        /** @var AbstractSectionTabItem $sectionTabItem */
//        foreach ($this->sectionTabItems as $sectionTabItem) {
//
//            $attribute = $sectionTabItem->getAttribute();
//            $input = \Input::get((string)$attribute->getKey());
//
//            if(is_a($attribute, ImageableAttribute::class)) {
//                $imageService->setSubFolder($attribute->getSubfolder());
//                $imageAndStates = $imageService->uploadAndDeleteImagesFromInput($input, $attribute->getImageSizes());
//                    if($imageAndStates) $imageService->updateImageReferencesInDatabase($imageAndStates, $model);
//            }
//        }
//    }
//
//
//    /*
//     * This method returns the validation from the loaded section
//     *
//     * @return array
//     */
//    public function getValidation($id = null, $update = false, $model = null)
//    {
//
//
//        //set empty validation array
//        $validation = ['messages' => [], 'rules' => []];
//
//        //Loop trough the attributes (these are modelAttributesData parsed)
//        foreach ($this->sectionTabItems as $attribute) {
//            //If options doest't exist, continue
//            if (!isset($attribute->options)) continue;
//            //If the validation doesn't exist, continue
//            if (!isset($attribute->options['validation'])) continue;
//            //If the rules exist add these for the current key
//            if (isset($attribute->options['validation']['rules'])) $validation['rules'][$attribute->key] = $attribute->options['validation']['rules'];
//            //If the messages exist add these for the current key
//            if (!isset($attribute->options['validation']['messages'])) continue;
//
//            foreach ($attribute->options['validation']['messages'] as $key => $message) {
//                $validation['messages'][$attribute->key . '.' . $key] = $message;
//            }
//
//        }
//
//        return $validation;
//    }
//
//
//    /**
//     * This method will check if the repository is sortable
//     *
//     * @return bool
//     */
//    public function getSortable()
//    {
//        if (method_exists($this->repository, 'getSortable')) return $this->repository->getSortable();
//
//        return False;
//    }
//
//    /**
//     * Returns the data_type from the given key
//     * When it doesn't exist returns false
//     *
//     * @param $key
//     * @return bool
//     */
//    public function getDataType($key)
//    {
//        if (!isset($this->sectionTabItems[$key]['data_type'])) return false;
//        return $this->sectionTabItems[$key]['data_type'];
//    }
//
//    public function replaceModelStrings($string, $siteId = null, $languageId = null, $model = null)
//    {
//
//
//        $string = preg_replace('#\[\[modelId\]\]#', $this->model->id, $string);
//        if ($model) $string = preg_replace('#\[\[selfId\]\]#', $model->id, $string);
//
//        if ($languageId) $string = preg_replace('#\[\[languageId\]\]#', $languageId, $string);
//
//        return $string;
//    }
//
//
//    public function extendValidator()
//    {
//
//        //Checks if the input can be json decoded
//        \Validator::extend('isJson', function ($key, $value, $options = null) {
//            //If it is a, return true
//            if ($prices = json_decode($value)) return true;
//            return false;
//        });
//        //Check if the price in the json is set and greater than 0
//        \Validator::extend('priceNotNull', function ($key, $value, $options = null) {
//            if (!$prices = json_decode($value)) return false;
//
//            foreach ($prices as $price) {
//                //If price_inc is not set
//                if (!isset($price->price_inc)) return false;
//                //If price is empty
//                if (empty($price->price_inc)) return false;
//                //If price is 0 or smaller
//                if ($price->price_inc <= 0) return false;
//            }
//            return true;
//        });
//        //Check if the minimum amount in the json is set and greater than 0
//        \Validator::extend('minimumNotNull', function ($key, $value, $options = null) {
//            if (!$prices = json_decode($value)) return false;
//
//            foreach ($prices as $price) {
//                //If price_inc is not set
//                if (!isset($price->min_amount)) return false;
//                //If price is empty
//                if (empty($price->min_amount)) return false;
//                //If price is 0 or smaller
//                if ($price->min_amount <= 0) return false;
//            }
//            return true;
//        });
//        //Check if the price in the Json is a number
//        \Validator::extend('priceAsNumber', function ($key, $value, $options = null) {
//            if (!$prices = json_decode($value)) return false;
//            foreach ($prices as $price) {
//                if (!is_numeric($price->price_inc)) return false;
//            }
//            return true;
//        });
//        //Check if the minimum amount in the Json is a number
//        \Validator::extend('minimumAsNumber', function ($key, $value, $options = null) {
//            if (!$prices = json_decode($value)) return false;
//            foreach ($prices as $price) {
//                if (!is_numeric($price->min_amount)) return false;
//            }
//            return true;
//        });
//        //Check if the minimum amount in the Json is not repeated
//        \Validator::extend('minimumRepeat', function ($key, $value, $options = null) {
//            if (!$prices = json_decode($value)) return false;
//            $min_amounts = [];
//            foreach ($prices as $price) {
//                if (in_array($price->min_amount, $min_amounts)) return false;
//                $min_amounts[] = $price->min_amount;
//            }
//            return true;
//        });
//        //Check if the given field
//        \Validator::extend('uniqueAttribute', function ($key, $value, $options = null) {
//            $eavService = new EavService();
//            //$options[0] = model_type
//            //$options[1] = attribute_type
//            //$options[2] = exclude_id
//            //$options[2] = exclude_field
//            $values = $eavService->getAllValuesForModelAndType($options[0], $options[1], $options[2], $options[3]);
//            //Check if the value  exist, if so return false
//            if (in_array($value, $values)) return false;
//
//            return true;
//
//        });
//
//
//        //Check if the value is not when an other field has a certain value
//        \Validator::extend('isNotIf', function ($key, $value, $options) {
//            //options[0] value that the key can't be
//            //options[1] the key for the if check
//            //options[2] the value for the if check
//            if (!\Input::has($options[1])) return true;
//
//            if (\Input::get($options[1]) != $options[2]) return true;
//            if (\Input::get($key) == $options[0]) return false;
//            return true;
//        });
//
//        /**
//         * Use extendImplicit when the validation also should work when the value is empty
//         * Check if the model is new
//         * If so, check if it is empty
//         */
//        \Validator::extendImplicit('required_if_new', function ($key, $value, $options) {
//
//            //Check of the modelId is not null. If true, return true
//            if ($options[0] !== null) return true;
//
//            //New Item
//
//            //Check if the value is not empty. return true
//            if (!empty($value)) return true;
//
//            //New model, and empty value, return false
//            return false;
//
//        });
//    }
//
//    public function generateKey($key)
//    {
//        if (is_array($key)) $key = implode('_', $key);
//
//        if ($this->keyAsArray) $key = $this->keyAsArray . '_' . $key . '[' . $this->keyArrayKey . ']';
//
//        return $key;
//    }
//
//    ///Getters
//    public function getKms()
//    {
//        return $this->kms;
//    }
//
//    /**
//     * Returns an array containing SectionTabInterfaces representing Tabs for sections
//     *
//     * @return SectionTabInterface[]|array
//     */
//    public function getTabs()
//    {
//        if(!$this->sectionTabDirector->getTabsCollection()) return [];
//        return $this->sectionTabDirector->getTabsCollection()->getTabs();
//    }
//
//    /**
//     * Adds attributes to their appropriate tabs.
//     *
//     * @return void
//     */
//    protected function addAttributesToTabs()
//    {
//        $tabsCollection = $this->getSectionTabDirector()->getTabsCollection();
//
//        $tabs = $tabsCollection->getTabs();
//        foreach($tabs as $tab) {
//            if($tab->getGroup() == SectionTabGroups::General) {
//                $this->sectionTabItems->each(function($sectionTabItem, $key) use($tab) {
//                    /** @var AbstractSectionTabItem $sectionTabItem */
//                    if($sectionTabItem->getGroup() == SectionTabGroups::General) $tab->addItem($sectionTabItem->getAttribute());
//                });
//            }
//            elseif ($tab->getGroup() == SectionTabGroups::Languages)
//            {
//                $this->sectionTabItems->each(function($sectionTabItem, $key) use($tab) {
//                    /** @var AbstractSectionTabItem $sectionTabItem */
//
//                    if($sectionTabItem->getGroup() != SectionTabGroups::Languages) return; //Item does not belong to a language section tab. Most likely to the general tab. Skip it.
//                    $attribute = $sectionTabItem->getAttribute();
//
//                    if(!$attribute->hasAssociatedLanguage()) {
//                        return; //attribute does not have a translation. Skip it
//                    }
//
//                    if(strtolower($attribute->getAssociatedLanguage()->iso_2) != $tab->getName()) return; //Attribute does belong to another language tab, not this one. Skip it.
//
//                    $tab->addItem($attribute);
//                });
//            }
//        }
//    }
//
//    /**
//     * Returns the sectiontab director which manages the creation of tabs via a builder
//     *
//     * @return AbstractSectionTabsDirector
//     */
//    public function getSectionTabDirector(): AbstractSectionTabsDirector
//    {
//        return $this->sectionTabDirector;
//    }
//
//
//}