V této kapitole prezentuji, jak jsem musel připravit stromovou strukturu současného fotoalba.
webalizace – odstranění diakritiky a nahrazení speciálních znaků (např. mezer) pomlčkou
Výchozí stav:
Struktura složek ve formátu /ALBUM/001/001/038/019/. Tuto strukturu jsem měl uloženou v databázi ve formátu (id, parent_id, path, description). Tuto strukturu jsem dále rozšířil o atributy level (hloubka zanoření ve stromu), webalize-desc )(webalizovaný název složky), webalize-path (webalizovaná cesta).
1. krok – vytvoření webalizovaného popisku v databázi
public function createCoolURL() { $this->connection->exec('begin'); foreach ($this->connection->table('I_dir') as $row) { $this->connection->exec('UPDATE `I_dir` SET `webalize-desc`=? WHERE `id`=? LIMIT 1', Strings::webalize($row->desc, '._', FALSE), $row->id); } $this->connection->exec('commit'); } |
2. krok – vypočtení atributu level
public function computeLevel() { $this->connection->exec('begin'); foreach ($this->connection->table('I_dir') as $row) { $this->connection->exec('UPDATE `I_dir` SET `level`=? WHERE `id`=? LIMIT 1', substr_count ($row->path, '\\')-1, $row->id); } $this->connection->exec('commit'); } |
3. krok – vytvoření webalizovaného překladu cesty
Tady je třeba se zamyslet co vlastně děláme a proč to níže může vypadat relativně složitě. Výchozí stav je takový, že známe cestu k cílové složce (/001/001/038/019/) a její název. Ale abychom byli schopni univerzálně přejmenovat celou cestu, tak musíme začít od kořene. Tj. první přejmenovat složky level=1 (/001/). Následně level=2 (/001/001/) a to pomocí parent_id, kde již víme, že se ta složka nějak jmenuje a jen připojit webalizovaný název aktuální úrovně.
public function createWebalizePath() { $this->connection->exec('begin'); foreach ($this->connection->fetchAll('SELECT DISTINCT `level` FROM `I_dir` WHERE `level`>0 ORDER BY `level` ASC') as $l) { foreach ($this->connection->fetchAll('SELECT `a`.`id`, `a`.`webalize-desc` AS `wd`, `b`.`webalize-path` AS `path` FROM `I_dir` `a` JOIN `I_dir` `b` ON `a`.`parent_id`=`b`.`id` WHERE `a`.`level`=?', $l->level) as $row) { $this->connection->exec('UPDATE `I_dir` SET `webalize-path`=? WHERE `id`=? LIMIT 1', ($row->path.$row->wd.'\\'), $row->id); } } $this->connection->exec('commit'); } |
4. krok – přejmenování samotných složek
Záhadná formule REVERSE(SUBSTRING(REVERSE(`path`), 5))…
- REVERSE(`path`) z „\001\002\“ do „\200\100\“
- SUBSTRING(…, 5) z „\200\100\“ do „100\“
- REVERSE(…) z „100\“ do „\001“
Zbytek je snad jasný…
public function renameFolders() { foreach ($this->connection->fetchAll('SELECT `path`, REVERSE(SUBSTRING(REVERSE(`path`), 5)) AS `newPath`, `webalize-desc` AS `wd` FROM `I_dir` WHERE `level`>0 ORDER BY `level` DESC') as $row) { @rename(ALBUM_PATH . strtr($row->path, '\\', '/'), ALBUM_PATH . strtr($row->newPath, '\\', '/') . $row->wd); } } |
Zatím tu není řešeno přidání nové složky, ale to bude principiálně stejné. Jen budu muset vyřešit jak dám programu vědět, která složka a kde přibyla.
Nápady – databáze (chci se ji maximálně vyhnout a velká náchylnost na chybu), Nějaký FLAG soubor – zatím se mi jeví jako dobré řešení. Musel bych jen udělat „robota“, který by hledal soubor jistých parametrů a v případě nálezu by danou složku zpracoval a soubor třeba smazal. Ale to předbíhám…