File: D:/HostingSpaces/SBogers10/reiskick.komma.nl/vendor/komma/kms/src/Core/CanSaveSlugsTrait.php
<?php declare(strict_types=1);
namespace Komma\KMS\Core;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Komma\KMS\Sites\HasSiteInterface;
use Komma\KMS\Sites\HasSitesInterface;
trait CanSaveSlugsTrait
{
/**
* Generates a unique slug for the model, and saves it at the model.
*
* @param Model $model
* @return Model
*/
protected function saveSlugForModel(Model $model): Model {
if(!is_a($model,HasSlugInterface::class)) return $model;
/** @var HasSlugInterface $model */
$suggestedSlug = $model->suggestSlug();
$collection = $this->retrieveCollectionForCreatingSlug($model);
while($collection->where('slug', '=', $suggestedSlug)->count() !== 0) {
$suggestedSlug = create_unique_slug($collection, $suggestedSlug);
}
$model->slug = $suggestedSlug;
$model->save();
return $model;
}
/**
* @param Model $model
* @return Builder[]|\Illuminate\Database\Eloquent\Collection
*/
private function retrieveCollectionForCreatingSlug(Model $model)
{
if(config('app.multipleSites') === false) {
if(is_a($model, AbstractTranslationModel::class) === false) {
return $model->where('id', '!=', $model->id)->get();
} else {
/** @var $model AbstractTranslationModel */
return $model->where('id', '!=', $model->id)->whereHas('language', function(Builder $query) use($model) {
$query->where('id', '=', $model->language->id);
})->get();
}
} else {
if(is_a($model, AbstractTranslationModel::class) === false) {
if(is_a($model, HasSiteInterface::class)) {
return $this->modelsHavingSameSiteAsGivenModel($model)->get();
} else if(is_a($model, HasSitesInterface::class)) {
return $this->modelsHavingSameSitesAsGivenModel($model)->get();
}
} else {
return $this->translationModelsHavingTheSameLanguageAndSite($model)->get();
}
}
throw new \InvalidArgumentException('The given Model ('.get_class($model).') does not support slug saving.');
}
/**
* @param HasSiteInterface $model
* @return Builder
*/
private function modelsHavingSameSiteAsGivenModel(HasSiteInterface $model)
{
$site = $model->site()->first(['id']);
return $collectionQuery = $model::whereHas('site', function(BelongsTo $query) use($site) {
$query->where('id', '=', $site->id);
})->where('id', '!=', $model->id);
}
/**
* @param HasSitesInterface $model
* @return Builder
*/
private function modelsHavingSameSitesAsGivenModel(HasSitesInterface $model)
{
$sites = $model->sites()->get(['id']);
$siteIds = $sites->pluck('id')->toArray();
return $collectionQuery = $model::whereHas('sites', function(BelongsTo $query) use($siteIds) {
$query->whereIn('id', $siteIds);
})->where('id', '!=', $model->id);
}
/**
* Returns a query builder that yields the translation models of the same class as the given instance.
* They will belong to the same site(s) as the given instance's translatable.
* They will also have the same language as the given instance.
*
* @param AbstractTranslationModel $model
* @return Builder|\Illuminate\Database\Eloquent\Collection|AbstractTranslationModel
*/
private function translationModelsHavingTheSameLanguageAndSite(AbstractTranslationModel $model) {
$queryBuilder = $model;
//Only get results excluding the current model
$queryBuilder = $queryBuilder->where('id', '!=', $model->id);
//Only get translations that have the same language as the given one.
$queryBuilder = $queryBuilder->whereHas('language', function(Builder $query) use($model) {
$query->where('id', '=', $model->language->id);
});
$translatable = $model->translatable()->first(); //Gets the abstractTranslatable model (page for example) for the given translation.
if(is_a($translatable, HasSiteInterface::class)) {
/** @var AbstractTranslatableModel|HasSiteInterface $translatable */
$translatable = $translatable->load('site');
if($translatable->site) { //We can only take the site into account if there is one
$queryBuilder = $queryBuilder->whereHas('translatable', function (Builder $query) use ($translatable) {
$query->whereHas('site', function (Builder $query) use ($translatable) {
$query->where('id', '=', $translatable->site->id);
});
});
}
} else if(is_a($model->translatable()->getRelated(), HasSitesInterface::class)) {
//Get all AbstractTranslationModels (e.g PageTranslations) that have a translatable (e.g Page) that has a same site as the AbstractTranslationModels (e.g PageTranslation)
/** @var AbstractTranslatableModel|HasSitesInterface $translatable */
$translatable = $translatable->load('sites');
if($translatable->sites->count() > 0) { //We can only take sites into account when there are any
$queryBuilder = $queryBuilder->whereHas('translatable', function (Builder $query) use ($translatable) {
$query->whereHas('sites', function (Builder $query) use ($translatable) {
$query->whereIn('sites.id', $translatable->sites->pluck('id')->toArray());
});
});
}
}
return $queryBuilder;
}
}