Completed
Push — v1.5 ( 5d3331...24344c )
by Andy
33:00 queued 23:00
created

class-minit.php ➔ minit_add_toc()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 3
nop 2
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
1
<?php
2
/*
3
Plugin Name: Minit
4
Plugin URI: https://github.com/kasparsd/minit
5
GitHub URI: https://github.com/kasparsd/minit
6
Description: Combine JS and CSS files and serve them from the uploads folder.
7
Version: 1.2
8
Author: Kaspars Dambis
9
Author URI: http://kaspars.net
10
*/
11
namespace UsabilityDynamics\AMD {
12
13
  $minit_instance = Minit::instance();
14
15
  class Minit {
16
17
    protected $minit_done = array();
18
    protected $async_queue = array();
19
20
    private function __construct() {
21
22
      // called once in header and once in footer
23
      add_filter( 'print_scripts_array', array( $this, 'init_minit_js' ) );
24
      add_filter( 'print_styles_array', array( $this, 'init_minit_css' ) );
25
26
      // Print external scripts asynchronously in the footer
27
      add_action( 'wp_print_footer_scripts', array( $this, 'async_init' ), 5 );
28
      add_action( 'wp_print_footer_scripts', array( $this, 'async_print' ), 20 );
29
30
      add_filter( 'script_loader_tag', array( $this, 'script_tag_async' ), 20, 3 );
31
32
    }
33
34
    public static function instance() {
35
36
      static $instance;
37
38
      if( !$instance )
39
        $instance = new Minit();
40
      
41
42
      // By default minit puts everything into footer, which causes issues with dependencies.
43
      add_filter( 'minit-js-in-footer', '__return_false' );
44
      
45
      // We disable all caching. 
46
      add_filter( 'minit-use-cache', '__return_false' );
47
      
48
      // Disable using the in-footer async thing.
49
      add_filter( 'minit-script-tag-async', '__return_false' );
50
      
51
      // Disables caching, although still writes to disk.
52
      add_filter( 'minit-cache-expiration', function() { return 0; });
53
      
54
55
      return $instance;
56
57
    }
58
59 View Code Duplication
    function init_minit_js( $todo ) {
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...
Duplication introduced by
This method seems to be duplicated in 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...
60
61
      global $wp_scripts;
62
63
      if( did_action( 'get_footer' ) ) {
64
        return $this->minit_objects( $wp_scripts, $todo, 'js', 'footer' );
65
      } else {
66
        return $this->minit_objects( $wp_scripts, $todo, 'js', 'header' );
67
      }
68
69
    }
70
71 View Code Duplication
    function init_minit_css( $todo ) {
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...
Duplication introduced by
This method seems to be duplicated in 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...
72
      global $wp_styles;
73
74
      if( did_action( 'get_footer' ) ) {
75
        return $this->minit_objects( $wp_styles, $todo, 'css', 'footer' );
76
      } else {
77
        return $this->minit_objects( $wp_styles, $todo, 'css', 'header' );
78
      }
79
80
    }
81
82
    /**
83
     * @param $object
84
     * @param $todo
85
     * @param $extension
86
     * @param $where
87
     * @return array
88
     */
89
    function minit_objects( &$object, $todo, $extension, $where ) {
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...
90
      global $wp_scripts;
91
92
      // Don't run if on admin or already processed
93
      if( is_admin() || empty( $todo ) )
94
        return $todo;
95
96
      if( $where === 'header' && $extension == 'js' ) {
97
        //die( '<pre>' . print_r( $wp_scripts->groups[], true ) . '</pre>' );
98
        //die( '<pre>' . print_r( $todo, true ) . '</pre>' );
99
      }
100
      // Allow files to be excluded from Minit
101
      $minit_exclude = apply_filters( 'minit-exclude-' . $extension, array() );
102
103
      // Not just exclude but actually drop files.
104
      $minit_drop = apply_filters( 'minit-drop-' . $extension, array() );
105
106
      if( !is_array( $minit_exclude ) )
107
        $minit_exclude = array();
108
109
      // Exluce all minit items by default. When ran in footer i
110
      $minit_exclude = array_merge( $minit_exclude, $this->get_done() );
111
112
      if( $where === 'header' && $extension == 'js' ) {
113
        // die( '<pre>$minit_todo ' . print_r( $todo, true ) . '</pre>' );
114
      }
115
116
      foreach( $todo as $_handle ) {
117
        if( isset( $wp_scripts->groups[ $_handle ] ) && $wp_scripts->groups[ $_handle ] === 1 && $where === 'header' ) {
118
          $minit_exclude[] = $_handle;
119
        }
120
      }
121
122
      if( $where === 'header' && $extension == 'js' ) {
123
        // die( '<pre>$minit_exclude ' . print_r( $minit_exclude, true ) . '</pre>' );
124
      }
125
126
      // echo( '<pre> minit todo ' . $extension . ' - ' . $where . ' - ' . print_r( $todo, true ) . '</pre>' );
127
      $minit_todo = array_diff( $todo, $minit_exclude );
128
129
      if( $where === 'header' && $extension == 'js' ) {
130
        //die( '<pre>$minit_todo ' . print_r( $minit_todo, true ) . '</pre>' );
131
      }
132
133
      if( empty( $minit_todo ) )
134
        return $todo;
135
136
      $done = array();
137
      $ver = array();
138
      $included_scripts = array();
139
140
      // Bust cache on Minit plugin update
141
      $ver[] = 'minit-ver-1.2';
142
143
      // Debug enable
144
      // if ( defined( 'WP_DEBUG' ) && WP_DEBUG )
145
      //	$ver[] = 'debug-' . time();
146
147
      // Use different cache key for SSL and non-SSL
148
      $ver[] = 'is_ssl-' . is_ssl();
149
150
      // Use a global cache version key to purge cache
151
      $ver[] = 'minit_cache_ver-' . get_option( 'minit_cache_ver' );
152
153
      // Drop select files.
154
      foreach( (array)$minit_drop as $_to_drop ) {
155
        if( ( $key = array_search( $_to_drop, $minit_todo ) ) !== false ) {
156
          unset( $minit_todo[ $key ] );
157
        }
158
      }
159
      //if( $where === 'header' ) {die( '<pre>' . print_r( $minit_todo, true ) . '</pre>' );//}
160
161
      // Use script version to generate a cache key
162
      foreach( $minit_todo as $t => $script ) {
163
        $ver[] = sprintf( '%s-%s', $script, $object->registered[ $script ]->ver );
164
        $included_scripts[] = $script;
165
      }
166
167
      // allow for version override.
168
      $ver = apply_filters( 'minit-build-ver', $ver, $extension );
169
170
      $cache_ver = md5( 'minit-' . implode( '-', $ver ) . $extension );
171
172
      $cache_ver = apply_filters( 'minit-ver-tag-' . $extension, $cache_ver, $included_scripts );
173
174
      // Try to get queue from cache
175
      if( $_use_cache = apply_filters( 'minit-use-cache', true ) ) {
0 ignored issues
show
Unused Code introduced by
$_use_cache is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
176
        $cache = get_transient( 'minit-' . $cache_ver );
177
      }
178
179
      if( isset( $cache[ 'cache_ver' ] ) && $cache[ 'cache_ver' ] == $cache_ver && file_exists( $cache[ 'file' ] ) )
180
        return $this->minit_enqueue_files( $object, $cache, $where );
181
182
      Minit::console_log( array(
183
        "where" => $where,
184
        "data" => $minit_todo
185
      ) );
186
187
      $_paths_used = array();
188
      $_modified_times = array();
189
190
      foreach( $minit_todo as $script ) {
191
192
        // Get the relative URL of the asset
193
        $src = self::get_asset_relative_path( $object->base_url, $object->registered[ $script ]->src );
194
195
        // Add support for pseudo packages such as jquery which return src as empty string
196
        if( empty( $object->registered[ $script ]->src ) || '' == $object->registered[ $script ]->src )
197
          $done[ $script ] = null;
198
199
        // Skip if the file is not hosted locally
200
        if( !$src || !file_exists( ABSPATH . $src ) )
201
          continue;
202
203
        $script_content = apply_filters( 'minit-item-' . $extension, file_get_contents( ABSPATH . $src ), $object, $script );
204
        $_paths_used[] = ABSPATH . $src;
205
206
        $_modified_times[ $src ] = filemtime( ABSPATH . $src );
207
208
        if( false !== $script_content )
209
          $done[ $script ] = $script_content;
210
211
      }
212
213
      if( empty( $done ) )
214
        return $todo;
215
216
      $wp_upload_dir = wp_upload_dir();
217
218
      // Try to create the folder for cache
219
      if( !is_dir( $wp_upload_dir[ 'basedir' ] . '/minit' ) )
220
        if( !mkdir( $wp_upload_dir[ 'basedir' ] . '/minit' ) )
221
          return $todo;
222
223
      // Use highest modified time.
224
      if( is_array( $_modified_times ) ) {
225
        $cache_ver = $cache_ver . '-' . md5( max( $_modified_times ) );
226
      }
227
228
      $combined_file_path = sprintf( apply_filters( 'minit-file-pattern', '%s/minit/%s.%s', $extension, $where, $_modified_times ), $wp_upload_dir[ 'basedir' ], $cache_ver, $extension );
229
      $combined_file_url = sprintf( apply_filters( 'minit-file-pattern', '%s/minit/%s.%s', $extension, $where, $_modified_times ), $wp_upload_dir[ 'baseurl' ], $cache_ver, $extension );
230
231
      if( isset( $where ) && $where === 'header' && $extension === 'js' ) {
232
        // die( '<pre>' . print_r( $_modified_times, true ) . '</pre>' );
233
        // die( '<pre>' . print_r( array( 'where' => $where, '$extension' => $extension, '$combined_file_url' => $combined_file_url  ), true ) . '</pre>' );
234
      }
235
236
      // Allow other plugins to do something with the resulting URL
237
      $combined_file_url = apply_filters( 'minit-url-' . $extension, $combined_file_url, $done );
238
239
      // Allow other plugins to minify and obfuscate
240
      $done_imploded = apply_filters( 'minit-content-' . $extension, implode( "\n\n", $done ), $done );
241
242
      // Store the combined file on the filesystem
243
      if( !file_exists( $combined_file_path ) )
244
        if( !file_put_contents( $combined_file_path, $done_imploded ) )
245
          return $todo;
246
247
      $status = array(
248
        'cache_ver' => $cache_ver,
249
        'todo' => $todo,
250
        'done' => array_keys( $done ),
251
        'url' => $combined_file_url,
252
        'file' => $combined_file_path,
253
        'extension' => $extension
254
      );
255
256
      if( $_use_cache = apply_filters( 'minit-use-cache', true ) ) {
0 ignored issues
show
Unused Code introduced by
$_use_cache is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
257
        // Cache this set of scripts, by default for 24 hours
258
        $cache_expiration = apply_filters( 'minit-cache-expiration', 24 * 60 * 60 );
259
        set_transient( 'minit-' . $cache_ver, $status, $cache_expiration );
260
      }
261
262
      $this->set_done( $cache_ver );
263
264
      return $this->minit_enqueue_files( $object, $status, $where );
265
266
    }
267
268
    /**
269
     * @param $message
270
     */
271
    function console_log( $message ) {
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...
272
273
      if( is_array( $message ) ) {
274
        $message = json_encode( $message );
275
      } else {
276
        $message = '"' . $message . '"';
277
      }
278
279
      if( defined( 'WP_DEBUG_MINIT' ) && WP_DEBUG_MINIT ) {
280
        echo "<script type='text/javascript'>console.log('minit'," . $message . ");</script>";
281
      }
282
283
    }
284
285
    function minit_enqueue_files( &$object, $status, $where ) {
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...
286
287
      extract( $status );
288
289
      Minit::console_log( "minit_enqueue_files " . ' ' . $extension . ' ' . $where );
290
291
      //$minit_exclude = (array)apply_filters( 'minit-exclude-js', array() );
292
293
      switch( $extension ) {
294
295
        case 'css':
296
297
          wp_enqueue_style( 'minit-' . $cache_ver, $url, null, null );
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
298
299
          // Add inline styles for all minited styles
300
          foreach( $done as $script ) {
301
302
            $inline_style = $object->get_data( $script, 'after' );
303
304
            if( empty( $inline_style ) )
305
              continue;
306
307
            if( is_string( $inline_style ) )
308
              $object->add_inline_style( 'minit-' . $cache_ver, $inline_style );
309
            elseif( is_array( $inline_style ) )
310
              $object->add_inline_style( 'minit-' . $cache_ver, implode( ' ', $inline_style ) );
311
312
          }
313
314
          break;
315
316
        case 'js':
317
318
          wp_enqueue_script( 'minit-' . $cache_ver, $url, null, null, apply_filters( 'minit-js-in-footer', $where == 'footer' ? true : false ) );
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
319
320
          // Add to the correct
321
          $object->set_group( 'minit-' . $cache_ver, false, apply_filters( 'minit-js-in-footer', $where == 'footer' ? true : false ) );
322
323
          $inline_data = array();
324
325
          // Add inline scripts for all minited scripts
326
          foreach( $done as $script )
327
            $inline_data[] = $object->get_data( $script, 'data' );
328
329
          // Filter out empty elements
330
          $inline_data = array_filter( $inline_data );
331
332
          if( !empty( $inline_data ) )
333
            $object->add_data( 'minit-' . $cache_ver, 'data', implode( "\n", $inline_data ) );
334
335
          break;
336
337
        default:
338
339
          return $todo;
340
341
      }
342
343
      // Remove scripts that were merged
344
      $todo = array_diff( $todo, $done );
345
346
      $todo[] = 'minit-' . $cache_ver;
347
348
      // Mark these items as done
349
      $object->done = array_merge( $object->done, $done );
350
351
      // Remove Minit items from the queue
352
      $object->queue = array_diff( $object->queue, $done );
353
354
      return $todo;
355
356
    }
357
358
    function set_done( $handle ) {
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...
359
360
      $this->minit_done[] = 'minit-' . $handle;
361
362
    }
363
364
    function get_done() {
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...
365
366
      return $this->minit_done;
367
368
    }
369
370
    public static function get_asset_relative_path( $base_url, $item_url ) {
371
372
      // Remove protocol reference from the local base URL
373
      $base_url = preg_replace( '/^(https?:\/\/|\/\/)/i', '', $base_url );
374
375
      // Check if this is a local asset which we can include
376
      $src_parts = explode( $base_url, $item_url );
377
378
      // Get the trailing part of the local URL
379
      $maybe_relative = end( $src_parts );
380
381
      if( !file_exists( ABSPATH . $maybe_relative ) )
382
        return false;
383
384
      return $maybe_relative;
385
386
    }
387
388
    public function async_init() {
389
390
      global $wp_scripts;
391
392
      if( !is_object( $wp_scripts ) || empty( $wp_scripts->queue ) )
393
        return;
394
395
      $base_url = site_url();
396
      $minit_exclude = (array)apply_filters( 'minit-exclude-js', array() );
397
398
      foreach( $wp_scripts->queue as $handle ) {
399
400
        // Skip asyncing explicitly excluded script handles
401
        if( in_array( $handle, $minit_exclude ) ) {
402
          continue;
403
        }
404
405
        $script_relative_path = Minit::get_asset_relative_path(
406
          $base_url,
407
          $wp_scripts->registered[ $handle ]->src
408
        );
409
410
        if( !$script_relative_path ) {
411
          // Add this script to our async queue
412
          $this->async_queue[] = $handle;
413
414
          // Remove this script from being printed the regular way
415
          wp_dequeue_script( $handle );
416
        }
417
418
      }
419
420
    }
421
422
    public function async_print() {
423
424
      global $wp_scripts;
425
426
      if( empty( $this->async_queue ) )
427
        return;
428
429
      // Disable the actual async..
430
      if( !apply_filters( 'minit-js-footer-async', true ) ) {
431
        return;
432
      }
433
434
      // Seems to be adding "head" script twice. Adding this to prevent.
435
      if( !apply_filters( 'minit-js-in-footer', true ) ) {
436
        return;
437
      }
438
439
      ?>
440
      <!-- Asynchronous scripts by Minit -->
441
      <script id="minit-async-scripts" type="text/javascript">
442
      (function () {
443
        var js, fjs = document.getElementById( 'minit-async-scripts' ),
444
          add = function ( url, id ) {
445
            js = document.createElement( 'script' );
446
            js.type = 'text/javascript';
447
            js.src = url;
448
            js.async = true;
449
            js.id = id;
450
            fjs.parentNode.insertBefore( js, fjs );
451
          };
452
        <?php
453
        foreach( $this->async_queue as $handle ) {
454
          printf(
455
            'add("%s", "%s"); ',
456
            $wp_scripts->registered[ $handle ]->src,
457
            'async-script-' . esc_attr( $handle )
458
          );
459
        }
460
        ?>
461
      })();
462
    </script>
463
      <?php
464
465
    }
466
467
    public function script_tag_async( $tag, $handle, $src ) {
0 ignored issues
show
Unused Code introduced by
The parameter $src is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
468
469
      // Allow others to disable this feature
470
      if( !apply_filters( 'minit-script-tag-async', true ) )
471
        return $tag;
472
473
      // Do this for minit scripts only
474
      if( false === stripos( $handle, 'minit-' ) )
475
        return $tag;
476
477
      // Bail if async is already set
478
      if( false !== stripos( $tag, ' async' ) )
479
        return $tag;
480
481
      // return str_ireplace( '<script ', '<script async ', $tag );
482
      return str_ireplace( '<script ', '<script ', $tag );
483
484
    }
485
486
  }
487
488
// Prepend the filename of the file being included
489
  add_filter( 'minit-item-css', 'UsabilityDynamics\AMD\minit_comment_combined', 15, 3 );
490
  add_filter( 'minit-item-js', 'UsabilityDynamics\AMD\minit_comment_combined', 15, 3 );
491
492
  function minit_comment_combined( $content, $object, $script ) {
493
494
    if( !$content )
495
      return $content;
496
497
    return sprintf(
498
      "\n\n/* Minit: %s */\n",
499
      $object->registered[ $script ]->src
500
    ) . $content;
501
502
  }
503
504
// Add table of contents at the top of the Minit file
505
  add_filter( 'minit-content-css', 'UsabilityDynamics\AMD\minit_add_toc', 100, 2 );
506
  add_filter( 'minit-content-js', 'UsabilityDynamics\AMD\minit_add_toc', 100, 2 );
507
508
  function minit_add_toc( $content, $items ) {
509
510
    if( !$content || empty( $items ) )
511
      return $content;
512
513
    $toc = array();
514
515
    foreach( $items as $handle => $item_content )
516
      $toc[] = sprintf( ' - %s', $handle );
517
518
    return sprintf( "/* TOC: " . time() . "\n%s\n*/", implode( "\n", $toc ) ) . $content;
519
520
  }
521
522
// Turn all local asset URLs into absolute URLs
523
  add_filter( 'minit-item-css', 'UsabilityDynamics\AMD\minit_resolve_css_urls', 10, 3 );
524
525 View Code Duplication
  function minit_resolve_css_urls( $content, $object, $script ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in 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...
526
527
    if( !$content )
528
      return $content;
529
530
    $src = Minit::get_asset_relative_path(
531
      $object->base_url,
532
      $object->registered[ $script ]->src
533
    );
534
535
    // Make all local asset URLs absolute
536
    $content = preg_replace(
537
      '/url\(["\' ]?+(?!data:|https?:|\/\/)(.*?)["\' ]?\)/i',
538
      sprintf( "url('%s/$1')", $object->base_url . dirname( $src ) ),
539
      $content
540
    );
541
542
    return $content;
543
544
  }
545
546
// Add support for relative CSS imports
547
  add_filter( 'minit-item-css', 'UsabilityDynamics\AMD\minit_resolve_css_imports', 10, 3 );
548
549 View Code Duplication
  function minit_resolve_css_imports( $content, $object, $script ) {
0 ignored issues
show
Duplication introduced by
This function seems to be duplicated in 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...
550
551
    if( !$content )
552
      return $content;
553
554
    $src = Minit::get_asset_relative_path(
555
      $object->base_url,
556
      $object->registered[ $script ]->src
557
    );
558
559
    // Make all import asset URLs absolute
560
    $content = preg_replace(
561
      '/@import\s+(url\()?["\'](?!https?:|\/\/)(.*?)["\'](\)?)/i',
562
      sprintf( "@import url('%s/$2')", $object->base_url . dirname( $src ) ),
563
      $content
564
    );
565
566
    return $content;
567
568
  }
569
570
// Exclude styles with media queries from being included in Minit
571
  add_filter( 'minit-item-css', 'UsabilityDynamics\AMD\minit_exclude_css_with_media_query', 10, 3 );
572
573
  function minit_exclude_css_with_media_query( $content, $object, $script ) {
574
575
    if( !$content )
576
      return $content;
577
578
    $whitelist = array( '', 'all', 'screen' );
579
580
    // Exclude from Minit if media query specified
581
    if( !in_array( $object->registered[ $script ]->args, $whitelist ) )
582
      return false;
583
584
    return $content;
585
586
  }
587
588
// Make sure that all Minit files are served from the correct protocol
589
  add_filter( 'minit-url-css', 'UsabilityDynamics\AMD\minit_maybe_ssl_url' );
590
  add_filter( 'minit-url-js', 'UsabilityDynamics\AMD\minit_maybe_ssl_url' );
591
592
  function minit_maybe_ssl_url( $url ) {
593
594
    if( is_ssl() )
595
      return str_replace( 'http://', 'https://', $url );
596
597
    return $url;
598
599
  }
600
601
// Add a Purge Cache link to the plugin list
602
  add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'UsabilityDynamics\AMD\minit_cache_purge_admin_link' );
603
604
  function minit_cache_purge_admin_link( $links ) {
605
606
    $links[] = sprintf(
607
      '<a href="%s">%s</a>',
608
      wp_nonce_url( add_query_arg( 'purge_minit', true ), 'purge_minit' ),
609
      __( 'Purge cache', 'minit' )
610
    );
611
612
    return $links;
613
614
  }
615
616
  /**
617
   * Maybe purge minit cache
618
   */
619
  add_action( 'admin_init', 'purge_minit_cache' );
620
621
  function purge_minit_cache() {
622
623
    if( !isset( $_GET[ 'purge_minit' ] ) )
624
      return;
625
626
    if( !check_admin_referer( 'purge_minit' ) )
627
      return;
628
629
    // Use this as a global cache version number
630
    update_option( 'minit_cache_ver', time() );
631
632
    add_action( 'admin_notices', 'UsabilityDynamics\AMD\minit_cache_purged_success' );
633
634
    // Allow other plugins to know that we purged
635
    do_action( 'minit-cache-purged' );
636
637
  }
638
639
  function minit_cache_purged_success() {
640
641
    printf(
642
      '<div class="updated"><p>%s</p></div>',
643
      __( 'Success: Minit cache purged.', 'minit' )
644
    );
645
646
  }
647
648
// This can used from cron to delete all Minit cache files
649
  add_action( 'minit-cache-purge-delete', 'UsabilityDynamics\AMD\minit_cache_delete_files' );
650
651
  function minit_cache_delete_files() {
652
653
    $wp_upload_dir = wp_upload_dir();
654
    $minit_files = glob( $wp_upload_dir[ 'basedir' ] . '/minit/*' );
655
656
    if( $minit_files ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $minit_files of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
657
      foreach( $minit_files as $minit_file ) {
658
        unlink( $minit_file );
659
      }
660
    }
661
662
  }
663
664
  /* Set timestamp for Minit */
665
  function minit_timestamp() {
666
    if( isset( $_GET[ "minitflush" ] ) || ( ( isset( $_SERVER[ 'HTTP_X_ACCESS_TOKEN' ] ) && $_SERVER[ 'HTTP_X_ACCESS_TOKEN' ] == 'yhcwokwserjzdjir' ) && ( isset( $_SERVER[ 'HTTP_X_MINIT_FLUSH' ] ) && $_SERVER[ 'HTTP_X_MINIT_FLUSH' ] == true ) ) ) {
667
      update_option( 'minit_timestamp', time() );
668
      $time = get_option( 'minit_timestamp' );
669
    } else {
670
      if( get_option( 'minit_timestamp' ) == true && get_option( 'minit_timestamp' ) !== '' ) {
671
        $time = get_option( 'minit_timestamp' );
672
      } else {
673
        $time = time();
674
      }
675
    }
676
    return $time;
677
  }
678
679
}