PluginProbe
Autoptimize / 1.3
Autoptimize v1.3
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.3, at classes/autoptimizeScripts.php

269 lines 6.7 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','show_ads.js','google_ad','blogcatalog.com/w','tweetmeme.com/i','mybloglog.com/','var s_sid = ','histats.com/js','smowtion_size','ads.smowtion.com/ad.js','sc_project','statcounter.com/counter/counter.js','widgets.amung.us','WAU_','wau_add','ws.amazon.com/widgets','media.fastclick.net','/ads/','comment-form-quicktags/quicktags.php','edToolbar','intensedebate.com','ch_client','scripts.chitika.net/','_gaq.push');
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 //Should we add try-catch?
29 if($options['trycatch'] == true)
30 $this->trycatch = true;
31
32 //Do we use yui?
33 $this->yui = $options['yui'];
34
35 //Get script files
36 if(preg_match_all('#<script.*</script>#Usmi',$this->content,$matches))
37 {
38 foreach($matches[0] as $tag)
39 {
40 if(preg_match('#src=("|\')(.*)("|\')#Usmi',$tag,$source))
41 {
42 //External script
43 $url = current(explode('?',$source[2],2));
44 $path = $this->getpath($url);
45 if($path !==false && preg_match('#\.js$#',$path))
46 {
47 //Inline
48 if($this->ismergeable($tag))
49 {
50 //We can merge it
51 $this->scripts[] = $path;
52 }else{
53 //No merge, but maybe we can move it
54 if($this->ismovable($tag))
55 {
56 //Yeah, move it
57 if($this->movetolast($tag))
58 {
59 $this->move['last'][] = $tag;
60 }else{
61 $this->move['first'][] = $tag;
62 }
63 }else{
64 //We shouldn't touch this
65 $tag = '';
66 }
67 }
68 }else{
69 //External script (example: google analytics)
70 //OR Script is dynamic (.php etc)
71 if($this->ismovable($tag))
72 {
73 if($this->movetolast($tag))
74 {
75 $this->move['last'][] = $tag;
76 }else{
77 $this->move['first'][] = $tag;
78 }
79 }else{
80 //We shouldn't touch this
81 $tag = '';
82 }
83 }
84 }else{
85 //Inline script
86 if($this->ismergeable($tag))
87 {
88 preg_match('#<script.*>(.*)</script>#Usmi',$tag,$code);
89 $code = preg_replace('#.*<!\[CDATA\[(?:\s*\*/)?(.*)(?://|/\*)\s*?\]\]>.*#sm','$1',$code[1]);
90 $code = preg_replace('/(?:^\\s*<!--\\s*|\\s*(?:\\/\\/)?\\s*-->\\s*$)/','',$code);
91 $this->scripts[] = 'INLINE;'.$code;
92 }else{
93 //Can we move this?
94 if($this->ismovable($tag))
95 {
96 if($this->movetolast($tag))
97 {
98 $this->move['last'][] = $tag;
99 }else{
100 $this->move['first'][] = $tag;
101 }
102 }else{
103 //We shouldn't touch this
104 $tag = '';
105 }
106 }
107 }
108
109 //Remove the original script tag
110 $this->content = str_replace($tag,'',$this->content);
111 }
112
113 return true;
114 }
115
116 //No script files :(
117 return false;
118 }
119
120 //Joins and optimizes JS
121 public function minify()
122 {
123 foreach($this->scripts as $script)
124 {
125 if(preg_match('#^INLINE;#',$script))
126 {
127 //Inline script
128 $script = preg_replace('#^INLINE;#','',$script);
129 //Add try-catch?
130 if($this->trycatch)
131 $script = 'try{'.$script.'}catch(e){}';
132 $this->jscode .= "\n".$script;
133 }else{
134 //External script
135 if($script !== false && file_exists($script) && is_readable($script))
136 {
137 $script = file_get_contents($script);
138 //Add try-catch?
139 if($this->trycatch)
140 $script = 'try{'.$script.'}catch(e){}';
141 $this->jscode .= "\n".$script;
142 }/*else{
143 //Couldn't read JS. Maybe getpath isn't working?
144 }*/
145 }
146 }
147
148 //Check for already-minified code
149 $this->md5hash = md5($this->jscode);
150 $ccheck = new autoptimizeCache($this->md5hash,'js');
151 if($ccheck->check())
152 {
153 $this->jscode = $ccheck->retrieve();
154 return true;
155 }
156 unset($ccheck);
157
158 //$this->jscode has all the uncompressed code now.
159 if($this->yui == false && class_exists('JSMin'))
160 {
161 $this->jscode = trim(JSMin::minify($this->jscode));
162 return true;
163 }elseif($this->yui == true && autoptimizeYUI::available()){
164 $this->jscode = autoptimizeYUI::compress('js',$this->jscode);
165 return true;
166 }else{
167 return false;
168 }
169 }
170
171 //Caches the JS in uncompressed, deflated and gzipped form.
172 public function cache()
173 {
174 $cache = new autoptimizeCache($this->md5hash,'js');
175 if(!$cache->check())
176 {
177 //Cache our code
178 $cache->cache($this->jscode,'text/javascript');
179 }
180 $this->url = AUTOPTIMIZE_CACHE_URL.$cache->getname();
181 }
182
183 //Returns the content
184 public function getcontent()
185 {
186 //Restore the full content
187 if(!empty($this->restofcontent))
188 {
189 $this->content .= $this->restofcontent;
190 $this->restofcontent = '';
191 }
192
193 //Add the scripts
194 $bodyreplacement = implode('',$this->move['first']);
195 $bodyreplacement .= '<script type="text/javascript" src="'.$this->url.'"></script>';
196 $bodyreplacement .= implode('',$this->move['last']).'</body>';
197 $this->content = str_replace('</body>',$bodyreplacement,$this->content);
198
199 //Return the modified HTML
200 return $this->content;
201 }
202
203 //Checks agains the whitelist
204 private function ismergeable($tag)
205 {
206 foreach($this->domove as $match)
207 {
208 if(strpos($tag,$match)!==false)
209 {
210 //Matched something
211 return false;
212 }
213 }
214
215 foreach($this->dontmove as $match)
216 {
217 if(strpos($tag,$match)!==false)
218 {
219 //Matched something
220 return false;
221 }
222 }
223
224 //If we're here it's safe to merge
225 return true;
226 }
227
228 //Checks agains the blacklist
229 private function ismovable($tag)
230 {
231
232 foreach($this->domove as $match)
233 {
234 if(strpos($tag,$match)!==false)
235 {
236 //Matched something
237 return true;
238 }
239 }
240
241 foreach($this->dontmove as $match)
242 {
243 if(strpos($tag,$match)!==false)
244 {
245 //Matched something
246 return false;
247 }
248 }
249
250 //If we're here it's safe to move
251 return true;
252 }
253
254 private function movetolast($tag)
255 {
256 foreach($this->domovelast as $match)
257 {
258 if(strpos($tag,$match)!==false)
259 {
260 //Matched, return true
261 return true;
262 }
263 }
264
265 //Should be in 'first'
266 return false;
267 }
268 }
269