Le gestionnaire de média de Dotclear 2 marche en général plutôt bien. Mais dans certains cas particuliers, il peut devenir très lent. En effet, sur la page d’informations d’un média, une combo box contient la liste de tous les répertoires du gestionnaire de média, pour permettre le déplacement du fichier. Dans le cas d’une arborescence complexe, la génération de cette liste peut prendre plusieurs dizaines de secondes…
C’était notamment le cas pour le gestionnaire de média d’Infobidouille, du fait d’une organisation des fichiers par date : un répertoire par année, contenant un répertoire par mois, contenant un répertoire par jour…
Pour résoudre ce problème sans désactiver complètement cette combo-box, parfois bien pratique, j’ai donc réécrit une nouvelle fonction permettant de lister les répertoires. Contrairement à celle d’origine, sa récursivité est limitée par un paramètre d’appel, et elle peut être restreinte à une sous-arborescence de celle du gestionnaire de média (dans ce cas, en plus de lister les répertoires de cette sous-arborescence, la fonction retourne aussi les chemins allant de la racine du gestionnaire à la racine de la sous-arborescence, pour permettre de déplacer un fichier n’importe où).
J’ai ajouté cette fonction dans le fichier admin/media_item.php :
function listDirs($base, $path, $profondeur) { $retval = Array(); if ($profondeur == 0) { return $retval; } if (!file_exists("$base/$path")) { return $retval; } $retval["/"] = ""; if ($path != "") { $tmpPath = "$base/$path"; while ($tmpPath != $base) { $relPath = str_replace($base."/", "", $tmpPath); $retval["/$relPath"] = $relPath; $tmpPath = dirname($tmpPath); } } $dirListing = scandir("$base/$path"); if ($dirListing === false) { return $retval; } $nbElem = sizeof($dirListing); for ($i = 0; $i < $nbElem; $i++) { $file = $dirListing[$i]; if ($file == "." || $file == "..") { continue; } else if(is_dir("$base/$path/$file")) { if ($path == "") { $newPath = $file; } else { $newPath = "$path/$file"; } $retval["/$newPath"] = $newPath; $retval = array_merge($retval, listDirs($base, $newPath, $profondeur - 1)); } } return $retval; }
J’appelle ensuite cette fonction deux fois. Une première fois pour construire la liste des répertoires contenus à la racine, et une seconde pour construire la liste des sous-répertoires sur deux niveau du répertoire contenant le fichier courant.
Toujours dans le fichier admin/media_item.php, remplacer :
$dirs_combo = array(); foreach ($core->media->getRootDirs() as $v) { if ($v->w) { $dirs_combo['/'.$v->relname] = $v->relname; } }
Par :
$dirs_combo = listDirs($core->blog->public_path, '', 1); $dirs_combo = array_merge(listDirs($core->blog->public_path, dirname($file->relname), 2), $dirs_combo);
Ainsi, de plusieurs centaines de répertoires, la liste générée passe à quelques dizaines. Bien entendu, cela signifie qu’une fois la modification effectuée, on ne peut plus déplacer un fichier de n’importe quel emplacement vers n’importe quel autre emplacement. Il faudra parfois s’y prendre en plusieurs opérations (au maximum, la moitié de la profondeur du plus long chemin).
Pour appliquer ce patch, déposez le à la racine de votre installation Dotclear puis ouvrez une console sur votre serveur, positionnez vous à la racine de votre installation Dotclear et tapez la commande suivante :
patch -p1 -ul -i fichier.patch -d .
Vous pourrez ensuite rétablir la version non patchée avec cette commande :
patch -p1 -ulR -i fichier.patch -d .
Si vous ne disposez pas d’un accès distant sur votre serveur, vous pouvez effectuer les modifications à la main ou appliquer le patch (en utilisant par exemple Cygwin si vous êtes sous Windows) sur une copie locale de votre installation Dotclear puis uploader la version patchée.