File: D:/HostingSpaces/Lacom/lacom.nl/app/KommaApp/Kms/Core/Sections/SectionService.php
<?php
namespace App\KommaApp\Kms\Core\Sections ;
use App\Helpers\KommaHelpers;
use App\KommaApp\Documents\Kms\DocumentableInterface;
use App\KommaApp\Documents\Kms\DocumentServiceInterface;
use App\KommaApp\Documents\Models\Document;
use App\KommaApp\Images\ImageService;
use App\KommaApp\Kms\Core\AbstractTranslatableModel;
use App\KommaApp\Kms\Core\AbstractTranslationModel;
use App\KommaApp\Kms\Core\Attributes\Attribute;
use App\KommaApp\Kms\Core\Attributes\Documents;
use App\KommaApp\Kms\Core\Attributes\Models\SelectOptionInterface;
use App\KommaApp\Kms\Core\Attributes\Models\SelectOption;
use App\KommaApp\Kms\Core\HasImagesInterface;
use App\KommaApp\Kms\Core\HasRoutesInterface;
use App\KommaApp\Kms\Core\Kms;
use App\KommaApp\Kms\Core\KmsInterface;
use App\KommaApp\Kms\Core\ModelBelongsToManySitesInterface;
use App\KommaApp\Kms\Core\ModelBelongsToSiteInterface;
use App\KommaApp\Kms\Core\NestedSets\Nodes\EloquentNodeInterface;
use App\KommaApp\Kms\Core\Tree\Tree;
use App\KommaApp\Kms\Core\Tree\TreeNode;
use App\KommaApp\Kms\SidebarListItem;
use App\KommaApp\Languages\Models\Language;
use App\KommaApp\Pages\Models\PageTranslation;
use App\KommaApp\Vacancies\Models\Vacancy;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Facades\App;
use InvalidArgumentException;
/**
* @see PageRepository Based of the deprecated PageRepository and KmsRepository
*
* Class SectionService
* @package App\KommaApp\Shop\
*/
class SectionService implements SectionServiceInterface
{
/** @var bool $sortable */
protected $sortable = true;
/**
* @var Tree $tree
*/
private $tree;
/**
* @var ImageService $imageService
*/
private $imageService;
/**
* @var string $forModelName
*/
protected $forModelName;
/** @var AbstractTranslatableModel $forModel */
protected $forModel;
/**
* @var AbstractTranslationModel $forTranslationModel
*/
protected $forTranslationModel;
/**
* @var string $forTranslationModelName
*/
protected $forTranslationModelName;
/**
* @var DocumentServiceInterface
*/
protected $documentService;
/**
* @var string $orderBy
*/
protected $orderBy;
/**
* @var bool $orderReverse
*/
protected $orderReverse = false;
/** @var Kms $kms */
private $kms;
function __construct()
{
if (!$this->forModelName) throw new \RuntimeException("Please set the forModelName variable in the '" . get_class($this) . "' class");
if (is_a((new $this->forModelName), AbstractTranslatableModel::class)) {
$translationModelInterface = (new $this->forModelName)->translations()->getRelated();
if (!is_a($translationModelInterface, AbstractTranslationModel::class)) throw new \RuntimeException("The method 'translations' method from the class '" . $this->forModelName . "' does not return a relation resolving to an instance of '" . AbstractTranslationModel::class . "'");
$this->forTranslationModel = $translationModelInterface;
$this->forTranslationModelName = get_class($translationModelInterface);
}
$this->kms = App::make(KmsInterface::class);
$this->tree = App::make("Tree");
$this->imageService = App::make(ImageService::class);
$this->imageService->setImageableType($this->forModelName);
$this->documentService = App::make(DocumentServiceInterface::class);
}
/**
* This method will get a model based on the id.
* When the id is NULL or the model does not exist, we will generate a new.
*
* @see KmsSection::loadModel()
* @param int $modelId
* @return Model
*/
public function getModel($modelId = null): Model
{
if ($modelId == null || !$model = $this->forModelName::find($modelId)) {
return $this->newModel();
}
$model = $this->setThumbnail($model);
return $model;
}
/**
* Gets the name of the model the service does its work for.
* Prevent usage of this method.
*
* @return string
*/
public function getForModelName(): string
{
return $this->forModelName;
}
/**
* Set the thumbnail for the model.
*
* @param Model $model
* @param string|null $thumbnailString an image url
* @return Model
*/
public function setThumbnail(Model $model, string $thumbnailString = null)
{
// Set thumbnail to first uploaded image
if (isset($model->images) && count($model->images) > 0 && !empty($model->images)) {
//Set thumbnail
$model->thumbnail = ['image_url' => $model->images[0]->thumb_image_url];
} // Set thumbnail to given placeholder image
elseif (isset($thumbnailString)) {
$model->thumbnail = ['image_url' => $thumbnailString];
} // Set thumbnail to first letter of model name
elseif ($model->title && $model->title != '') {
$model->thumbnail = ['string' => strtoupper(substr($model->title, 0, 1))];
} // Set thumbnail to id of the model
else {
$model->thumbnail = ['string' => $model->id];
}
return $model;
}
/**
* @param AbstractTranslatableModel $model
* @param string $thumbnailString
* @return mixed
*/
public function setTreeThumbnail(AbstractTranslatableModel $model, string $thumbnailString = null)
{
// Set thumbnail to first uploaded image
if (isset($model->images) && count($model->images) > 0) {
//Set thumbnail
$model->thumbnail = $model->images[0]->thumb_image_url;
} // Set thumbnail to given placeholder image
elseif (isset($thumbnailString)) $model->thumbnail = $thumbnailString;
return $model;
}
/**
* This method will create a new TranslatableModelInterface instance with its translations.
*
* @param null $siteId
* @return Model
*/
public function newModel($siteId = null): Model
{
if ($this->kms) {
//kms is only set for sections that are linked to a site.
if ($siteId == null) {
$siteId = $this->kms->getSiteId();
}
//Create a base TranslatableModelInterface if it doesn't exist already
$this->makeRootModelIfNotExists($siteId);
}
//Create a new TranslatableModelInterface
$model = new $this->forModelName;
$site = $this->kms->getSite();
if ($this->kms && isset($site)) {
//Check if Model is translatable
if (is_a((new $this->forModelName), AbstractTranslatableModel::class)) {
//Create translations per language
$languages = $this->kms->getSiteLanguages();
foreach ($languages as $language) {
//new translation per language
$translation = new $this->forTranslationModel();
//set the language
$translation->fill(['language_id', $language->id]);
$translation->translatable()->associate($model);
//couple model and translation together
}
}
if (method_exists($model, 'site')) $model->site()->associate($site);
}
//Set the thumbnail
$model = $this->setThumbnail($model);
return $model;
}
/**
* Gets the model query
*
* @return \Illuminate\Database\Query\Builder
*/
public function models()
{
return $this->forModelName::query();
}
/**
* Gets the model query
*
* @return \Illuminate\Database\Query\Builder
*/
public function translationModels()
{
if(!$this->forTranslationModelName) return null;
return $this->forTranslationModelName::query();
}
/**
* Get model tree
*
* @return Tree
*/
public function getModelTree($siteId = null):Tree
{
//Create a base page if it doesnt exist already
$this->makeRootModelIfNotExists($siteId);
//Create the tree based on the site id
$tree = $this->getModelsAsTree($siteId);
return $tree;
}
/**
* Returns all models for the sidebar menu in the backend
*
* @return array
*/
public function getModelsForSideBar():array
{
if(isset($this->orderBy)){
if($this->orderReverse) $models = $this->forModelName::orderBy($this->orderBy, 'desc');
else $models = $this->forModelName::orderBy($this->orderBy);
}
else $models = $this->forModelName::orderBy('id');
// If Site isset then we add it to the query, so
$site = $this->kms->getSite();
if($site && $siteId = $this->kms->getSite()->id) {
$models = $models->where('site_id', $siteId);
}
// Get the models
$models = $models->get();
// Preload translation to prevent individual queries
if(is_a(new $this->forModelName, AbstractTranslatableModel::class)){
$models = $models->load('translation');
}
// Preload images to prevent individual queries
if(is_a(new $this->forModelName, HasImagesInterface::class)){
$models = $models->load('images');
}
$sidebarList = [];
foreach ($models as $model) {
$sidebarListItem = new SidebarListItem();
$this->setThumbnail($model);
$this->generateThumbnail($model);
//Set the values for the sidebar
$sidebarListItem->setId($model->id);
$sidebarListItem->setStatus($model->active);
$title = KommaHelpers::str_limit_full_word($model->title, 75);
$sidebarListItem->setName($title);
$sidebarListItem->setThumbnail($model->thumbnail);
$sidebarList[] = $sidebarListItem;
}
return $sidebarList;
}
/**
* This method will build an model tree.
* Based on the site and language-id
* Used by the Controllers get and set-structure method
*
* @param null $langId
* @return Tree
*/
public function getModelsAsTree($langId = null):Tree
{
//If LangId is null set current LanguageId
if ($langId == null) $langId = $this->kms->getSiteDefaultLanguage();
$translatableModelInterfaces = $this->forModelName::with('translation')
->orderBy('lft', 'asc');
// If Site isset then we add it to the query, so
if($this->kms->getSite() && $siteId = $this->kms->getSite()->id) $translatableModelInterfaces = $translatableModelInterfaces->where('site_id', $siteId);
if(is_a(new $this->forModelName, HasImagesInterface::class)) $translatableModelInterfaces = $translatableModelInterfaces->with('images');
$translatableModelInterfaces = $translatableModelInterfaces->get();
foreach ($translatableModelInterfaces as &$translatableModelInterface){
if(!isset($translatableModelInterface->images) || is_bool($translatableModelInterface->images) || $translatableModelInterface->images->count() == 0) continue;
// $translatableModelInterface->images = $this->imageService->getImages($translatableModelInterface->id);
$translatableModelInterface = $this->setTreeThumbnail($translatableModelInterface);
}
$tree = new Tree();
$tree = $tree->make($translatableModelInterfaces->all());
return $tree;
}
/**
* This method will load entities between
* the given left and right boundaries
* For the given site- and lang-id
*
* @param $lft
* @param $rgt
* @param $siteId
* @param $langId
* @return mixed
*/
public function getModelsBetween($lft, $rgt, $siteId = null, $langId = null)
{
//If siteId is null set currentSiteId
if ($siteId == null) $siteId = $this->kms->getSiteId();
//If LangId is null set current LanguageId
if ($langId == null) $langId = $this->kms->getSiteDefaultLanguage();
$table = (new $this->forModelName)->getTable();
$shortClassName = $this->kms->getShortNameFromClass($this->forModelName, true);
//Create the db query
$records = \DB::table($table)
->select($table.'.lft', $table.'.rgt', $this->forTranslationModel->getTable().'.name', $table.'.id as id', $this->forTranslationModel->getTable().'.id as '.$this->forTranslationModel->getTable().'_id', $this->forTranslationModel->getTable().'.description', $this->forTranslationModel->getTable().'.slug')
->leftJoin($this->forTranslationModel->getTable(), $table.'.id', '=', $this->forTranslationModel->getTable().'.'.$shortClassName.'_id')
->whereBetween($table.'.lft', array($lft + 1, $rgt - 1))
->where($table.'.site_id', '=', $siteId)
->where(function ($query) use ($langId) {
$query->whereNull($this->forTranslationModel->getTable().'.language_id')
->orWhere($this->forTranslationModel->getTable().'.language_id', '=', $langId);
})
->orderBy($table.'.lft', 'asc')
->get();
return $records;
}
/**
* This method will save an model
*
* @param Model $model or null
* @param Collection $sectionTabItems These must be filled with data. This is something you need to do yourself.
*
* @return mixed
*/
public function saveModel(Model $model = null, Collection $sectionTabItems): Model
{
//We want to have an empty model if we don't have a Model
if ($model == null) {
$model = new $this->forModelName;
$model->site_id = $this->kms->getSiteId();
$model->active = 1;
}
$shortModelClassName = $this->kms->getShortNameFromClass($model, true);
if($model->exists == false) $model->save();
$editedModel = false;
$sectionTabItems->each(
function($sectionTabItem, $key) use($model, &$editedModel, $shortModelClassName) {
/** @var SectionTabItem $sectionTabItem */
$attribute = $sectionTabItem->getAttribute();
// if(is_a($attribute, Dynamic::class)) \Log::info("KmsRepository::69. Dynamic attribute with key '".$attribute->getKey()."' Gets it's value from '".$attribute->getsValueFrom()."'. Value: '".$attribute->getValue()."'"); //debugging helper
// if(is_a($attribute, Images::class)) dd($attribute); //debugging helper
// if(is_a($attribute, Select::class)) dd($attribute); //debugging helper
$reference = $attribute->getsValueFromReference();
switch ($attribute->getsValueFrom())
{
case Attribute::ValueFromModel:
$value = $attribute->getValue();
$model->$reference = $value;
$editedModel = true;
break;
case Attribute::ValueFromTranslationModel:
$value = $attribute->getValue();
/** @var Language $language */
$language = $attribute->getAssociatedLanguage();
$translation = $model->translations()->where([
[$shortModelClassName.'_id', '=', $model->id],
['language_id', '=', $language->id],
])->first();
if(!$translation) $translation = $this->getOrCreateTranslationModelForModel($model, $language);
$translation->$reference = $value;
$translation->save();
break;
case Attribute::ValueFromModelHasManyRelation:
$data = explode('|', $reference);
$valueRelationMethod = $data[0];
if(method_exists($model, $valueRelationMethod) === false) throw new \RuntimeException("The value reference method name ('".$valueRelationMethod."') does not exist on the model with class name: ".(get_class($model)).". Please check the attribute configuration in the section.");
if(count($data) != 2) throw new \InvalidArgumentException("The value reference from attribute '".get_class($sectionTabItem->getAttribute())."' must be a pipe seperated relation|relationAttribute pair. But now it contains more pipes and that is not allowed.");
$value = $attribute->getValue();
$values = explode(',', $value);
if($value != "")
$model->$valueRelationMethod()->sync($values);
else
$model->$valueRelationMethod()->detach();
break;
case Attribute::ValueFromDocuments:
if(!is_a($attribute, Documents::class)) throw new \RuntimeException('The attribute with value reference "'.$reference.'" in section that uses the "'.get_class($this).'" service must be a "'.Documents::class.'" but was a "'.get_class($attribute).'"');
$this->documentService->processUploadedDocumentsForModel($model, $attribute);
break;
}
}
);
if($editedModel) $model->save();
return $model;
}
/**
* Uses a model that must have a translations method, creates a new translation for it if it does not exists and associates it with the language given.
* Returns the translation
*
* @param AbstractTranslatableModel $model
* @param Language $language
* @return Model The translation
*/
protected function getOrCreateTranslationModelForModel(AbstractTranslatableModel $model, Language $language): Model{
$shortModelClassName = $this->kms->getShortNameFromClass($model, true);
$shortModelClassName = str_replace("model", "", $shortModelClassName);
$translation = $this->forTranslationModel::where([
[$shortModelClassName.'_id','=',$model->id],
['language_id','=',$language->id],
])->first();
if($translation) return $translation;
//Translation does not exist. Create it and associate a language with it and save it in the model.
/** @var PageTranslation $translation */
$translation = new $this->forTranslationModel;
$translation->language()->associate($language);
$model->translations()->save($translation);
return $translation;
}
/**
* Returns true when the section has a sortable items list to the left side of the screen or false if not.
*
* @return boolean
*/
public function getSortable()
{
return $this->sortable;
}
/**
* @param int|null $siteId
* @param int|null $languageId TODO: Jules. Check if we still need this
* @param int|null $excludeId TODO: Jules. Check if we still need this
* @return SelectOptionInterface[]
*/
public function getOptionsForSelect($languageId = null, int $excludeId = null): array
{
$entities = [];
// Check if the getModelsAsTree method exist
// if ( ! method_exists($this, 'getModelsAsTree')) {
if ( $this->sortable == false) {
/** @var $sidebarListItems SidebarListItem[] */
$sidebarListItems = $this->getModelsForSideBar();
$entities[] = (new SelectOption())
->setContent('/')
->setHtmlContent('/')
->setValue(0);
if ($excludeId == -1) $entities = [];
foreach ($sidebarListItems as $sidebarListItem) {
$model = $this->forModelName::find($sidebarListItem->getId());
if(!$model) continue;
$entities[] = (new SelectOption())
->setValue($model->id)
->setContent($sidebarListItem->getName());
}
return $entities;
}
// Get all models as tree
/** @var Tree $tree */
$tree = $this->getModelsAsTree($languageId);
// Exclude the current active item)
if ($excludeId) $tree->removeFromIndex((int)$excludeId);
// QnD !!! Indexing trees per language (multiple queries)
$treePerLanguage = [];
$siteLanguages = $this->kms->getSiteLanguages();
foreach ($siteLanguages as $language) {
$treePerLanguage[$language->id] = $this->getModelsAsTree($language->id);
}
// End QnD !!!
// The tree index contains all nodes keyed by id
/** @var TreeNode $record */
foreach ($tree->getIndex() as $record) {
$nodeName = null;
$sidebarListItem = $record->node;
$entity = (new SelectOption())->setValue($sidebarListItem->id);
// For each site language
foreach ($siteLanguages as $language) {
// Route with lanuage: Get the primary route for the current language
/** @var Tree $currentTree */
$currentTree = $treePerLanguage[$language->id];
//If $nodeName exist, continue
if ($nodeName) continue;
//No nodeName, get one
/** @var Tree[] $treePerLanguage*/
// $nodeName = $treePerLanguage[$language->id]->getEntityById($entity['value'])->getTranslationField('name', $language);
$nodeName = $treePerLanguage[$language->id]->getEntityById($entity->getValue())->getTranslationField('name', $language);
}
$entity->setContent((empty($nodeName) ? '/' : $nodeName));
//Set the spaces for an indent (three)
$indent = str_repeat(' ', $record->getDepth());
//Set the content for the dropdown list
$entity->setHtmlContent($indent . (empty($nodeName) ? '/' : ucfirst($nodeName) ));
$entities[] = $entity;
}
return $entities;
}
/**
* Fills attributes with data from a model in this way:
*
* 1. First it looks if it needs to get the value from a translationModel.
* If so, gets it, fills the attribute and fills the next attribute if any
* 2. Then it looks if it needs to get the value from it's model.
* If so, gets it, fills the attribute and fills the next attribute if any
* 4. Then it looks if it needs to get the value from the images associated with it.
* If so, gets it, fills the attribute and fills the next attribute if any
* Please notice that if cases 1, 2 and 3 where true the value you may have set with setValue is overwritten.
*
* @param Collection $sectionTabItems A collection containing implementations AbstractSectionTabItem's
* @param Model $model
* @return Collection
*/
public function fillAttributesWithData(Collection $sectionTabItems, Model $model)
{
//Validate that each Collection item is an instance of AbstractSectionTabItem
$sectionTabItems->every(function($item, $key) {
if(!is_a($item, AbstractSectionTabItem::class)) throw new \InvalidArgumentException("The attributes passed must be a Collection of AbstractSectionTabItem instances but was not");
});
$filledAttributes = new Collection();
$sectionTabItems->each(
function ($sectionTabItem, $key) use ($model, $filledAttributes) {
/** @var $sectionTabItem SectionTabItem */
if(!is_a($sectionTabItem->getAttribute(), Attribute::class)) throw new \InvalidArgumentException("One of the attributes in a AbstractSectionTabItem instance is not but must be an child instance of Attribute.");
// if(is_a($sectionTabItem->getAttribute(), OnOff::class)) dd($sectionTabItem->getAttribute());
// if(is_a($sectionTabItem->getAttribute(), Select::class)) dd($sectionTabItem->getAttribute()->getValue());
$value = null;
$valueReference = $sectionTabItem->getAttribute()->getsValueFromReference();
switch($sectionTabItem->getAttribute()->getsValueFrom())
{
//Case 1. Check if the translation of the model has a value.
case Attribute::ValueFromTranslationModel:
if($sectionTabItem->getAttribute()->hasAssociatedLanguage())
{
if(!is_a($model, AbstractTranslatableModel::class)) throw new \RuntimeException("The model '".get_class($model)."' is not a model that is translatable (It does not implement the TranslatableModelInterface). Please check the section configuration (Attribute with reference '".$sectionTabItem->getAttribute()->getsValueFromReference()."') or make the model implement the interface.");
$translation = $model->translations()->where('language_id', $sectionTabItem->getAttribute()->getAssociatedLanguage()->id)->first();
// \Log::info("Filling attribute of class: '".get_class($sectionTabItem->getAttribute())."' with a value that comes from a translation.");
if(!$translation) {
// \Log::warning("Skipping filling attribute of class '".get_class($sectionTabItem->getAttribute())."' because it did not have a translation");
return;
} //Skip filling the value if the model did not have a translation
if(method_exists($model, "translations") === false) throw new \InvalidArgumentException("The model given did not have a translation while its attribute states that it references a value of that model.");
if(array_key_exists($valueReference, $translation->attributesToArray()) === false) throw new \RuntimeException("The translation value reference field name ('".$valueReference."') does not exist on the translations from the model with class name: ".(get_class($model)).". Please check the attribute configuration in the section.");
// \Log::info("Filled attribute with key '".$sectionTabItem->getAttribute()->getKey()."' with a value that comes from the '".$valueReference."' field of the translation model. Value: ".$translation->$valueReference);
$value = $translation->$valueReference;
}
break;
//Case 2 check if the model directly has a value
case Attribute::ValueFromModel:
$keys = array_keys($model->getAttributes());
if(!array_key_exists($valueReference, $keys) === false) throw new \RuntimeException("The value reference field name ('".$valueReference."') does not exist on the model with class name: ".(get_class($model)).". Please check the attribute configuration in the section. All available field names: ".implode(', ', $keys));
$value = $model->$valueReference;
break;
//Case 3
case Attribute::ValueFromModelHasManyRelation:
if(!method_exists($model, $valueReference) === false) throw new \RuntimeException("The value reference method name ('".$valueReference."') does not exist or is not a HasMany relation on the model with class name: ".(get_class($model)).". Please check the attribute configuration in the section.");
$data = explode('|', $valueReference);
if(count($data) != 2) throw new \InvalidArgumentException("The value reference from attribute '".get_class($sectionTabItem->getAttribute())."' must be a pipe seperated relation|relationAttribute pair. But now it contains more pipes and that is not allowed.");
$relationMethod = $data[0];
$relationFieldId = $data[1];
$collection = $model->$relationMethod()->get();
$valueToProcess = [];
$self = $this;
$collection->each(function($item, $key) use (&$valueToProcess, $relationFieldId, $sectionTabItem, $relationMethod, $self) {
if(strpos($item->$relationFieldId, ',') !== false) throw new \RuntimeException("The relation method '".$relationMethod."' returned a value with a , character in it which is not allowed. See Attribute configuration of attribute '".get_class($sectionTabItem->getAttribute())."' in section '".get_class($self)."'");
$valueToProcess[] = $item->$relationFieldId;
});
$value = implode(',', $valueToProcess);
break;
//Case 4 check if the model has images. If so set the image ids as the value of the attribute. Delimited with a pipe (|) symbol
case Attribute::ValueFromImages:
if(method_exists($model, $valueReference) === false) throw new InvalidArgumentException("The method '".$valueReference."' does not exist on the model with class name: ".(get_class($model)).". Please check the attribute configuration in the section");
if(is_a($model->$valueReference(), Relation::class) === false) throw new InvalidArgumentException("The method '".$valueReference."' must return a relation ('".Relation::class."') but did return: ".gettype($model->$valueReference().". Please check the attribute configuration in the section"));
$imageIds = $model->$valueReference()->pluck('id');
if($imageIds->count() > 0) $value = implode('|', $imageIds->toArray());
break;
case Attribute::ValueFromDocuments:
//Case 5 check if the model has documents.
if(!is_a($model, DocumentableInterface::class)) throw new InvalidArgumentException("The model '".get_class($model)."' must implement the interface '".DocumentableInterface::class."' but did not");
/** @var $model DocumentableInterface */
$value = json_encode($model->documents()->get());
break;
}
//Finally when we have a value we will set it on the attribute and then process the next one.
if($value !== null) {
$sectionTabItem->getAttribute()->setValue((string)$value);
}
$filledAttributes->push($sectionTabItem);
}
);
// dd($filledAttributes);
return $filledAttributes;
}
/**
* This method will remove an TranslatableModelInterface instance
*
* @param $model
* @throws \Exception
*/
public function destroyModel(Model $model)
{
//delete the images
$this->imageService->deleteModelImages($model);
if(is_a($model,AbstractTranslatableModel::class)) {
foreach ($model->translations()->get() as $translation) {
//Delete the route of the translation
if(is_a($model, HasRoutesInterface::class)){
$translation->routes()->delete();
}
//Delete the translation
$translation->delete();
}
}
$model->delete();
}
/**
* This method will create the root model if necessary.
* This TranslatableModelInterface database entry is used as a base for the lft and rgt.
*
* @param $siteId
* @return null
*/
protected function makeRootModelIfNotExists($siteId = null)
{
if(!is_a(new $this->forModelName, EloquentNodeInterface::class)) return null;
if($siteId == null) throw new InvalidArgumentException('The SectionService::makeRootModelIfNotExists method does need a siteId to function and you did not specify one. Perhaps you may need to override this method in the class "'.get_class($this).'" to suit your needs.');
if($this->forModelName::where(['lft' => 1, 'site_id' => $siteId])->first()) return null;
$newRoot = new $this->forModelName([
'active' => 1,
'site_id' => $siteId,
// 'lft' => 1,
// 'rgt' => 2,
'tree' => $siteId]);
$newRoot->makeRoot();
return $newRoot;
}
/**
*
* Generate the html of the thumbnail
*
* @param $model
*/
public function generateThumbnail(&$model){
//If there is no thumbnail return
if(!isset($model->thumbnail)){
if(isset($model->name)) $model->thumbnail = '<span>'.strtoupper(substr($model->name, 0, 1)).'</span>';
elseif(isset($model->translation) && isset($model->translation->name)) $model->thumbnail = '<span>'.strtoupper(substr($model->translation->name, 0, 1)).'</span>';
}
if (isset($model->thumbnail['image_url'])) $model->thumbnail = '<img src="' . $model->thumbnail['image_url'] . '""/>';
//If there is a string set as array, return only the string
elseif (isset($model->thumbnail['string'])) $model->thumbnail = '<span>'.$model->thumbnail['string'].'</span>';
elseif (is_array($model->thumbnail) && isset($model->thumbnail[0])) $model->thumbnail = '<span>'.$model->thumbnail[0].'</span>';
else $model->thumbnail = '<span>'.$model->id.'</span>';
}
/**
* Generate an unique slug name for routing resolved by the wildcard resolver
*
* @param String $tableName
* @param int $translationId
* @param string $name
* @param int $uniquifier
* @return string
*/
protected function createOrGetUniqueSlug(AbstractTranslationModel $translation, string $name, int $uniquifier = 0): string
{
if($uniquifier == 0) $slug = str_slug($name);
else $slug = str_slug($name) . '-' . $uniquifier;
// Get the model
$model = $translation->translatable()->first();
if(is_a($model, Vacancy::class)){
$results = $translation::where('slug', $slug)
->where('id', '!=', $translation->id)
->whereHas('translatable' ,function ($query) use ($model){
$query->where('site_id', $model->site_id);
})
->get();
}
elseif(is_a($model, ModelBelongsToSiteInterface::class)){
$results = $translation::where('slug', $slug)
->where('id', '!=', $translation->id)
->whereHas('translatable' ,function ($query){
$query->where('site_id', $this->kms->getSite()->id);
})
->get();
}
elseif(is_a($model, ModelBelongsToManySitesInterface::class)){
dd('maak dit');
}
else{
// Get the all translations
$results = $translation::where('slug', $slug)
->where('id', '!=', $translation->id)
->get();
}
if($results->count() == 0) return $slug;
else{
$slug = $this->createOrGetUniqueSlug($translation, $name, ($uniquifier + 1));
return $slug;
}
}
}