Completed
Push — master ( 8e92fc...99555e )
by frank
02:12
created

autoptimizeCache::clearall_actionless()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Handles disk-cache-related operations.
4
 */
5
6
if ( ! defined( 'ABSPATH' ) ) {
7
    exit;
8
}
9
10
class autoptimizeCache
11
{
12
    /**
13
     * Cache filename.
14
     *
15
     * @var string
16
     */
17
    private $filename;
18
19
    /**
20
     * Cache directory path (with a trailing slash).
21
     *
22
     * @var string
23
     */
24
    private $cachedir;
25
26
    /**
27
     * Whether gzipping is done by the web server or us.
28
     * True => we don't gzip, the web server does it.
29
     * False => we do it ourselves.
30
     *
31
     * @var bool
32
     */
33
    private $nogzip;
34
35
    /**
36
     * Ctor.
37
     *
38
     * @param string $md5 Hash.
39
     * @param string $ext Extension.
40
     */
41
    public function __construct( $md5, $ext = 'php' )
42
    {
43
        $this->cachedir = AUTOPTIMIZE_CACHE_DIR;
44
        $this->nogzip   = AUTOPTIMIZE_CACHE_NOGZIP;
45
        if ( ! $this->nogzip ) {
46
            $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . '.php';
47
        } else {
48
            if ( in_array( $ext, array( 'js', 'css' ) ) ) {
49
                $this->filename = $ext . '/' . AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . '.' . $ext;
50
            } else {
51
                $this->filename = AUTOPTIMIZE_CACHEFILE_PREFIX . $md5 . '.' . $ext;
52
            }
53
        }
54
    }
55
56
    /**
57
     * Returns true if the cached file exists on disk.
58
     *
59
     * @return bool
60
     */
61
    public function check()
62
    {
63
        return file_exists( $this->cachedir . $this->filename );
64
    }
65
66
    /**
67
     * Returns cache contents if they exist, false otherwise.
68
     *
69
     * @return string|false
70
     */
71
    public function retrieve()
72
    {
73
        if ( $this->check() ) {
74
            if ( false == $this->nogzip ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
75
                return file_get_contents( $this->cachedir . $this->filename . '.none' );
76
            } else {
77
                return file_get_contents( $this->cachedir . $this->filename );
78
            }
79
        }
80
        return false;
81
    }
82
83
    /**
84
     * Stores given $data in cache.
85
     *
86
     * @param string $data Data to cache.
87
     * @param string $mime Mimetype.
88
     *
89
     * @return void
90
     */
91
    public function cache( $data, $mime )
92
    {
93
        if ( false === $this->nogzip ) {
94
            // We handle gzipping ourselves.
95
            $file    = 'default.php';
96
            $phpcode = file_get_contents( AUTOPTIMIZE_PLUGIN_DIR . 'config/' . $file );
97
            $phpcode = str_replace( array( '%%CONTENT%%', 'exit;' ), array( $mime, '' ), $phpcode );
98
99
            file_put_contents( $this->cachedir . $this->filename, $phpcode );
100
            file_put_contents( $this->cachedir . $this->filename . '.none', $data );
101
        } else {
102
            // Write code to cache without doing anything else.
103
            file_put_contents( $this->cachedir . $this->filename, $data );
104
            if ( apply_filters( 'autoptimize_filter_cache_create_static_gzip', false ) ) {
105
                // Create an additional cached gzip file.
106
                file_put_contents( $this->cachedir . $this->filename . '.gz', gzencode( $data, 9, FORCE_GZIP ) );
107
            }
108
        }
109
    }
110
111
    /**
112
     * Get cache filename.
113
     *
114
     * @return string
115
     */
116
    public function getname()
117
    {
118
        // NOTE: This could've maybe been a do_action() instead, however,
119
        // that ship has sailed.
120
        // The original idea here was to provide 3rd party code a hook so that
121
        // it can "listen" to all the complete autoptimized-urls that the page
122
        // will emit... Or something to that effect I think?
123
        apply_filters( 'autoptimize_filter_cache_getname', AUTOPTIMIZE_CACHE_URL . $this->filename );
124
125
        return $this->filename;
126
    }
127
128
    /**
129
     * Returns true if given `$file` is considered a valid Autoptimize cache file,
130
     * false otherwise.
131
     *
132
     * @param string $dir Directory name (with a trailing slash).
133
     * @param string $file Filename.
134
     * @return bool
135
     */
136
    protected static function is_valid_cache_file( $dir, $file )
137
    {
138
        if ( '.' !== $file && '..' !== $file &&
139
            false !== strpos( $file, AUTOPTIMIZE_CACHEFILE_PREFIX ) &&
140
            is_file( $dir . $file ) ) {
141
142
            // It's a valid file!
143
            return true;
144
        }
145
146
        // Everything else is considered invalid!
147
        return false;
148
    }
149
150
    /**
151
     * Clears contents of AUTOPTIMIZE_CACHE_DIR.
152
     *
153
     * @return void
154
     */
155
    protected static function clear_cache_classic()
156
    {
157
        $contents = self::get_cache_contents();
158
        foreach ( $contents as $name => $files ) {
159
            $dir = rtrim( AUTOPTIMIZE_CACHE_DIR . $name, '/' ) . '/';
160
            foreach ( $files as $file ) {
161
                if ( self::is_valid_cache_file( $dir, $file ) ) {
162
                    @unlink( $dir . $file ); // @codingStandardsIgnoreLine
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...
163
                }
164
            }
165
        }
166
167
        @unlink( AUTOPTIMIZE_CACHE_DIR . '/.htaccess' ); // @codingStandardsIgnoreLine
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...
168
    }
169
170
    /**
171
     * Recursively deletes the specified pathname (file/directory) if possible.
172
     * Returns true on success, false otherwise.
173
     *
174
     * @param string $pathname Pathname to remove.
175
     *
176
     * @return bool
177
     */
178
    protected static function rmdir( $pathname )
179
    {
180
        $files = self::get_dir_contents( $pathname );
181
        foreach ( $files as $file ) {
182
            $path = $pathname . '/' . $file;
183
            if ( is_dir( $path ) ) {
184
                self::rmdir( $path );
185
            } else {
186
                unlink( $path );
187
            }
188
        }
189
190
        return rmdir( $pathname );
191
    }
192
193
    /**
194
     * Clears contents of AUTOPTIMIZE_CACHE_DIR by renaming the current
195
     * cache directory into a new one with a unique name and then
196
     * re-creating the default (empty) cache directory.
197
     *
198
     * @return bool Returns true when everything is done successfully, false otherwise.
199
     */
200
    protected static function clear_cache_via_rename()
201
    {
202
        $ok       = false;
203
        $dir      = self::get_pathname_base();
204
        $new_name = self::get_unique_name();
205
206
        // Makes sure the new pathname is on the same level...
207
        $new_pathname = dirname( $dir ) . '/' . $new_name;
208
        $renamed      = @rename( $dir, $new_pathname ); // @codingStandardsIgnoreLine
209
210
        // When renamed, re-create the default cache directory back so it's
211
        // available again...
212
        if ( $renamed ) {
213
            $ok = self::cacheavail();
214
        }
215
216
        return $ok;
217
    }
218
219
    /**
220
     * Returns true when advanced cache clearing is enabled.
221
     *
222
     * @return bool
223
     */
224
    public static function advanced_cache_clear_enabled()
225
    {
226
        return apply_filters( 'autoptimize_filter_cache_clear_advanced', false );
227
    }
228
229
    /**
230
     * Returns a (hopefully) unique new cache folder name for renaming purposes.
231
     *
232
     * @return string
233
     */
234
    protected static function get_unique_name()
235
    {
236
        $prefix   = self::get_advanced_cache_clear_prefix();
237
        $new_name = uniqid( $prefix, true );
238
239
        return $new_name;
240
    }
241
242
    /**
243
     * Get cache prefix name used in advanced cache clearing mode.
244
     *
245
     * @return string
246
     */
247
    protected static function get_advanced_cache_clear_prefix()
248
    {
249
        $pathname = self::get_pathname_base();
250
        $basename = basename( $pathname );
251
        $prefix   = $basename . '-';
252
253
        return $prefix;
254
    }
255
256
    /**
257
     * Returns an array of file and directory names found within
258
     * the given $pathname without '.' and '..' elements.
259
     *
260
     * @param string $pathname Pathname.
261
     *
262
     * @return array
263
     */
264
    protected static function get_dir_contents( $pathname )
265
    {
266
        return array_slice( scandir( $pathname ), 2 );
267
    }
268
269
    /**
270
     * Wipes directories which were created as part of the fast cache clearing
271
     * routine (which renames the current cache directory into a new one with
272
     * a custom-prefixed unique name).
273
     *
274
     * @return bool
275
     */
276
    public static function delete_advanced_cache_clear_artifacts()
277
    {
278
        $dir    = self::get_pathname_base();
279
        $prefix = self::get_advanced_cache_clear_prefix();
280
        $parent = dirname( $dir );
281
        $ok     = false;
282
283
        // Returns the list of files without '.' and '..' elements.
284
        $files = self::get_dir_contents( $parent );
285
        if ( is_array( $files ) && ! empty( $files ) ) {
286
            foreach ( $files as $file ) {
287
                $path     = $parent . '/' . $file;
288
                $prefixed = ( false !== strpos( $path, $prefix ) );
289
                // Removing only our own (prefixed) directories...
290
                if ( is_dir( $path ) && $prefixed ) {
291
                    $ok = self::rmdir( $path );
292
                }
293
            }
294
        }
295
296
        return $ok;
297
    }
298
299
    /**
300
     * Returns the cache directory pathname used.
301
     * Done as a function so we canSlightly different
302
     * if multisite is used and `autoptimize_separate_blog_caches` filter
303
     * is used.
304
     *
305
     * @return string
306
     */
307
    public static function get_pathname()
308
    {
309
        $pathname = self::get_pathname_base();
310
311 View Code Duplication
        if ( is_multisite() && apply_filters( 'autoptimize_separate_blog_caches', true ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
312
            $blog_id   = get_current_blog_id();
313
            $pathname .= $blog_id . '/';
314
        }
315
316
        return $pathname;
317
    }
318
319
    /**
320
     * Returns the base path of our cache directory.
321
     *
322
     * @return string
323
     */
324
    protected static function get_pathname_base()
325
    {
326
        $pathname = WP_CONTENT_DIR . AUTOPTIMIZE_CACHE_CHILD_DIR;
327
328
        return $pathname;
329
    }
330
331
    /**
332
     * Deletes everything from the cache directories.
333
     *
334
     * @param bool $propagate Whether to trigger additional actions when cache is purged.
335
     *
336
     * @return bool
337
     */
338
    public static function clearall( $propagate = true )
339
    {
340
        if ( ! self::cacheavail() ) {
341
            return false;
342
        }
343
344
        // TODO/FIXME: If cache is big, switch to advanced/new cache clearing automatically?
345
        if ( self::advanced_cache_clear_enabled() ) {
346
            self::clear_cache_via_rename();
347
        } else {
348
            self::clear_cache_classic();
349
        }
350
351
        // Remove the transient so it gets regenerated...
352
        delete_transient( 'autoptimize_stats' );
353
354
        // Cache was just purged, clear page cache and allow others to hook into our purging...
355
        if ( true === $propagate ) {
356
            if ( ! function_exists( 'autoptimize_do_cachepurged_action' ) ) {
357
                function autoptimize_do_cachepurged_action() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
358
                    do_action( 'autoptimize_action_cachepurged' );
359
                }
360
            }
361
            add_action( 'shutdown', 'autoptimize_do_cachepurged_action', 11 );
362
            add_action( 'autoptimize_action_cachepurged', array( 'autoptimizeCache', 'flushPageCache' ), 10, 0 );
363
        }
364
365
        // Warm cache (part of speedupper)!
366
        if ( apply_filters( 'autoptimize_filter_speedupper', true ) ) {
367
            $url   = site_url() . '/?ao_speedup_cachebuster=' . rand( 1, 100000 );
368
            $cache = @wp_remote_get( $url ); // @codingStandardsIgnoreLine
369
            unset( $cache );
370
        }
371
372
        return true;
373
    }
374
375
    /**
376
     * Wrapper for clearall but with false param
377
     * to ensure the event is not propagated to others
378
     * through our own hooks (to avoid infinite loops).
379
     *
380
     * @return bool
381
     */
382
    public static function clearall_actionless()
383
    {
384
        return self::clearall( false );
385
    }
386
387
    /**
388
     * Returns the contents of our cache dirs.
389
     *
390
     * @return array
391
     */
392
    protected static function get_cache_contents()
393
    {
394
        $contents = array();
395
396
        foreach ( array( '', 'js', 'css' ) as $dir ) {
397
            $contents[ $dir ] = scandir( AUTOPTIMIZE_CACHE_DIR . $dir );
398
        }
399
400
        return $contents;
401
    }
402
403
    /**
404
     * Returns stats about cached contents.
405
     *
406
     * @return array
407
     */
408
    public static function stats()
409
    {
410
        $stats = get_transient( 'autoptimize_stats' );
411
412
        // If no transient, do the actual scan!
413
        if ( ! is_array( $stats ) ) {
414
            if ( ! self::cacheavail() ) {
415
                return 0;
416
            }
417
            $stats = self::stats_scan();
418
            $count = $stats[0];
419
            if ( $count > 100 ) {
420
                // Store results in transient.
421
                set_transient(
422
                    'autoptimize_stats',
423
                    $stats,
424
                    apply_filters( 'autoptimize_filter_cache_statsexpiry', HOUR_IN_SECONDS )
425
                );
426
            }
427
        }
428
429
        return $stats;
430
    }
431
432
    /**
433
     * Performs a scan of cache directory contents and returns an array
434
     * with 3 values: count, size, timestamp.
435
     * count = total number of found files
436
     * size = total filesize (in bytes) of found files
437
     * timestamp = unix timestamp when the scan was last performed/finished.
438
     *
439
     * @return array
440
     */
441
    protected static function stats_scan()
442
    {
443
        $count = 0;
444
        $size  = 0;
445
446
        // Scan everything in our cache directories.
447
        foreach ( self::get_cache_contents() as $name => $files ) {
448
            $dir = rtrim( AUTOPTIMIZE_CACHE_DIR . $name, '/' ) . '/';
449
            foreach ( $files as $file ) {
450
                if ( self::is_valid_cache_file( $dir, $file ) ) {
451
                    if ( AUTOPTIMIZE_CACHE_NOGZIP &&
452
                        (
453
                            false !== strpos( $file, '.js' ) ||
454
                            false !== strpos( $file, '.css' ) ||
455
                            false !== strpos( $file, '.img' ) ||
456
                            false !== strpos( $file, '.txt' )
457
                        )
458
                    ) {
459
                        // Web server is gzipping, we count .js|.css|.img|.txt files.
460
                        $count++;
461
                    } elseif ( ! AUTOPTIMIZE_CACHE_NOGZIP && false !== strpos( $file, '.none' ) ) {
462
                        // We are gzipping ourselves via php, counting only .none files.
463
                        $count++;
464
                    }
465
                    $size += filesize( $dir . $file );
466
                }
467
            }
468
        }
469
470
        $stats = array( $count, $size, time() );
471
472
        return $stats;
473
    }
474
475
    /**
476
     * Ensures the cache directory exists, is writeable and contains the
477
     * required .htaccess files.
478
     * Returns false in case it fails to ensure any of those things.
479
     *
480
     * @return bool
481
     */
482
    public static function cacheavail()
483
    {
484
        if ( ! defined( 'AUTOPTIMIZE_CACHE_DIR' ) ) {
485
            // We didn't set a cache.
486
            return false;
487
        }
488
489
        foreach ( array( '', 'js', 'css' ) as $dir ) {
490
            if ( ! self::check_cache_dir( AUTOPTIMIZE_CACHE_DIR . $dir ) ) {
491
                return false;
492
            }
493
        }
494
495
        // Using .htaccess inside our cache folder to overrule wp-super-cache.
496
        $htaccess = AUTOPTIMIZE_CACHE_DIR . '/.htaccess';
497
        if ( ! is_file( $htaccess ) ) {
498
            /**
499
             * Create `wp-content/AO_htaccess_tmpl` file with
500
             * whatever htaccess rules you might need
501
             * if you want to override default AO htaccess
502
             */
503
            $htaccess_tmpl = WP_CONTENT_DIR . '/AO_htaccess_tmpl';
504
            if ( is_file( $htaccess_tmpl ) ) {
505
                $content = file_get_contents( $htaccess_tmpl );
506
            } elseif ( is_multisite() || ! AUTOPTIMIZE_CACHE_NOGZIP ) {
507
                $content = '<IfModule mod_expires.c>
508
        ExpiresActive On
509
        ExpiresByType text/css A30672000
510
        ExpiresByType text/javascript A30672000
511
        ExpiresByType application/javascript A30672000
512
</IfModule>
513
<IfModule mod_headers.c>
514
    Header append Cache-Control "public, immutable"
515
</IfModule>
516
<IfModule mod_deflate.c>
517
        <FilesMatch "\.(js|css)$">
518
        SetOutputFilter DEFLATE
519
    </FilesMatch>
520
</IfModule>
521
<IfModule mod_authz_core.c>
522
    <Files *.php>
523
        Require all granted
524
    </Files>
525
</IfModule>
526
<IfModule !mod_authz_core.c>
527
    <Files *.php>
528
        Order allow,deny
529
        Allow from all
530
    </Files>
531
</IfModule>';
532
            } else {
533
                $content = '<IfModule mod_expires.c>
534
        ExpiresActive On
535
        ExpiresByType text/css A30672000
536
        ExpiresByType text/javascript A30672000
537
        ExpiresByType application/javascript A30672000
538
</IfModule>
539
<IfModule mod_headers.c>
540
    Header append Cache-Control "public, immutable"
541
</IfModule>
542
<IfModule mod_deflate.c>
543
    <FilesMatch "\.(js|css)$">
544
        SetOutputFilter DEFLATE
545
    </FilesMatch>
546
</IfModule>
547
<IfModule mod_authz_core.c>
548
    <Files *.php>
549
        Require all denied
550
    </Files>
551
</IfModule>
552
<IfModule !mod_authz_core.c>
553
    <Files *.php>
554
        Order deny,allow
555
        Deny from all
556
    </Files>
557
</IfModule>';
558
            }
559
            @file_put_contents( $htaccess, $content ); // @codingStandardsIgnoreLine
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...
560
        }
561
562
        // All OK!
563
        return true;
564
    }
565
566
    /**
567
     * Ensures the specified `$dir` exists and is writeable.
568
     * Returns false if that's not the case.
569
     *
570
     * @param string $dir Directory to check/create.
571
     *
572
     * @return bool
573
     */
574
    protected static function check_cache_dir( $dir )
575
    {
576
        // Try creating the dir if it doesn't exist.
577
        if ( ! file_exists( $dir ) ) {
578
            @mkdir( $dir, 0775, true ); // @codingStandardsIgnoreLine
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...
579
            if ( ! file_exists( $dir ) ) {
580
                return false;
581
            }
582
        }
583
584
        // If we still cannot write, bail.
585
        if ( ! is_writable( $dir ) ) {
586
            return false;
587
        }
588
589
        // Create an index.html in there to avoid prying eyes!
590
        $idx_file = rtrim( $dir, '/\\' ) . '/index.html';
591
        if ( ! is_file( $idx_file ) ) {
592
            @file_put_contents( $idx_file, '<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>' ); // @codingStandardsIgnoreLine
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...
593
        }
594
595
        return true;
596
    }
597
598
    /**
599
     * Flushes as many page cache plugin's caches as possible.
600
     *
601
     * @return void
602
     */
603
    // @codingStandardsIgnoreStart
604
    public static function flushPageCache()
605
    {
606
        if ( function_exists( 'wp_cache_clear_cache' ) ) {
607
            if ( is_multisite() ) {
608
                $blog_id = get_current_blog_id();
609
                wp_cache_clear_cache( $blog_id );
610
            } else {
611
                wp_cache_clear_cache();
612
            }
613
        } elseif ( has_action( 'cachify_flush_cache' ) ) {
614
            do_action( 'cachify_flush_cache' );
615
        } elseif ( function_exists( 'w3tc_pgcache_flush' ) ) {
616
            w3tc_pgcache_flush();
617
        } elseif ( function_exists( 'wp_fast_cache_bulk_delete_all' ) ) {
618
            wp_fast_cache_bulk_delete_all();
619
        } elseif ( class_exists( 'WpFastestCache' ) ) {
620
            $wpfc = new WpFastestCache();
621
            $wpfc->deleteCache();
622
        } elseif ( class_exists( 'c_ws_plugin__qcache_purging_routines' ) ) {
623
            c_ws_plugin__qcache_purging_routines::purge_cache_dir(); // quick cache
624
        } elseif ( class_exists( 'zencache' ) ) {
625
            zencache::clear();
626
        } elseif ( class_exists( 'comet_cache' ) ) {
627
            comet_cache::clear();
628
        } elseif ( class_exists( 'WpeCommon' ) ) {
629
            // WPEngine cache purge/flush methods to call by default
630
            $wpe_methods = array(
631
                'purge_varnish_cache',
632
            );
633
634
            // More agressive clear/flush/purge behind a filter
635
            if ( apply_filters( 'autoptimize_flush_wpengine_aggressive', false ) ) {
636
                $wpe_methods = array_merge( $wpe_methods, array( 'purge_memcached', 'clear_maxcdn_cache' ) );
637
            }
638
639
            // Filtering the entire list of WpeCommon methods to be called (for advanced usage + easier testing)
640
            $wpe_methods = apply_filters( 'autoptimize_flush_wpengine_methods', $wpe_methods );
641
642
            foreach ( $wpe_methods as $wpe_method ) {
643
                if ( method_exists( 'WpeCommon', $wpe_method ) ) {
644
                    WpeCommon::$wpe_method();
645
                }
646
            }
647
        } elseif ( function_exists( 'sg_cachepress_purge_cache' ) ) {
648
            sg_cachepress_purge_cache();
649
        } elseif ( file_exists( WP_CONTENT_DIR . '/wp-cache-config.php' ) && function_exists( 'prune_super_cache' ) ) {
650
            // fallback for WP-Super-Cache
651
            global $cache_path;
652
            if ( is_multisite() ) {
653
                $blog_id = get_current_blog_id();
654
                prune_super_cache( get_supercache_dir( $blog_id ), true );
655
                prune_super_cache( $cache_path . 'blogs/', true );
656
            } else {
657
                prune_super_cache( $cache_path . 'supercache/', true );
658
                prune_super_cache( $cache_path, true );
659
            }
660
        }
661
    }
662
    // @codingStandardsIgnoreEnd
663
}
664