Améliorer la performance du gestionnaire de médias de PluXml

Rédigé par Jean-Pierre Pourrez -

Sur le forum de PluXml, le dessinateur de BD David Revoy (Deewad) appelle à l'aide car il utilise un grand nombre d'images pour ses oeuvres. Compte-tenu du volume, le gestionnaire de médias de PluXml commence à être vraiment à la peine. Il lui faut plusieurs dizaines de secondes pour afficher la liste des images.

Je vous détaille dans la suite de l'article comment y remédier.

Si vous maitrisez Git, les modifications apportées sont disponibles dans la branche plxmedias-1811 sur mon dépôt Github :

git clone https://github.com/bazooka07/PluXml.git -b plxmedias-1811

Les modifications portent essentiellement sur le fichier core/lib/class.plx.medias.php qui précise la class plxMedias :

Supprimer ou commenter comme suit les propriétés $thumb...  concernant la taille des vignettes

/*
	public $thumbQuality = 60; # qualité image
	public $thumbWidth = 60; # largeur des miniatures
	public $thumbHeight = 60; # hauteur des miniatures
	* */

Elles réglent la taille des vignettes à 60px. Mais la feuille de style CSS les réduit à 48px. Et la fonction qui crée ces vignettes utilisent par défaut une taille de 48px. Donc poubelle.

La correction des expressions régulières dans PluXml est un vaste chantier dont l'ouverture est repoussée d'année en année. Vous trouverez toutes les corrections à ce sujet dans la branche echecs de mon dépôt Github. Elles sont en service depuis au moins deux ans. Voici les corrections à apporter concernant les extensions de fichiers :

public $img_exts = '/\.(jpe?g|png|gif|bmp)$/i';
public $doc_exts = '/\.(7z|aiff|asf|avi|csv|docx?|epub|fla|flv|gz|gzip|m4a|m4v|mid|mov|mp3|mp4|mpc|mpe?g|ods|odt|odp|ogg|pdf|pptx?|ppt|pxd|qt|ram|rar|rm|rmi|rmvb|rtf|svg|swf|sxc|sxw|tar|tgz|txt|vtt|wav|webm|wma|wmv|xcf|xlsx?|zip)$/i';

Pour les images, les extensions sont classées par ordre de popularité. Normalement, il faudrait en faire autant pour les documents.

Nous allons maintenant rentrer dans le lourd. Il faut remplacer totalement les trois fonctions suivantes. La bonne nouvelle est qu'elles se suivent. C'est plus facile pour effacer.

  • private function _getAllDirs()
  • private function _getDirFiles($dir)
  • public function contentFolder()

Et le code qui va bien à la place :

/**
	 * Méthode qui retourne un tableau de tous les dossiers et sous-dossiers d'un répertoire.
	 *
	 * @author	J.P. Pourrez (bazooka07)
	 **/
	private function _getAllDirs() {
		$result = array();
		$pattern = '*/';
		$offset = strlen($this->path);
		for($i=1; $i<10; $i++) {
			$dirs = glob($this->path . str_repeat($pattern, $i), GLOB_ONLYDIR);
			if(empty($dirs)) { break; }
			foreach($dirs as $d) {
				$path = substr($d, $offset);
				$result[] = array(
					'level' => $i,
					/* 'name'	=> '/'.$path, // totalement inutile et jamais utilisé ! */
					'path'	=> $path
				);
			}
		}
		usort($result, function($a, $b) { return strcasecmp($a['path'], $b['path']); });
		return $result;
	}

	/**
	 * Méthode qui retourne la liste des fichiers d'un répertoire
	 *
	 * @param	dir		répertoire de lecture
	 * @return	files	tableau contenant la liste de tous les fichiers d'un dossier
	 * @author	Stephane F
	 **/
	private function _getDirFiles($dir) {

		$src = $this->path.$dir;
		if(!is_dir($src)) return array();

		$defaultSample = PLX_CORE.'admin/theme/images/file.png';
		$offset = strlen($this->path);
		$files = array();
		foreach(array_filter(
			glob($src.'*'),
			function($item) { return !preg_match('@\.tb\.\w+$@', $item); } # On rejette les miniatures
		) as $filename) {
			if(is_dir($filename)) { continue; }

			$thumbInfos = false;
			if(preg_match('@\.(jpe?g|png|gif)$@i', $filename, $matches)) {
				# Youpi! We catch a picture
				$thumbName = plxUtils::thumbName($filename);
				if(file_exists($thumbName)) {
					$thumbInfos = array(
						'infos' 	=> getimagesize($thumbName),
						'filesize'	=> filesize($thumbName)
					);
				}
				$sample = $this->path. '.thumbs/' .substr($filename, $offset);
				$sampleOk = (
					file_exists($sample) or
					plxUtils::makeThumb(
						$filename,
						$sample
					)
				);
				$imgSize = getimagesize($filename);
			} else {
				$imgSize = false;
			}
			$stats = stat($filename);
			$files[basename($filename)] = array(
				'.thumb'	=> (!empty($sampleOk)) ? $sample : $defaultSample,
				'name' 		=> basename($filename),
				'path' 		=> $filename,
				'date' 		=> $stats['mtime'],
				'filesize' 	=> $stats['size'],
				'extension'	=> '.' . strtolower(pathinfo($filename, PATHINFO_EXTENSION)),
				'infos' 	=> $imgSize,
				'thumb' 	=> $thumbInfos
			);
		}

		ksort($files);
		return $files;
	}

	/**
	 * Méthode qui formate l'affichage de la liste déroulante des dossiers
	 *
	 * @return	string	balise select à afficher
	 * @author	J.P. Pourrez (bazooka07)
	 **/
	public function contentFolder() {

		$currentFolder = $this->dir;
		if(!empty($this->aDirs)) {
			$options = array_map(
				function($item) use($currentFolder) {
					$selected = ($item['path'] == $currentFolder) ? ' selected' : '';
					return <<< OPTION
			<option class="level_{$item['level']}" value="${item['path']}"$selected>/${item['path']}</option>
OPTION;
				},
				$this->aDirs
			);
		}

		$selectedRoot = (empty($this->dir)) ? ' selected' : '';
		$caption = L_PLXMEDIAS_ROOT;
		$start = <<< START
		<select class="folder" id="folder" name="folder">
			<option value="."$selectedRoot>($caption)</option>\n
START;
		$stop = <<< STOP
		</select>\n
STOP;
		return $start . ((!empty($options)) ? implode("\n", $options) : '') . $stop;
	}

La fonction __getAllDirs est la plus pénalisante pour plusieurs raisons :

  • elle utilise une vieille fonction scandir
  • c'est une fonction récursive qui demande le passage de paramètres
  • On fusionne des tableaux et on en crée un à chaque fois
  • on trie les tableaux à chaque fois plutôt que de faire un tri à la fin

Il reste encore quelques petits détails à régler.

Toutes les vignettes ont une taille de 48px. Autant le préciser dans la balise <img> correspondante. Cela aidera le navigateur Internet à faire le rendu de la page. Il faut modifier pour cela le fichier core/admin/medias.php. Rechercher l'expression unique class="thumb" et modifier la balise <img> correspondante en précisant la taille de l'image comme suit :

<img alt="" src="https://kazimentou.fr/'.$v['.thumb'].'" class="thumb" width="48" height="48" />

Enfin la dernière modification est à faire pour le thème d'administration dans le fichier core/admin/theme/css en recherchant la règle #medias-table img  et en la modifiant comme suit :

#medias-table img {
max-width: initial !important;
vertical-align: bottom;
}

Attention si vous utilisez des fichiers minifiés, il faut les regénér. J'ignore comment procède le staff de PluXml. Si Python est installé sur votre PC, vous pouvez utiliser le programme css-html-js-minify après vous être déplacé dans le dossier core/admin/theme. Pour l'installer :

sudo pip3 css-html-js-minify

Vous pouvez télécharger l'archive Zip de la future version 5.7 modifiée de Pluxml sur la page de téléchargement.

Classé dans : Pluxml
Mot-clés : aucun

2 commentaires

#1  - Frémo a dit :

Bravo et merci pour vos nombreuses contributions à PluXml !

Petit erreur de frappe sur le nom du dessinateur qui est en fait David Revoy (au lieu de Leroy).
Merci pour lui. :)

Bonne journée.
Frédéric

#2  - Jean-Pierre Pourrez a dit :

Désolé. C'est corrigé.
En espérant que ces améliorations soient publiées avec la prochaine version de PluXml.

Fil RSS des commentaires de cet article

Les commentaires sont fermés.