File: D:/HostingSpaces/pietvanmierlo/stempelbv.nl/app/Komma/Shop/Categories/Kms/CategoryService.php
<?php
namespace App\Komma\Shop\Categories\Kms;
use App\Helpers\KommaHelpers;
use App\Komma\Kms\Core\Attributes\Attribute;
use App\Komma\Kms\Core\Tree\NestedSets\Nodes\TreeModelInterface;
use App\Komma\Kms\Core\Sections\SectionService;
use App\Komma\Kms\Core\Sections\SectionTabItem;
use App\Komma\Kms\Core\Tree\TreeService;
use App\Komma\Globalization\Languages\Models\Language;
use App\Komma\Shop\Categories\Models\Category;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
class CategoryService extends SectionService implements CategoryServiceInterface
{
protected $sortable = true;
/** @var TreeService $treeService */
private $treeService;
function __construct()
{
$this->forModelName = Category::class;
$this->treeService = app(TreeService::class);
parent::__construct();
}
/**
* 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
{
/** @var TreeModelInterface|Model $model */
$sectionTabItems->each(function($sectionTabItem, $key) use($model) {
/** @var SectionTabItem $sectionTabItem */
$attribute = $sectionTabItem->getAttribute();
$value = $attribute->getValue();
$reference = $attribute->getsValueFromReference();
switch ($attribute->getsValueFrom())
{
case Attribute::ValueFromItself:
if($reference == 'parent_id') {
$this->doAfterSave(function($model) use($value) {
/** @var TreeModelInterface $model */
// Get parent_id of the input
$parentId = $value;
$parentPage = $model->find($parentId);
// Set default to false
$currentParentId = null;
// if true then get current parent_id
$currentParentId = $model->getParentId();
//Check if parent page is found, model isset and parent page id isn't the current parent id
if ($parentPage && $model && $parentPage->id !== $currentParentId) {
$model->makeLastChildOf($parentPage);
// dd('New parent page', $parentPage, 'Old parent page id: ', $currentParentId);
}
});
}
break;
case Attribute::ValueFromTranslationModel;
if($reference == 'name')
{
$this->doAfterSave(function($model) use ($attribute, $value) {
/** @var Language $language */
$language = $attribute->getAssociatedLanguage();
$translation = $this->getTranslationModelForModelByLanguage($model, $language);
if(!$translation) throw new \RuntimeException('Expected to get a category translation. Got none.');
$translation['slug'] = (str_slug($value));
$translation->translatable()->associate($model);
$translation->save();
});
}
break;
}
});
$model = $this->makeChildOfRootOrSave($model);
$model = parent::saveModel($model, $sectionTabItems); //First make sure we have a model and save the attributes in them from the SectionTabItem attributes
//Return the page
return $model;
}
/**
* Fills non-product specific attributes. Product specific attributes are processed in the parent
*
*
* @param Collection $sectionTabItems A collection containing implementations AbstractSectionTabItem's
* @param Model $model
* @return Collection
*/
public function fillAttributesWithData(Collection $sectionTabItems, Model $model)
{
$filledAttributesCollection = parent::fillAttributesWithData($sectionTabItems, $model);
$sectionTabItems->each(
function ($sectionTabItem, $key) use ($model, $filledAttributesCollection, &$quantityDiscountAttribute, &$quantityPriceAttribute) {
/** @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.");
$attribute = $sectionTabItem->getAttribute();
$valueReference = $sectionTabItem->getAttribute()->getsValueFromReference();
switch($sectionTabItem->getAttribute()->getsValueFrom()) {
case Attribute::ValueFromItself:
switch ($valueReference) {
case 'parent_id':
$parentId = 1;
if($model->exists) $parentId = $model->getParentId();
$attribute->setValue($parentId);
break;
}
break;
break;
}
}
);
return $filledAttributesCollection;
}
/**
* Make the category a child of the root category OR just save it if it already is a child of the root category
*
* @param $model
* @return TreeModelInterface
*/
private function makeChildOfRootOrSave(TreeModelInterface $model)
{
$rootModel = $this->forModelName::where('lft', '=', 1)->first();
if(!$rootModel) throw new \RuntimeException('No root model for '.$this->forModelName.'. Make sure it exists');
$model->makeLastChildOf($rootModel);
return $model;
}
/**
* Makes the AbstractTranslatableModel a child from the categories by id if it isn't a child yet
*
* @param CategorizableInterface $model
* @param string $categoryIds comma seperated like this 1,4,2,5
*/
public function makeChildOfCategoriesIfNotAlready(CategorizableInterface $model, string $categoryIds):void
{
if(!$model->id) return;
if($categoryIds !== "") {
$categoryIds = array_unique(explode(',', $categoryIds));
} else {
$categoryIds = [];
}
$categories = $this->forModelName::whereIn('id', $categoryIds)->get();
if(!$categories) return;
$modelShortClassName = KommaHelpers::getShortNameFromClass($model, true);
$relationName = str_plural($modelShortClassName);
if(!method_exists((new $this->forModelName), $relationName)) {
throw new \RuntimeException('The class "'.$this->forModelName.'" must have, but did not have a MorphToMany relation method called "'.$relationName.'". Without it we cannot make the "'.get_class($model).'" a child of "'.$this->forModelName.'"');
}
$model->categories()->sync($categoryIds);
}
/**
* Returns the category ids as a comma separated string for the CategorizableInterface implementation
*
* @param CategorizableInterface $model
* @return string Category ids, comma separated
*/
public function getCategoryIdsForModel(CategorizableInterface $model): ?string
{
if(!$model->id) return null;
$idsCollection = $model->categories()->get(['category_id'])->map(function(Category $category ) {
return $category->category_id;
});
$idString = implode(',', $idsCollection->toArray());
if($idString == "") return null;
return $idString;
}
}