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); } }