93 lines
2.9 KiB
PHP
93 lines
2.9 KiB
PHP
<?php
|
|
|
|
use humhub\components\Migration;
|
|
|
|
class m260401_200000_add_slug extends Migration
|
|
{
|
|
public function safeUp()
|
|
{
|
|
$schema = $this->db->getSchema()->getTableSchema('rescue_space_profile', true);
|
|
if ($schema === null) {
|
|
return;
|
|
}
|
|
|
|
if (!isset($schema->columns['slug'])) {
|
|
$this->addColumn('rescue_space_profile', 'slug', $this->string(190)->null()->after('mission_statement'));
|
|
}
|
|
|
|
$rows = (new \yii\db\Query())
|
|
->select([
|
|
'id' => 'rsp.id',
|
|
'rescue_name' => 'rsp.rescue_name',
|
|
'space_name' => 's.name',
|
|
])
|
|
->from(['rsp' => 'rescue_space_profile'])
|
|
->leftJoin(['cc' => 'contentcontainer'], 'cc.id = rsp.contentcontainer_id')
|
|
->leftJoin(['s' => 'space'], 's.contentcontainer_id = cc.id')
|
|
->orderBy(['rsp.id' => SORT_ASC])
|
|
->all($this->db);
|
|
|
|
foreach ($rows as $row) {
|
|
$source = trim((string)($row['space_name'] ?? ''));
|
|
if ($source === '') {
|
|
$source = trim((string)($row['rescue_name'] ?? ''));
|
|
}
|
|
|
|
$slug = $this->createUniqueSlug($source, (int)$row['id']);
|
|
$this->update('rescue_space_profile', ['slug' => $slug], ['id' => (int)$row['id']]);
|
|
}
|
|
|
|
$this->alterColumn('rescue_space_profile', 'slug', $this->string(190)->notNull());
|
|
$this->safeCreateIndex('ux_rescue_space_profile_slug', 'rescue_space_profile', 'slug', true);
|
|
}
|
|
|
|
public function safeDown()
|
|
{
|
|
$schema = $this->db->getSchema()->getTableSchema('rescue_space_profile', true);
|
|
if ($schema === null || !isset($schema->columns['slug'])) {
|
|
return;
|
|
}
|
|
|
|
$this->safeDropIndex('ux_rescue_space_profile_slug', 'rescue_space_profile');
|
|
$this->dropColumn('rescue_space_profile', 'slug');
|
|
}
|
|
|
|
private function createUniqueSlug(string $source, int $rowId): string
|
|
{
|
|
$base = $this->normalizeToSlug($source);
|
|
$candidate = $base;
|
|
$counter = 1;
|
|
|
|
while ($this->slugExists($candidate, $rowId)) {
|
|
$candidate = $base . '-' . $counter;
|
|
$counter++;
|
|
}
|
|
|
|
return $candidate;
|
|
}
|
|
|
|
private function normalizeToSlug(string $value): string
|
|
{
|
|
$normalized = trim($value);
|
|
$ascii = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $normalized);
|
|
if ($ascii !== false) {
|
|
$normalized = $ascii;
|
|
}
|
|
|
|
$slug = strtolower($normalized);
|
|
$slug = preg_replace('/[^a-z0-9]+/', '-', $slug) ?? '';
|
|
$slug = trim($slug, '-');
|
|
|
|
return $slug !== '' ? $slug : 'rescue';
|
|
}
|
|
|
|
private function slugExists(string $slug, int $rowId): bool
|
|
{
|
|
return (new \yii\db\Query())
|
|
->from('rescue_space_profile')
|
|
->where(['slug' => $slug])
|
|
->andWhere(['!=', 'id', $rowId])
|
|
->exists($this->db);
|
|
}
|
|
}
|