handle slugs in persistent data manager

This commit is contained in:
Bence Pőcze 2023-05-07 00:49:30 +02:00
parent afec6f1103
commit 8b25f57fe3
Signed by: bence
GPG Key ID: DC5BD6E95A333E6D

View File

@ -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']);