source: spip-zone/_core_/plugins/compresseur/inc/compresseur_concatener.php @ 43971

Last change on this file since 43971 was 43971, checked in by cedric@…, 9 years ago

debug de la gestion du recalcul dans la concatenation des fichiers (&var_mode=recalcul dans une url ne doit pas empecher de retomber sur le bon nom de fichier compresse obtenu sans ce var_mode)
respect de l'ordre du html pour le calcul du nom

Gestion plus smart du google closure compiler :

  • prise en compte des callbacks dans le nom du fichier compresse, ce qui permet de differencier le nom final dans les cas avec ou sans closure compiler
  • la fonction minifier_encore_js n'est appelee que lorsque le head est modifie (ou recalcul explicite)
  • modification de la fonction minifier_encore_js : si son second argument est une chaine, on l'utilise comme nom de fichier cible pour y recopier le js minifie, et on renvoie ce nom la, ce qui permet a l'appelant de fixer le nom final
File size: 5.7 KB
Line 
1<?php
2
3/***************************************************************************\
4 *  SPIP, Systeme de publication pour l'internet                           *
5 *                                                                         *
6 *  Copyright (c) 2001-2011                                                *
7 *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
8 *                                                                         *
9 *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
10 *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
11\***************************************************************************/
12
13if (!defined("_ECRIRE_INC_VERSION")) return;
14
15
16/**
17 * Concatener en un seul une liste de fichier,
18 * avec appels de callback sur chaque fichier,
19 * puis sur le fichier final
20 *
21 * Gestion d'un cache : le fichier concatene n'est produit que si il n'existe pas
22 * pour la liste de fichiers fournis en entree 
23 *
24 *
25 * @param array $files
26 *   liste des fichiers a concatener, chaque entree sour la forme html=>fichier
27 *   string $key : html d'insertion du fichier dans la page
28 *   string|array $fichier : chemin du fichier, ou tableau (page,argument) si c'est un squelette
29 * @param string $format
30 *   js ou css utilise pour l'extension du fichier de sortie
31 * @param array $callbacks
32 *   tableau de fonctions a appeler :
33 *   each_pre : fonction de preparation a appeler sur le contenu de chaque fichier
34 *   each_min : fonction de minification a appeler sur le contenu de chaque fichier
35 *   all_min : fonction de minification a appeler sur le contenu concatene complet, en fin de traitement
36 * @return array
37 *   tableau a 2 entrees retournant le nom du fichier et des commentairs html a inserer dans la page initiale
38 */
39function concatener_fichiers($files,$format='js', $callbacks = array()){
40        $nom = "";
41        if (!is_array($files) && $files) $files = array($files);
42        if (count($files)){
43                $callback_min = isset($callbacks['each_min'])?$callbacks['each_min']:'concatener_callback_identite';
44                $callback_pre = isset($callbacks['each_pre'])?$callbacks['each_pre']:'';
45          $url_base = self('&');
46
47                // on trie la liste de files pour calculer le nom
48                // necessaire pour retomber sur le meme fichier
49                // si on renome une url a la volee pour enlever le var_mode=recalcul
50                // mais attention, il faut garder l'ordre initial pour la minification elle meme !
51                $dir = sous_repertoire(_DIR_VAR,'cache-'.$format);
52                $nom = $dir . md5(serialize($files).serialize($callbacks)) . ".$format";
53                if (
54                        (defined('_VAR_MODE') AND _VAR_MODE=='recalcul')
55                        OR !file_exists($nom)
56                ) {
57                        $fichier = "";
58                        $comms = array();
59                        $total = 0;
60                        $files2 = false;
61                        foreach($files as $key=>$file){
62                                if (!is_array($file)) {
63                                        // c'est un fichier
64                                        $comm = $file;
65                                        // enlever le timestamp si besoin
66                                        $file = preg_replace(",[?].+$,",'',$file);
67
68                                        // preparer le fichier si necessaire
69                                        if ($callback_pre)
70                                                $file = $callback_pre($file);
71                                       
72                                        lire_fichier($file, $contenu);
73                                }
74                                else {
75                                        // c'est un squelette
76                                        $comm = _SPIP_PAGE . "=$file[0]"
77                                                . (strlen($file[1])?"($file[1])":'');
78                                        parse_str($file[1],$contexte);
79                                        $contenu = recuperer_fond($file[0],$contexte);
80
81                                        // preparer le contenu si necessaire
82                                        if ($callback_pre)
83                                                $contenu = $callback_pre($contenu, $url_base);
84                                        // enlever le var_mode si present pour retrouver la css minifiee standard
85                                        if (strpos($file[1],'var_mode')!==false) {
86                                                if (!$files2) $files2 = $files;
87                                                $old_key = $key;
88                                                $key = preg_replace(',(&(amp;)?)?var_mode=[^&\'"]*,','',$key);
89                                                $file[1] = preg_replace(',&?var_mode=[^&\'"]*,','',$file[1]);
90                                                $files2 = array_replace_key($files2,$old_key,$key,$file);
91                                        }
92                                }
93                                // passer la balise html initiale en second argument
94                                $fichier .= "/* $comm */\n". $callback_min($contenu, $key) . "\n\n";
95                                $comms[] = $comm;
96                                $total += strlen($contenu);
97                        }
98
99                        // calcul du % de compactage
100                        $pc = intval(1000*strlen($fichier)/$total)/10;
101                        $comms = "compact [\n\t".join("\n\t", $comms)."\n] $pc%";
102                        $fichier = "/* $comms */\n\n".$fichier;
103
104                        // si on a nettoye des &var_mode=recalcul : mettre a jour le nom
105                        // on ecrit pas dans le nom initial, qui est de toute facon recherche qu'en cas de recalcul
106                        // donc jamais utile
107                        if ($files2) {
108                                $files=$files2;
109                                $nom = $dir . md5(serialize($files).serialize($callbacks)) . ".$format";
110                        }
111
112                        $nom_tmp = $nom;
113                  $final_callback = (isset($callbacks['all_min'])?$callbacks['all_min']:false);
114                  if ($final_callback){
115                          unset($callbacks['all_min']);
116                    $nom_tmp = $dir . md5(serialize($files).serialize($callbacks)) . ".$format";
117                  }
118                        // ecrire
119                        ecrire_fichier($nom_tmp,$fichier,true);
120                        // ecrire une version .gz pour content-negociation par apache, cf. [11539]
121                        ecrire_fichier("$nom_tmp.gz",$fichier,true);
122
123                  if ($final_callback){
124                                // closure compiler ou autre super-compresseurs
125                                // a appliquer sur le fichier final
126                                $encore = $final_callback($nom_tmp, $nom);
127                    // si echec, on se contente de la compression sans cette callback
128                          if ($encore!==$nom){
129                                        // ecrire
130                                        ecrire_fichier($nom,$fichier,true);
131                                        // ecrire une version .gz pour content-negociation par apache, cf. [11539]
132                                        ecrire_fichier("$nom.gz",$fichier,true);
133                          }
134                  }
135                }
136
137
138        }
139
140        // Le commentaire detaille n'apparait qu'au recalcul, pour debug
141        return array($nom, (isset($comms) AND $comms) ? "<!-- $comms -->\n" : '');
142}
143
144function &concatener_callback_identite(&$contenu){
145        return $contenu;
146}
147
148function &array_replace_key($tableau,$orig_key,$new_key,$new_value=null){
149        $t = array();
150  foreach($tableau as $k=>$v){
151          if ($k==$orig_key){
152                  $k=$new_key;
153            if (!is_null($new_value))
154                    $v = $new_value;
155          }
156    $t[$k] = $v;
157  }
158  return $t;
159}
Note: See TracBrowser for help on using the repository browser.