[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / plugins-dist / compresseur / compresseur_fonctions.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2016 *
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
13 /**
14 * Fonctions et filtres du compresseur
15 *
16 * @package SPIP\Compresseur\Fonctions
17 */
18 if (!defined('_ECRIRE_INC_VERSION')) {
19 return;
20 }
21 $GLOBALS['spip_matrice']['compresseur_embarquer_images_css'] = 'inc/compresseur_embarquer.php';
22
23 /**
24 * Minifier un fichier JS ou CSS
25 *
26 * Si la source est un chemin, on retourne un chemin avec le contenu minifié
27 * dans _DIR_VAR/cache_$format/
28 * Si c'est un flux on le renvoit compacté
29 * Si on ne sait pas compacter, on renvoie ce qu'on a recu
30 *
31 * @param string $source
32 * Contenu à minifier ou chemin vers un fichier dont on veut minifier le contenu
33 * @param string $format
34 * Format de la source (js|css).
35 * @return string
36 * - Contenu minifié (si la source est un contenu)
37 * - Chemin vers un fichier ayant le contenu minifié (si source est un fichier)
38 */
39 function minifier($source, $format = null) {
40 if (!$format and preg_match(',\.(js|css)$,', $source, $r)) {
41 $format = $r[1];
42 }
43 include_spip('inc/compresseur_minifier');
44 if (!function_exists($minifier = 'minifier_' . $format)) {
45 return $source;
46 }
47
48 // Si on n'importe pas, est-ce un fichier ?
49 if (!preg_match(',[\s{}],', $source)
50 and preg_match(',\.' . $format . '$,i', $source, $r)
51 and file_exists($source)
52 ) {
53 // si c'est une css, il faut reecrire les url en absolu
54 if ($format == 'css') {
55 $source = url_absolue_css($source);
56 }
57
58 $f = basename($source, '.' . $format);
59 $f = sous_repertoire(_DIR_VAR, 'cache-' . $format)
60 . preg_replace(',(.*?)(_rtl|_ltr)?$,', "\\1-minify-"
61 . substr(md5("$source-minify"), 0, 4) . "\\2", $f, 1)
62 . '.' . $format;
63
64 if ((@filemtime($f) > @filemtime($source))
65 and (!defined('_VAR_MODE') or _VAR_MODE != 'recalcul')
66 ) {
67 return $f;
68 }
69
70 if (!lire_fichier($source, $contenu)) {
71 return $source;
72 }
73
74 // traiter le contenu
75 $contenu = $minifier($contenu);
76
77 // ecrire le fichier destination, en cas d'echec renvoyer la source
78 if (ecrire_fichier($f, $contenu, true)) {
79 return $f;
80 } else {
81 return $source;
82 }
83 }
84
85 // Sinon simple minification de contenu
86 return $minifier($source);
87 }
88
89 /**
90 * Synonyme historique de minifier, pour compatibilite
91 *
92 * @deprecated Utiliser minifier()
93 *
94 * @param string $source
95 * @param string $format
96 * @return string
97 */
98 function compacte($source, $format = null) {
99 return minifier($source, $format);
100 }
101
102 /**
103 * Compacte les éléments CSS et JS d'un <head> HTML
104 *
105 * Cette fonction vérifie les réglages du site et traite le compactage
106 * des css et/ou js d'un <head>
107 *
108 * Un fichier .gz est crée pour chaque, qui peut etre utilisé par apache
109 * et lui éviter de recompresser à chaque hit, avec les directives suivantes :
110 *
111 * <IfModule mod_gzip.c>
112 * mod_gzip_on Yes
113 * mod_gzip_can_negotiate Yes
114 * mod_gzip_static_suffix .gz
115 * AddEncoding gzip .gz
116 * mod_gzip_item_include file \.(js|css)$
117 * </IfModule>
118 *
119 * @see compacte_head_files()
120 *
121 * @param string $flux
122 * Partie de contenu du head HTML
123 * @return string
124 * Partie de contenu du head HTML
125 */
126 function compacte_head($flux) {
127 include_spip('inc/compresseur');
128 if (!defined('_INTERDIRE_COMPACTE_HEAD')) {
129 // dans l'espace prive on compacte toujours, c'est concu pour
130 if ((!test_espace_prive() and $GLOBALS['meta']['auto_compress_css'] == 'oui') or (test_espace_prive() and !defined('_INTERDIRE_COMPACTE_HEAD_ECRIRE'))) {
131 $flux = compacte_head_files($flux, 'css');
132 }
133 if ((!test_espace_prive() and $GLOBALS['meta']['auto_compress_js'] == 'oui') or (test_espace_prive() and !defined('_INTERDIRE_COMPACTE_HEAD_ECRIRE'))) {
134 $flux = compacte_head_files($flux, 'js');
135 }
136 }
137
138 return $flux;
139 }
140
141 /**
142 * Embarquer sous forme URI Scheme un fichier
143 *
144 * Une URI Scheme est de la forme data:xxx/yyy;base64,....
145 *
146 * Experimental
147 *
148 * @filtre
149 *
150 * @staticvar array $mime
151 * Couples (extension de fichier => type myme)
152 * @param string $src
153 * Chemin du fichier
154 * @param string $base
155 * Le chemin de base à partir duquel chercher $src
156 * @param int $maxsize
157 * Taille maximale des fichiers à traiter
158 * @return string
159 * URI Scheme du fichier si la compression est faite,
160 * URL du fichier sinon (la source)
161 */
162 function filtre_embarque_fichier($src, $base = '', $maxsize = 4096) {
163 static $mime = array();
164 $extension = substr(strrchr($src, '.'), 1);
165 $filename = $base . $src;
166
167 if (!file_exists($filename)
168 or filesize($filename) > $maxsize
169 or !lire_fichier($filename, $contenu)
170 ) {
171 return $src;
172 }
173
174 if (!isset($mime[$extension])) {
175 if (isset($GLOBALS['tables_mime']) and isset($GLOBALS['tables_mime'][$extension])) {
176 $mime[$extension] = $GLOBALS['tables_mime'][$extension];
177 }
178 }
179 if (!isset($mime[$extension])) {
180 if (!function_exists('sql_getfetsel')) {
181 include_spip('base/abstract_sql');
182 }
183 $mime[$extension] = sql_getfetsel('mime_type', 'spip_types_documents', 'extension=' . sql_quote($extension));
184 }
185
186 $base64 = base64_encode($contenu);
187 $encoded = 'data:' . $mime[$extension] . ';base64,' . $base64;
188
189 return $encoded;
190 }
191
192
193 /**
194 * Embarquer le 'src' d'une balise html en URI Scheme
195 *
196 * Experimental
197 *
198 * @param string $img
199 * Code HTML d'une image
200 * @param int $maxsize
201 * Taille maximale des fichiers à traiter
202 * @return string
203 * Code HTML de l'image, avec la source en URI Scheme si cela a été possible.
204 */
205 function filtre_embarque_src($img, $maxsize = 4096) {
206 $src = extraire_attribut($img, 'src');
207 if ($src2 = filtre_embarque_fichier($src, '', $maxsize) and $src2 != $src) {
208 $img = inserer_attribut($img, 'src', $src2);
209 }
210
211 return $img;
212 }