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

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

refactoring du compresseur :
Separer par groupes fonctionnel :

  • minifier pour tout ce qui concerne la minification css ou js d'un fichier
  • concatener pour le regroupement de plusieurs fichiers en un (au passage, la fonction est generalisee et les specificites css/js sont simplement gerees par les callbacks passees en appel)
  • embarquer pour tout ce qui concerne(ra) l'inclusion des images en base64 dans les css (a developper)

On rationalise les nommage

File size: 8.0 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 * Ecrire la balise javascript pour inserer le fichier compresse
17 * C'est cette fonction qui decide ou il est le plus pertinent
18 * d'inserer le fichier, et dans quelle forme d'ecriture
19 *
20 * @param string $flux
21 *   contenu du head nettoye des fichiers qui ont ete compresse
22 * @param int $pos
23 *   position initiale du premier fichier inclu dans le fichier compresse
24 * @param string $src
25 *   nom du fichier compresse
26 * @param string $comments
27 *   commentaires a inserer devant
28 * @return string
29 */
30function compresseur_ecrire_balise_js_dist(&$flux, $pos, $src, $comments = ""){
31        $comments .= "<script type='text/javascript' src='$src'></script>";
32  $flux = substr_replace($flux,$comments,$pos,0);
33  return $flux;
34}
35
36/**
37 * Ecrire la balise css pour inserer le fichier compresse
38 * C'est cette fonction qui decide ou il est le plus pertinent
39 * d'inserer le fichier, et dans quelle forme d'ecriture
40 *
41 * @param string $flux
42 *   contenu du head nettoye des fichiers qui ont ete compresse
43 * @param int $pos
44 *   position initiale du premier fichier inclu dans le fichier compresse
45 * @param string $src
46 *   nom du fichier compresse
47 * @param string $comments
48 *   commentaires a inserer devant
49 * @return string
50 */
51function compresseur_ecrire_balise_css_dist(&$flux, $pos, $src, $comments = "", $media=""){
52        $comments .= "<link rel='stylesheet'".($media?" media='$media'":"")." href='$src' type='text/css' />";
53  $flux = substr_replace($flux,$comments,$pos,0);
54        return $flux;
55}
56
57/**
58 * Extraire les balises CSS a compacter et retourner un tableau
59 * balise => src
60 *
61 * @param  $flux
62 * @param  $url_base
63 * @return array
64 */
65function compresseur_extraire_balises_css_dist($flux, $url_base){
66        $balises = extraire_balises($flux,'link');
67        $files = array();
68        foreach ($balises as $s){
69                if (extraire_attribut($s, 'rel') === 'stylesheet'
70                        AND (!($type = extraire_attribut($s, 'type'))
71                                OR $type == 'text/css')
72                        AND is_null(extraire_attribut($s, 'name')) # css nommee : pas touche
73                        AND is_null(extraire_attribut($s, 'id'))   # idem
74                        AND !strlen(strip_tags($s))
75                        AND $src = preg_replace(",^$url_base,",_DIR_RACINE,extraire_attribut($s, 'href')))
76                        $files[$s] = $src;
77        }
78        return $files;
79}
80
81/**
82 * Extraire les balises JS a compacter et retoruner un tableau
83 * balise => src
84 * @param  $flux
85 * @param  $url_base
86 * @return array
87 */
88function compresseur_extraire_balises_js_dist($flux, $url_base){
89        $balises = extraire_balises($flux,'script');
90        $files = array();
91        foreach ($balises as $s){
92                if (extraire_attribut($s, 'type') === 'text/javascript'
93                        AND $src = extraire_attribut($s, 'src')
94                        AND !strlen(strip_tags($s)))
95                        $files[$s] = $src;
96        }
97        return $files;
98}
99
100/**
101 * Compacter (concatener+minifier) les fichiers format css ou js
102 * du head. Reperer fichiers statiques vs url squelettes
103 * Compacte le tout dans un fichier statique pose dans local/
104 *
105 * @param string $flux
106 *  contenu du <head> de la page html
107 * @param string $format
108 *  css ou js
109 * @return string
110 */
111function compacte_head_files($flux,$format) {
112        $url_base = url_de_base();
113        $url_page = substr(generer_url_public('A'), 0, -1);
114        $dir = preg_quote($url_page,',').'|'.preg_quote(preg_replace(",^$url_base,",_DIR_RACINE,$url_page),',');
115
116        if (!$extraire_balises = charger_fonction("compresseur_extraire_balises_$format",'',true))
117                return $flux;
118
119        $files = array();
120        $flux_nocomment = preg_replace(",<!--.*-->,Uims","",$flux);
121        foreach ($extraire_balises($flux_nocomment, $url_base) as $s=>$src) {
122                if (
123                        preg_match(',^('.$dir.')(.*)$,', $src, $r)
124                        OR (
125                                // ou si c'est un fichier
126                                $src = preg_replace(',^'.preg_quote(url_de_base(),',').',', '', $src)
127                                // enlever un timestamp eventuel derriere un nom de fichier statique
128                                AND $src2 = preg_replace(",[.]{$format}[?].+$,",".$format",$src)
129                                // verifier qu'il n'y a pas de ../ ni / au debut (securite)
130                                AND !preg_match(',(^/|\.\.),', substr($src,strlen(_DIR_RACINE)))
131                                // et si il est lisible
132                                AND @is_readable($src2)
133                        )
134                ) {
135                        if ($r)
136                                $files[$s] = explode('&', str_replace('&amp;', '&', $r[2]), 2);
137                        else
138                                $files[$s] = $src;
139                }
140        }
141
142        $callbacks = array('each_min'=>'callback_minifier_'.$format.'_file', 'all_min'=>'callback_minifier_encore');
143        if ($format=="css")
144                $callbacks['each_pre'] = 'compresseur_callback_prepare_css';
145
146        include_spip('inc/compresseur_concatener');
147        include_spip('inc/compresseur_minifier');
148        if (list($src,$comms) = concatener_fichiers($files, $format, $callbacks)){
149                $compacte_ecrire_balise = charger_fonction("compresseur_ecrire_balise_$format",'');
150                $files = array_keys($files);
151                // retrouver la position du premier fichier compacte
152                $pos = strpos($flux,reset($files));
153                // supprimer tous les fichiers compactes du flux
154                $flux = str_replace($files,"",$flux);
155                // inserer la balise (deleguer a la fonction, en lui donnant le necessaire)
156                $flux = $compacte_ecrire_balise($flux, $pos, $src, $comms);
157        }
158
159        return $flux;
160}
161
162
163/**
164 * lister les fonctions de preparation des feuilles css
165 * avant minification
166 *
167 * @return array
168 */
169function compresseur_liste_fonctions_prepare_css(){
170        static $fonctions = null;
171
172        if (is_null($fonctions)){
173                $fonctions = array('urls_absolues_css');
174                // les fonctions de preparation aux CSS peuvent etre personalisees
175                // via la globale $compresseur_filtres_css sous forme de tableau de fonctions ordonnees
176                if (isset($GLOBALS['compresseur_filtres_css']) AND is_array($GLOBALS['compresseur_filtres_css']))
177                        $fonctions = $GLOBALS['compresseur_filtres_css'] + $fonctions;
178        }
179  return $fonctions;
180}
181
182
183/**
184 * Preparer un fichier CSS avant sa minification
185 * @param string $css
186 * @param bool|string $is_inline
187 * @return bool|int|null|string
188 */
189function &compresseur_callback_prepare_css(&$css, $is_inline = false, $fonctions=null) {
190        if ($is_inline) return compresseur_callback_prepare_css_inline($css,$is_inline);
191        if (!preg_match(',\.css$,i', $css, $r)) return $css;
192
193        $url_absolue_css = url_absolue($css);
194
195        if (!$fonctions) $fonctions = compresseur_liste_fonctions_prepare_css();
196        elseif (is_string($fonctions)) $fonctions = array($fonctions);
197
198        $sign = implode(",",$fonctions);
199        $sign = substr(md5("$css-$sign"), 0,8);
200
201        $file = basename($css,'.css');
202        $file = sous_repertoire (_DIR_VAR, 'cache-css')
203                . preg_replace(",(.*?)(_rtl|_ltr)?$,","\\1-f-" . $sign . "\\2",$file)
204                . '.css';
205
206        if ((@filemtime($file) > @filemtime($css))
207                AND ($GLOBALS['var_mode'] != 'recalcul'))
208                return $file;
209
210        if ($url_absolue_css==$css){
211                if (strncmp($GLOBALS['meta']['adresse_site'],$css,$l=strlen($GLOBALS['meta']['adresse_site']))!=0
212                 OR !lire_fichier(_DIR_RACINE . substr($css,$l), $contenu)){
213                                include_spip('inc/distant');
214                                if (!$contenu = recuperer_page($css))
215                                        return $css;
216                }
217        }
218        elseif (!lire_fichier($css, $contenu))
219                return $css;
220
221        $contenu = compresseur_callback_prepare_css_inline($contenu, $css, $fonctions);
222
223        // ecrire la css
224        if (!ecrire_fichier($file, $contenu))
225                return $css;
226
227        return $file;
228}
229
230/**
231 * Preparer du contenu CSS inline avant minification
232 *
233 * @param string $contenu
234 * @param string $url_base
235 * @return string
236 */
237function &compresseur_callback_prepare_css_inline(&$contenu, $url_base, $fonctions=null) {
238        if (!$fonctions) $fonctions = compresseur_liste_fonctions_prepare_css();
239        elseif (is_string($fonctions)) $fonctions = array($fonctions);
240
241        foreach($fonctions as $f)
242                if (function_exists($f))
243                        $contenu = $f($contenu, $url_base);
244       
245        return $contenu;
246}
247
Note: See TracBrowser for help on using the repository browser.