PluginProbe
Autoptimize / 1.6.0
Autoptimize v1.6.0
2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 All 107 releases
autoptimize / classes / autoptimizeScripts.php

autoptimizeScripts.php in Autoptimize 1.6.0, at classes/autoptimizeScripts.php

275 lines 6.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class autoptimizeScripts extends autoptimizeBase
4 {
5 private $scripts = array();
6 private $dontmove = array('document.write','html5.js','show_ads.js','google_ad','_gaq.push','/ads/');
7 private $domove = array('gaJsHost','load_cmc','jd.gallery.transitions.js','swfobject.embedSWF(','tiny_mce.js','tinyMCEPreInit.go');
8 private $domovelast = array('addthis.com','/afsonline/show_afs_search.js','disqus.js','networkedblogs.com/getnetworkwidget','infolinks.com/js/','jd.gallery.js.php','jd.gallery.transitions.js','swfobject.embedSWF(','linkwithin.com/widget.js','tiny_mce.js','tinyMCEPreInit.go');
9 private $trycatch = false;
10 private $yui = false;
11 private $jscode = '';
12 private $url = '';
13 private $move = array('first' => array(), 'last' => array());
14 private $restofcontent = '';
15 private $md5hash = '';
16
17 //Reads the page and collects script tags
18 public function read($options)
19 {
20 //Remove everything that's not the header
21 if($options['justhead'] == true)
22 {
23 $content = explode('</head>',$this->content,2);
24 $this->content = $content[0].'</head>';
25 $this->restofcontent = $content[1];
26 }
27
28 $excludeJS = $options['exclude'];
29 if ($excludeJS!=="") {
30 $exclJSArr = array_map('trim',explode(",",$excludeJS));
31 $this->dontmove = array_merge($exclJSArr,$this->dontmove);
32 }
33
34 //Should we add try-catch?
35 if($options['trycatch'] == true)
36 $this->trycatch = true;
37
38 //Do we use yui?
39 $this->yui = $options['yui'];
40
41 //Get script files
42 if(preg_match_all('#<script.*</script>#Usmi',$this->content,$matches))
43 {
44 foreach($matches[0] as $tag)
45 {
46 if(preg_match('#src=("|\')(.*)("|\')#Usmi',$tag,$source))
47 {
48 //External script
49 $url = current(explode('?',$source[2],2));
50 $path = $this->getpath($url);
51 if($path !==false && preg_match('#\.js$#',$path))
52 {
53 //Inline
54 if($this->ismergeable($tag))
55 {
56 //We can merge it
57 $this->scripts[] = $path;
58 }else{
59 //No merge, but maybe we can move it
60 if($this->ismovable($tag))
61 {
62 //Yeah, move it
63 if($this->movetolast($tag))
64 {
65 $this->move['last'][] = $tag;
66 }else{
67 $this->move['first'][] = $tag;
68 }
69 }else{
70 //We shouldn't touch this
71 $tag = '';
72 }
73 }
74 }else{
75 //External script (example: google analytics)
76 //OR Script is dynamic (.php etc)
77 if($this->ismovable($tag))
78 {
79 if($this->movetolast($tag))
80 {
81 $this->move['last'][] = $tag;
82 }else{
83 $this->move['first'][] = $tag;
84 }
85 }else{
86 //We shouldn't touch this
87 $tag = '';
88 }
89 }
90 }else{
91 //Inline script
92 if($this->ismergeable($tag))
93 {
94 preg_match('#<script.*>(.*)</script>#Usmi',$tag,$code);
95 $code = preg_replace('#.*<!\[CDATA\[(?:\s*\*/)?(.*)(?://|/\*)\s*?\]\]>.*#sm','$1',$code[1]);
96 $code = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/','',$code);
97 $this->scripts[] = 'INLINE;'.$code;
98 }else{
99 //Can we move this?
100 if($this->ismovable($tag))
101 {
102 if($this->movetolast($tag))
103 {
104 $this->move['last'][] = $tag;
105 }else{
106 $this->move['first'][] = $tag;
107 }
108 }else{
109 //We shouldn't touch this
110 $tag = '';
111 }
112 }
113 }
114
115 //Remove the original script tag
116 $this->content = str_replace($tag,'',$this->content);
117 }
118
119 return true;
120 }
121
122 //No script files :(
123 return false;
124 }
125
126 //Joins and optimizes JS
127 public function minify()
128 {
129 foreach($this->scripts as $script)
130 {
131 if(preg_match('#^INLINE;#',$script))
132 {
133 //Inline script
134 $script = preg_replace('#^INLINE;#','',$script);
135 //Add try-catch?
136 if($this->trycatch)
137 $script = 'try{'.$script.'}catch(e){}';
138 $this->jscode .= "\n".$script;
139 }else{
140 //External script
141 if($script !== false && file_exists($script) && is_readable($script))
142 {
143 $script = file_get_contents($script);
144 //Add try-catch?
145 if($this->trycatch)
146 $script = 'try{'.$script.'}catch(e){}';
147 $this->jscode .= "\n".$script;
148 }/*else{
149 //Couldn't read JS. Maybe getpath isn't working?
150 }*/
151 }
152 }
153
154 //Check for already-minified code
155 $this->md5hash = md5($this->jscode);
156 $ccheck = new autoptimizeCache($this->md5hash,'js');
157 if($ccheck->check())
158 {
159 $this->jscode = $ccheck->retrieve();
160 return true;
161 }
162 unset($ccheck);
163
164 //$this->jscode has all the uncompressed code now.
165 if($this->yui == false && class_exists('JSMin'))
166 {
167 $this->jscode = trim(JSMin::minify($this->jscode));
168 return true;
169 }elseif($this->yui == true && autoptimizeYUI::available()){
170 $this->jscode = autoptimizeYUI::compress('js',$this->jscode);
171 return true;
172 }else{
173 return false;
174 }
175 }
176
177 //Caches the JS in uncompressed, deflated and gzipped form.
178 public function cache()
179 {
180 $cache = new autoptimizeCache($this->md5hash,'js');
181 if(!$cache->check())
182 {
183 //Cache our code
184 $cache->cache($this->jscode,'text/javascript');
185 }
186 $this->url = AUTOPTIMIZE_CACHE_URL.$cache->getname();
187 }
188
189 //Returns the content
190 public function getcontent()
191 {
192 //Restore the full content
193 if(!empty($this->restofcontent))
194 {
195 $this->content .= $this->restofcontent;
196 $this->restofcontent = '';
197 }
198
199 //Add the scripts
200 $bodyreplacement = implode('',$this->move['first']);
201 $bodyreplacement .= '<script type="text/javascript" src="'.$this->url.'"></script>';
202 $bodyreplacement .= implode('',$this->move['last']).'</body>';
203 $this->content = str_replace('</body>',$bodyreplacement,$this->content);
204
205 //Return the modified HTML
206 return $this->content;
207 }
208
209 //Checks agains the whitelist
210 private function ismergeable($tag)
211 {
212 foreach($this->domove as $match)
213 {
214 if(strpos($tag,$match)!==false)
215 {
216 //Matched something
217 return false;
218 }
219 }
220
221 foreach($this->dontmove as $match)
222 {
223 if(strpos($tag,$match)!==false)
224 {
225 //Matched something
226 return false;
227 }
228 }
229
230 //If we're here it's safe to merge
231 return true;
232 }
233
234 //Checks agains the blacklist
235 private function ismovable($tag)
236 {
237
238 foreach($this->domove as $match)
239 {
240 if(strpos($tag,$match)!==false)
241 {
242 //Matched something
243 return true;
244 }
245 }
246
247 foreach($this->dontmove as $match)
248 {
249 if(strpos($tag,$match)!==false)
250 {
251 //Matched something
252 return false;
253 }
254 }
255
256 //If we're here it's safe to move
257 return true;
258 }
259
260 private function movetolast($tag)
261 {
262 foreach($this->domovelast as $match)
263 {
264 if(strpos($tag,$match)!==false)
265 {
266 //Matched, return true
267 return true;
268 }
269 }
270
271 //Should be in 'first'
272 return false;
273 }
274 }
275