QR_code_generator/app/Support/HasObjectsTrait.php

91 lines
3.5 KiB
PHP

<?php
namespace App\Support;
use App\Models\Objects\NirObject;
use App\Models\Objects\ObjectType;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
trait HasObjectsTrait {
public function objects(): MorphToMany {
return $this->morphToMany(NirObject::class, 'objectable')->withPivot(['ord', 'group'])->orderByPivot('ord')->withTimestamps();
}
public function objectsByGroup($group = null): MorphToMany {
return $this->objects()->wherePivot('group', '=', $group ?? 'default');
}
public function getObjectAttribute() {
return $this->objects()->first();
}
public function getObject($typeName): ?Model {
return ($type = ObjectType::byName($typeName)->first()) ? $this->objects()->firstOrCreate(['type_id' => $type->id]) : null;
}
public function createObject($typeName, $ord = null, $group = null): ?Model {
if (($type = ObjectType::byName($typeName)->first()) && ($object = NirObject::create(['type_id' => $type->id]))) {
$this->attachObject($object, $ord, $group);
return $object;
}
return null;
}
public function attachObject(NirObject $object, $ord = null, $group = null) {
$ord = ($ord === null) ? $this->getMaxOrd($group) : $ord;
$this->moveFollowingObjects($ord, $group);
$this->objects()->attach($object->id, ['ord' => $ord ?? 0, 'group' => $group ?? 'default']);
}
public function moveFollowingObjects($ord, $group = null) {
$this->objectsByGroup($group)->wherePivot('ord', '>=', $ord)->get()->each(function($object) {
$this->objects()->updateExistingPivot($object, ['ord' => $object->pivot->ord + 1]);
});
}
public function getMaxOrd($group = null): int {
$res = $this->objectsByGroup($group)->max('ord');
return ($res !== null) ? ($res + 1) : 0;
}
public function moveObject(NirObject $object, $ord, $group = null) {
$currentGroup = $object->currentGroup($this);
$group = $group ?? $currentGroup;
$currentOrd = $object->currentOrd($this);
if (($group === $currentGroup) && ($ord > $currentOrd)) {
$this->objectsByGroup($group)->wherePivot('ord', '>', $currentOrd)->wherePivot('ord', '<=', $ord)->each(function($object) {
$this->objects()->updateExistingPivot($object, ['ord' => $object->pivot->ord - 1]);
});
} else $this->moveFollowingObjects($ord, $group);
$this->objects()->updateExistingPivot($object, ['ord' => $ord, 'group' => $group ?? 'default']);
$this->trimIndexes([$group, $currentGroup]);
}
public function trimIndexes($groups) {
collect(is_array($groups) ? $groups : [$groups])->unique()->each(function($group) {
$this->objectsByGroup($group)->each(function($object, $index) {
if ($object->pivot->ord !== $index) $this->objects()->updateExistingPivot($object, ['ord' => $index]);
});
});
}
public function getValue($fieldName) {
return $this->object ? $this->object->getValue($fieldName) : null;
}
public function setValue($fieldName, $value) {
return $this->object ? $this->object->setValue($fieldName, $value) : null;
}
public function setValues(array $values) {
return $this->object ? $this->object->setValues($values) : null;
}
public function addValue($fieldName, $value) {
return $this->object ? $this->object->addValue($fieldName, $value) : null;
}
}