Completed
Push — master ( b4f20e...d72b5a )
by frank
02:16
created

classes/autoptimizeCache.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
3
4
class autoptimizeCache {
5
    private $filename;
6
    private $mime;
7
    private $cachedir;
8
    private $delayed;
9
    
10
    public function __construct($md5,$ext='php') {
11
        $this->cachedir = AUTOPTIMIZE_CACHE_DIR;
12
        $this->delayed = AUTOPTIMIZE_CACHE_DELAY;
13
        $this->nogzip = AUTOPTIMIZE_CACHE_NOGZIP;
14
        if($this->nogzip == false) {
15
            $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX.$md5.'.php';
16
        } else {
17
            if (in_array($ext, array("js","css")))     {
18
                $this->filename = $ext.'/'.AUTOPTIMIZE_CACHEFILE_PREFIX.$md5.'.'.$ext;
19
            } else {
20
                $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX.$md5.'.'.$ext;
21
            }
22
        }
23
    }
24
    
25
    public function check() {
26
        if(!file_exists($this->cachedir.$this->filename)) {
27
            // No cached file, sorry
28
            return false;
29
        }
30
        // Cache exists!
31
        return true;
32
    }
33
    
34
    public function retrieve() {
35
        if($this->check()) {
36
            if($this->nogzip == false) {
37
                return file_get_contents($this->cachedir.$this->filename.'.none');
38
            } else {
39
                return file_get_contents($this->cachedir.$this->filename);
40
            }
41
        }
42
        return false;
43
    }
44
    
45
    public function cache($code,$mime) {
46
        if($this->nogzip == false) {
47
            $file = ($this->delayed ? 'delayed.php' : 'default.php');
48
            $phpcode = file_get_contents(AUTOPTIMIZE_PLUGIN_DIR.'/config/'.$file);
49
            $phpcode = str_replace(array('%%CONTENT%%','exit;'),array($mime,''),$phpcode);
50
            file_put_contents($this->cachedir.$this->filename,$phpcode, LOCK_EX);
51
            file_put_contents($this->cachedir.$this->filename.'.none',$code, LOCK_EX);
52 View Code Duplication
            if(!$this->delayed) {
53
                // Compress now!
54
                file_put_contents($this->cachedir.$this->filename.'.deflate',gzencode($code,9,FORCE_DEFLATE), LOCK_EX);
55
                file_put_contents($this->cachedir.$this->filename.'.gzip',gzencode($code,9,FORCE_GZIP), LOCK_EX);
56
            }
57 View Code Duplication
        } else {
58
            // Write code to cache without doing anything else
59
            file_put_contents($this->cachedir.$this->filename,$code, LOCK_EX);
60
            if (apply_filters('autoptimize_filter_cache_create_static_gzip', false)) {
61
                // Create an additional cached gzip file
62
                file_put_contents($this->cachedir.$this->filename.'.gz', gzencode($code,9,FORCE_GZIP), LOCK_EX);
63
            }
64
        }
65
    }
66
    
67
    public function getname() {
68
        apply_filters('autoptimize_filter_cache_getname',AUTOPTIMIZE_CACHE_URL.$this->filename);
69
        return $this->filename;
70
    }
71
    
72
    static function clearall() {
73
        if(!autoptimizeCache::cacheavail()) {
74
            return false;
75
        }
76
    
77
        // scan the cachedirs        
78 View Code Duplication
        foreach (array("","js","css") as $scandirName) {
79
            $scan[$scandirName] = scandir(AUTOPTIMIZE_CACHE_DIR.$scandirName);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$scan was never initialized. Although not strictly required by PHP, it is generally a good practice to add $scan = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
80
        }
81
        
82
        // clear the cachedirs
83
        foreach ($scan as $scandirName=>$scanneddir) {
84
            $thisAoCacheDir=rtrim(AUTOPTIMIZE_CACHE_DIR.$scandirName,"/")."/";
85
            foreach($scanneddir as $file) {
86
                if(!in_array($file,array('.','..')) && strpos($file,AUTOPTIMIZE_CACHEFILE_PREFIX) !== false && is_file($thisAoCacheDir.$file)) {
87
                    @unlink($thisAoCacheDir.$file);
88
                }
89
            }
90
        }
91
92
        @unlink(AUTOPTIMIZE_CACHE_DIR."/.htaccess");
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
93
        delete_transient("autoptimize_stats");
94
95
        // add cachepurged action 
96
        if (!function_exists('autoptimize_do_cachepurged_action')) {
97
            function autoptimize_do_cachepurged_action() {
98
                do_action("autoptimize_action_cachepurged");
99
            }
100
        }
101
        add_action("shutdown","autoptimize_do_cachepurged_action",11);
102
        
103
        // try to purge caching plugins cache-files?
104
        include_once(AUTOPTIMIZE_PLUGIN_DIR.'classlesses/autoptimizePageCacheFlush.php');
105
        add_action("autoptimize_action_cachepurged","autoptimize_flush_pagecache",10,0);
106
107
        // warm cache (part of speedupper)?
108
        if ( apply_filters('autoptimize_filter_speedupper', true) ) {
109
            $warmCacheUrl = site_url()."/?ao_speedup_cachebuster=".rand(1,100000);
110
            $warmCache = @wp_remote_get($warmCacheUrl);
111
            unset($warmCache);
112
        }
113
114
        return true;
115
    }
116
117
    static function stats()    {
118
        $AOstats=get_transient("autoptimize_stats");
119
120
        if (empty($AOstats)) {
121
            // Cache not available :(
122
            if(!autoptimizeCache::cacheavail()) {
123
                return 0;
124
            }
125
            
126
            // Count cached info
127
            $count = 0;
128
            $size = 0;
129
            
130
            // scan the cachedirs        
131 View Code Duplication
            foreach (array("","js","css") as $scandirName) {
132
                $scan[$scandirName] = scandir(AUTOPTIMIZE_CACHE_DIR.$scandirName);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$scan was never initialized. Although not strictly required by PHP, it is generally a good practice to add $scan = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
133
            }
134
            
135
            foreach ($scan as $scandirName=>$scanneddir) {
136
                $thisAoCacheDir=rtrim(AUTOPTIMIZE_CACHE_DIR.$scandirName,"/")."/";
137
                foreach($scanneddir as $file) {
138
                    if(!in_array($file,array('.','..')) && strpos($file,AUTOPTIMIZE_CACHEFILE_PREFIX) !== false) {
139
                        if(is_file($thisAoCacheDir.$file)) {
140
                            if(AUTOPTIMIZE_CACHE_NOGZIP && (strpos($file,'.js') !== false || strpos($file,'.css') !== false || strpos($file,'.img') !== false || strpos($file,'.txt') !== false )) {
141
                                $count++;
142
                            } elseif(!AUTOPTIMIZE_CACHE_NOGZIP && strpos($file,'.none') !== false) {
143
                                $count++;
144
                            }
145
                            $size+=filesize($thisAoCacheDir.$file);
146
                        }
147
                    }
148
                }
149
            }
150
            $AOstats=array($count,$size,time());
151
            if ($count>100) {
152
                set_transient( "autoptimize_stats", $AOstats, apply_filters( 'autoptimize_filter_cache_statsexpiry', HOUR_IN_SECONDS ) );
153
            }
154
        }
155
        // print the number of instances
156
        return $AOstats;
157
    }    
158
159
    static function cacheavail() {
160
        if(!defined('AUTOPTIMIZE_CACHE_DIR')) {
161
            // We didn't set a cache
162
            return false;
163
        }
164
        
165
        foreach (array("","js","css") as $checkDir) {
166
            if(!autoptimizeCache::checkCacheDir(AUTOPTIMIZE_CACHE_DIR.$checkDir)) {
167
                return false;
168
            }
169
        }
170
        
171
        /** write index.html here to avoid prying eyes */
172
        $indexFile=AUTOPTIMIZE_CACHE_DIR.'/index.html';
173
        if(!is_file($indexFile)) {
174
            @file_put_contents($indexFile,'<html><head><meta name="robots" content="noindex, nofollow"></head><body>Generated by <a href="http://wordpress.org/extend/plugins/autoptimize/" rel="nofollow">Autoptimize</a></body></html>');
175
        }
176
177
        /** write .htaccess here to overrule wp_super_cache */
178
        $htAccess=AUTOPTIMIZE_CACHE_DIR.'/.htaccess';
179
        if(!is_file($htAccess)) {
180
            /** 
181
             * create wp-content/AO_htaccess_tmpl with 
182
             * whatever htaccess rules you might need
183
             * if you want to override default AO htaccess
184
             */
185
            $htaccess_tmpl=WP_CONTENT_DIR."/AO_htaccess_tmpl";
186
            if (is_file($htaccess_tmpl)) { 
187
                $htAccessContent=file_get_contents($htaccess_tmpl);
188
            } else if (is_multisite() || AUTOPTIMIZE_CACHE_NOGZIP == false) {
189
                $htAccessContent='<IfModule mod_expires.c>
190
        ExpiresActive On
191
        ExpiresByType text/css A30672000
192
        ExpiresByType text/javascript A30672000
193
        ExpiresByType application/javascript A30672000
194
</IfModule>
195
<IfModule mod_headers.c>
196
    Header append Cache-Control "public, immutable"
197
</IfModule>
198
<IfModule mod_deflate.c>
199
        <FilesMatch "\.(js|css)$">
200
        SetOutputFilter DEFLATE
201
    </FilesMatch>
202
</IfModule>
203
<IfModule mod_authz_core.c>
204
    <Files *.php>
205
        Require all granted
206
    </Files>
207
</IfModule>
208
<IfModule !mod_authz_core.c>
209
    <Files *.php>
210
        Order allow,deny
211
        Allow from all
212
    </Files>
213
</IfModule>';
214
            } else {
215
                $htAccessContent='<IfModule mod_expires.c>
216
        ExpiresActive On
217
        ExpiresByType text/css A30672000
218
        ExpiresByType text/javascript A30672000
219
        ExpiresByType application/javascript A30672000
220
</IfModule>
221
<IfModule mod_headers.c>
222
    Header append Cache-Control "public, immutable"
223
</IfModule>
224
<IfModule mod_deflate.c>
225
    <FilesMatch "\.(js|css)$">
226
        SetOutputFilter DEFLATE
227
    </FilesMatch>
228
</IfModule>
229
<IfModule mod_authz_core.c>
230
    <Files *.php>
231
        Require all denied
232
    </Files>
233
</IfModule>
234
<IfModule !mod_authz_core.c>
235
    <Files *.php>
236
        Order deny,allow
237
        Deny from all
238
    </Files>
239
</IfModule>';
240
            }
241
            @file_put_contents($htAccess,$htAccessContent);
242
        }
243
244
        // All OK
245
        return true;
246
    }
247
248
    static function checkCacheDir($dir) {
249
        // Check and create if not exists
250
        if(!file_exists($dir))    {
251
            @mkdir($dir,0775,true);
252
            if(!file_exists($dir))    {
253
                return false;
254
            }
255
        }
256
257
        // check if we can now write
258
        if(!is_writable($dir))    {
259
            return false;
260
        }
261
262
        // and write index.html here to avoid prying eyes
263
        $indexFile=$dir.'/index.html';
264
        if(!is_file($indexFile)) {
265
            @file_put_contents($indexFile,'<html><head><meta name="robots" content="noindex, nofollow"></head><body>Generated by <a href="http://wordpress.org/extend/plugins/autoptimize/" rel="nofollow">Autoptimize</a></body></html>');
266
        }
267
        
268
        return true;
269
    }
270
}
271