diff --git a/src/PersistentData/PersistentDataManager.php b/src/PersistentData/PersistentDataManager.php index 22c9fee..60fec89 100644 --- a/src/PersistentData/PersistentDataManager.php +++ b/src/PersistentData/PersistentDataManager.php @@ -8,9 +8,12 @@ use SokoWeb\Interfaces\Database\IAuditLogger; use SokoWeb\Interfaces\Database\IResultSet; use SokoWeb\Interfaces\PersistentData\IPersistentDataManager; use SokoWeb\PersistentData\Model\Model; +use SokoWeb\PersistentData\Model\ModelWithSlug; class PersistentDataManager implements IPersistentDataManager { + const SLUG_MAX_LENGTH = 255; + private IConnection $dbConnection; private ?IAuditLogger $auditLogger; @@ -58,6 +61,14 @@ class PersistentDataManager implements IPersistentDataManager return $this->selectFromDb($select, $type, $useRelations, $withRelations); } + public function selectFromDbBySlug(string $slug, string $type, bool $useRelations = false, array $withRelations = []) + { + $select = new Select($this->dbConnection); + $select->where('slug', '=', $slug); + + return $this->selectFromDb($select, $type, $useRelations, $withRelations); + } + public function loadRelationsFromDb(Model $model, bool $recursive = false, array $withRelations = []): void { $relations = $model::getRelations(); @@ -103,12 +114,20 @@ class PersistentDataManager implements IPersistentDataManager } if (count($modified) > 0) { + if ($model instanceof ModelWithSlug && isset($modified['slug'])) { + $modified['slug'] = $this->generateUniqueSlug($model, $modified['slug']); + } + $modify->setId($id); $modify->setDiff($diff); $modify->fill($modified); $modify->save(); } } else { + if ($model instanceof ModelWithSlug) { + $modified['slug'] = $this->generateUniqueSlug($model, $modified['slug']); + } + $modify->fill($modified); $modify->save(); @@ -129,6 +148,29 @@ class PersistentDataManager implements IPersistentDataManager $model->resetSnapshot(); } + private function generateUniqueSlug(ModelWithSlug $model, string $notUniqueSlug): string + { + $numbered = 1; + + do { + if ($numbered > 1) { + $slug = substr($notUniqueSlug, 0, static::SLUG_MAX_LENGTH - (strlen((string)$numbered) + 1)); + $slug = $notUniqueSlug . '_' . (string)$numbered; + } else { + $slug = substr($notUniqueSlug, 0, static::SLUG_MAX_LENGTH); + } + + $select = new Select($this->dbConnection, $model::getTable()); + $select->where('slug', '=', $slug); + + $numbered++; + } while ($select->count() != 0); + + $model->setSlug($slug); + + return $slug; + } + private function createSelect(Select $select, string $type, bool $useRelations = false, array $withRelations = []): Select { $table = call_user_func([$type, 'getTable']);