Completed
Push — v1.5 ( cd46e3...80949e )
by Maxim
15:19 queued 07:45
created

Minit::log()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 4
nop 0
dl 0
loc 13
rs 9.4285
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::log( "In [$where] in to-do: " . join( ", ", array_values( $minit_todo )));
183
184
      $_paths_used = array();
185
      $_modified_times = array();
186
187
      foreach( $minit_todo as $script ) {
188
189
        // Get the relative URL of the asset
190
        $src = self::get_asset_relative_path( $object->base_url, $object->registered[ $script ]->src );
191
192
        // Add support for pseudo packages such as jquery which return src as empty string
193
        if( empty( $object->registered[ $script ]->src ) || '' == $object->registered[ $script ]->src )
194
          $done[ $script ] = null;
195
196
        // Skip if the file is not hosted locally
197
        if( !$src || !file_exists( ABSPATH . $src ) )
198
          continue;
199
200
        $script_content = apply_filters( 'minit-item-' . $extension, file_get_contents( ABSPATH . $src ), $object, $script );
201
        $_paths_used[] = ABSPATH . $src;
202
203
        $_modified_times[ $src ] = filemtime( ABSPATH . $src );
204
205
        if( false !== $script_content )
206
          $done[ $script ] = $script_content;
207
208
      }
209
210
      if( empty( $done ) )
211
        return $todo;
212
213
      $wp_upload_dir = wp_upload_dir();
214
215
      // Try to create the folder for cache
216
      if( !is_dir( $wp_upload_dir[ 'basedir' ] . '/minit' ) )
217
        if( !mkdir( $wp_upload_dir[ 'basedir' ] . '/minit' ) )
218
          return $todo;
219
220
      // Use highest modified time.
221
      if( is_array( $_modified_times ) ) {
222
        $_most_recent = max( $_modified_times );
223
        Minit::log( "For [$extension] in [$where] setting cache_ver from modified times, where [" . $_most_recent . "] is the latest, hash is [" . md5( $_most_recent ) . "]." );
224
        $cache_ver = $cache_ver . '-' . md5( $_most_recent );
225
      }
226
227
      $combined_file_path = sprintf( apply_filters( 'minit-file-pattern', '%s/minit/%s.%s', $extension, $where, $_modified_times ), $wp_upload_dir[ 'basedir' ], $cache_ver, $extension );
228
      $combined_file_url = sprintf( apply_filters( 'minit-file-pattern', '%s/minit/%s.%s', $extension, $where, $_modified_times ), $wp_upload_dir[ 'baseurl' ], $cache_ver, $extension );
229
230
      if( isset( $where ) && $where === 'header' && $extension === 'js' ) {
231
        // die( '<pre>' . print_r( $_modified_times, true ) . '</pre>' );
232
        // die( '<pre>' . print_r( array( 'where' => $where, '$extension' => $extension, '$combined_file_url' => $combined_file_url  ), true ) . '</pre>' );
233
      }
234
235
      // Allow other plugins to do something with the resulting URL
236
      $combined_file_url = apply_filters( 'minit-url-' . $extension, $combined_file_url, $done );
237
238
      // Allow other plugins to minify and obfuscate
239
      $done_imploded = apply_filters( 'minit-content-' . $extension, implode( "\n\n", $done ), $done );
240
241
      // Store the combined file on the filesystem
242
      if( !file_exists( $combined_file_path ) )
243
        if( !file_put_contents( $combined_file_path, $done_imploded ) )
244
          return $todo;
245
246
      $status = array(
247
        'cache_ver' => $cache_ver,
248
        'todo' => $todo,
249
        'done' => array_keys( $done ),
250
        'url' => $combined_file_url,
251
        'file' => $combined_file_path,
252
        'extension' => $extension
253
      );
254
255
      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...
256
        // Cache this set of scripts, by default for 24 hours
257
        $cache_expiration = apply_filters( 'minit-cache-expiration', 24 * 60 * 60 );
258
        set_transient( 'minit-' . $cache_ver, $status, $cache_expiration );
259
      }
260
261
      $this->set_done( $cache_ver );
262
263
      return $this->minit_enqueue_files( $object, $status, $where );
264
265
    }
266
267
    /**
268
     * Outputs to frontend console via ChromePhp.
269
     *
270
     */
271
    static public function log() {
272
273
      if( !class_exists( 'UsabilityDynamics\AMD\ChromePhp' ) ) {
274
        include (__DIR__ . '/class-chrome-php.php');
275
      }
276
277
      if( class_exists( 'UsabilityDynamics\AMD\ChromePhp' ) ) {
278
        $_args = func_get_args();
279
        array_unshift( $_args, "wp-amd:minit:" );
280
        call_user_func_array( array('UsabilityDynamics\AMD\ChromePhp', 'log' ), $_args );
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
      Minit::log( "minit_enqueue_files " . ' ' . $status['extension'] . ' ' . $where . " cache_ver: [" . $status['cache_ver'] . "]" );
288
289
      //$minit_exclude = (array)apply_filters( 'minit-exclude-js', array() );
290
291
      switch( $status['extension'] ) {
292
293
        case 'css':
294
295
          wp_enqueue_style( 'minit-' . $cache_ver, $url, null, null );
0 ignored issues
show
Bug introduced by
The variable $cache_ver does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The variable $url does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
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...
296
297
          // Add inline styles for all minited styles
298
          foreach( $done as $script ) {
0 ignored issues
show
Bug introduced by
The variable $done does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
299
300
            $inline_style = $object->get_data( $script, 'after' );
301
302
            if( empty( $inline_style ) )
303
              continue;
304
305
            if( is_string( $inline_style ) )
306
              $object->add_inline_style( 'minit-' . $cache_ver, $inline_style );
307
            elseif( is_array( $inline_style ) )
308
              $object->add_inline_style( 'minit-' . $cache_ver, implode( ' ', $inline_style ) );
309
310
          }
311
312
          break;
313
314
        case 'js':
315
316
          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...
317
318
          // Add to the correct
319
          $object->set_group( 'minit-' . $cache_ver, false, apply_filters( 'minit-js-in-footer', $where == 'footer' ? true : false ) );
320
321
          $inline_data = array();
322
323
          // Add inline scripts for all minited scripts
324
          foreach( $done as $script )
325
            $inline_data[] = $object->get_data( $script, 'data' );
326
327
          // Filter out empty elements
328
          $inline_data = array_filter( $inline_data );
329
330
          if( !empty( $inline_data ) )
331
            $object->add_data( 'minit-' . $cache_ver, 'data', implode( "\n", $inline_data ) );
332
333
          break;
334
335
        default:
336
337
          return $todo;
0 ignored issues
show
Bug introduced by
The variable $todo seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
338
339
      }
340
341
      // Remove scripts that were merged
342
      $todo = array_diff( $status['todo'], $status['done'] );
343
344
      $todo[] = 'minit-' . $cache_ver;
345
346
      // Mark these items as done
347
      $object->done = array_merge( $object->done, $done );
348
349
      // Remove Minit items from the queue
350
      $object->queue = array_diff( $object->queue, $done );
351
352
      return $todo;
353
354
    }
355
356
    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...
357
358
      $this->minit_done[] = 'minit-' . $handle;
359
360
    }
361
362
    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...
363
364
      return $this->minit_done;
365
366
    }
367
368
    public static function get_asset_relative_path( $base_url, $item_url ) {
369
370
      // Remove protocol reference from the local base URL
371
      $base_url = preg_replace( '/^(https?:\/\/|\/\/)/i', '', $base_url );
372
373
      // Check if this is a local asset which we can include
374
      $src_parts = explode( $base_url, $item_url );
375
376
      // Get the trailing part of the local URL
377
      $maybe_relative = end( $src_parts );
378
379
      if( !file_exists( ABSPATH . $maybe_relative ) )
380
        return false;
381
382
      return $maybe_relative;
383
384
    }
385
386
    public function async_init() {
387
      Minit::log( "Doing [async_init]. " );
388
      global $wp_scripts;
389
390
      if( !is_object( $wp_scripts ) || empty( $wp_scripts->queue ) )
391
        return;
392
393
      $base_url = site_url();
394
      $minit_exclude = (array)apply_filters( 'minit-exclude-js', array() );
395
396
      foreach( $wp_scripts->queue as $handle ) {
397
398
        // Skip asyncing explicitly excluded script handles
399
        if( in_array( $handle, $minit_exclude ) ) {
400
          continue;
401
        }
402
403
        $script_relative_path = Minit::get_asset_relative_path(
404
          $base_url,
405
          $wp_scripts->registered[ $handle ]->src
406
        );
407
408
        if( !$script_relative_path ) {
409
          // Add this script to our async queue
410
          $this->async_queue[] = $handle;
411
412
          // Remove this script from being printed the regular way
413
          wp_dequeue_script( $handle );
414
        }
415
416
      }
417
418
    }
419
420
    public function async_print() {
421
422
      Minit::log( "Doing [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
}