Passed
Branch dev (3fd540)
by Michael
22:28
created

AdminPageFramework_Resource_Base   F

Complexity

Total Complexity 75

Size/Duplication

Total Lines 750
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 75
eloc 263
dl 0
loc 750
rs 2.4
c 0
b 0
f 0

27 Methods

Rating   Name   Duplication   Size   Complexity  
A _replyToEnqueueStyles() 0 4 2
A _replyToAddScript() 0 9 2
A _replyToEnqueueScripts() 0 4 2
A _getClassSpecificStyleTag() 0 19 4
A _enqueueSRCByCondition() 0 2 1
A _replyToEnqueueCommonStyles() 0 10 2
A _replyToSetupArgumentCallback() 0 8 2
A _enqueueResourcesByType() 0 6 2
A _replyToModifyEnqueuedAttributes() 0 22 4
A _printClassSpecificStyles() 0 10 1
A ___enqueueScript() 0 17 5
A ___getCommonStyleTag() 0 16 3
A ___getEnqueuedIndexPropertyNameByType() 0 7 3
A __construct() 0 12 2
A _printCommonStyles() 0 8 2
A _getClassSpecificIEStyleTag() 0 19 4
A _printClassSpecificScripts() 0 24 3
A ___enqueueStyle() 0 14 3
A ___getCommonIEStyleTag() 0 17 3
A ___getContainerPropertyNameByType() 0 7 3
A _replyToAddStyle() 0 9 2
A _printCommonScripts() 0 23 3
A _enqueueSRC() 0 11 2
B ___getSRCFormatted() 0 40 7
A _replyToEnqueueCommonScripts() 0 3 2
A _replyToSetUpHooks() 0 35 4
A _addEnqueuingResourceByType() 0 26 2

How to fix   Complexity   

Complex Class

Complex classes like AdminPageFramework_Resource_Base often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use AdminPageFramework_Resource_Base, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Admin Page Framework
4
 *
5
 * http://admin-page-framework.michaeluno.jp/
6
 * Copyright (c) 2013-2021, Michael Uno; Licensed MIT
7
 *
8
 */
9
10
/**
11
 * Provides methods to enqueue or insert resource elements.
12
 *
13
 * The class handles `<link>`, `<style>` and `<script>` tags to be inserted conditionally into the head tag or the footer of the page.
14
 *
15
 * @abstract
16
 * @since       2.1.5
17
 * @since       3.3.0       Changed the name from `AdminPageFramework_HeadTag_Base`.
18
 * @since       3.6.3       Changed it to extend `AdminPageFramework_WPUtility`.
19
 * @extends     AdminPageFramework_FrameworkUtility
20
 * @package     AdminPageFramework/Common/Factory/Resource
21
 * @internal
22
 * @extends     AdminPageFramework_FrameworkUtility
23
 */
24
abstract class AdminPageFramework_Resource_Base extends AdminPageFramework_FrameworkUtility {
25
26
    /**
27
     * Represents the structure of the array for enqueuing scripts and styles.
28
     *
29
     * @since       2.1.2
30
     * @since       2.1.5       Moved to the base class.
31
     * @since       3.0.0       Moved from the property class.
32
     * @since       3.3.0       Changed the name to `$_aStructure_EnqueuingResources` from `$_aStructure_EnqueuingScriptsAndStyles`.
33
     * @internal
34
     */
35
    protected static $_aStructure_EnqueuingResources = array(
36
37
        /* The system internal keys. */
38
        'sSRC'              => null,
39
        'sSRCRaw'           => null,
40
        'aPostTypes'        => array(),     // for meta box class
41
        'sPageSlug'         => null,
42
        'sTabSlug'          => null,
43
        'sType'             => null,        // script or style
44
45
        /* The below keys are for users. */
46
        'handle_id'         => null,
47
        'dependencies'      => array(),
48
        'version'           => false,       // although the type should be string, the wp_enqueue_...() functions want false as the default value.
49
        'attributes'        => array(),     // [3.3.0+] - the attribute array @deprecated 3.9.0
50
        'conditional'       => null,        // [3.9.0+] Comments for IE 6, lte IE 7 etc. @see wp_style_add_data() and wp_script_add_data()
51
52
        // script specific
53
        'translation'       => array(),     // only for scripts
54
        'translation_var'   => '',          // [3.9.0+] the object name of the passed translation data to JavaScript script
55
        'in_footer'         => false,       // only for scripts
56
57
        // style specific
58
        'media'             => 'all',       // only for styles
59
        /// [3.9.0+] @see wp_style_add_data()
60
        'rtl'               => null,        // bool|string To declare an RTL stylesheet.
61
        'suffix'            => null,        // string      Optional suffix, used in combination with RTL.
62
        'alt'               => null,        // bool        For rel="alternate stylesheet".
63
        'title'             => null,        // string      For preferred/alternate stylesheets.
64
    );
65
66
    /**
67
     * Stores the class selector used for the class-specific style.
68
     *
69
     * @since       3.2.0
70
     * @remark      This value should be overridden in an extended class.
71
     * @internal
72
     */
73
    protected $_sClassSelector_Style    = 'admin-page-framework-style';
74
75
    /**
76
     * Stores the class selector used to the class-specific script.
77
     *
78
     * @since       3.2.0
79
     * @remark      This value should be overridden in an extended class.
80
     * @internal
81
     */
82
    protected $_sClassSelector_Script   = 'admin-page-framework-script';
83
84
    /**
85
     * Stores hand IDs by resource url to look up handle id and add custom arguments.
86
     * @since       3.3.0
87
     * @internal
88
     */
89
    protected $_aHandleIDs = array();
90
91
    /**
92
     * A property object.
93
     *
94
     * @var         AdminPageFramework_Property_Base
95
     * @remark      Set in the constructor.
96
     */
97
    public $oProp;
98
99
    /**
100
     * A utility object.
101
     *
102
     * @remark      Set in the constructor.
103
     * @deprecated  3.6.3
104
     * @remark      kept for backward compatibility.
105
     * @var         AdminPageFramework_WPUtility
106
     */
107
    public $oUtil;
108
109
    /**
110
     * Sets up properties and hooks.
111
     * @internal
112
     */
113
    public function __construct( $oProp ) {
114
115
        $this->oProp = $oProp;
116
117
        // for backward compatibility
118
        $this->oUtil = new AdminPageFramework_WPUtility;
0 ignored issues
show
Deprecated Code introduced by
The property AdminPageFramework_Resource_Base::$oUtil has been deprecated: 3.6.3 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

118
        /** @scrutinizer ignore-deprecated */ $this->oUtil = new AdminPageFramework_WPUtility;

This property has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.

Loading history...
119
120
        if ( $this->isDoingAjax() ) {
121
            return;
122
        }
123
124
        $this->registerAction( 'current_screen', array( $this, '_replyToSetUpHooks' ) );
125
126
    }
127
128
        /**
129
         * @since 3.9.0
130
         */
131
        public function _replyToSetUpHooks() {
132
133
            if ( ! $this->oProp->oCaller->isInThePage() ) {
134
                return;
135
            }
136
137
            // Hook the admin header to insert custom admin stylesheets and scripts.
138
            add_action( 'admin_enqueue_scripts', array( $this, '_replyToEnqueueCommonScripts' ), 1 );
139
            add_action( 'admin_enqueue_scripts', array( $this, '_replyToEnqueueCommonStyles' ), 1  );
140
141
            add_action( 'admin_enqueue_scripts', array( $this, '_replyToEnqueueScripts' ) );
142
            add_action( 'admin_enqueue_scripts', array( $this, '_replyToEnqueueStyles' ) );
143
144
            /// A low priority is required to let dependencies loaded fast especially in customizer.php.
145
            add_action( did_action( 'admin_print_styles' ) ? 'admin_print_footer_scripts' : 'admin_print_styles', array( $this, '_replyToAddStyle' ), 999 );
146
            add_action( did_action( 'admin_print_scripts' ) ? 'admin_print_footer_scripts' : 'admin_print_scripts', array( $this, '_replyToAddScript' ), 999 );
147
148
            // Take care of items that could not be added in the head tag.
149
150
            /// For wp-admin/customizer.php
151
            add_action( 'customize_controls_print_footer_scripts', array( $this, '_replyToEnqueueScripts' ) );
152
            add_action( 'customize_controls_print_footer_scripts', array( $this, '_replyToEnqueueStyles' ) );
153
154
            /// For admin pages other than wp-admin/customizer.php
155
            add_action( 'admin_footer', array( $this, '_replyToEnqueueScripts' ) );
156
            add_action( 'admin_footer', array( $this, '_replyToEnqueueStyles' ) );
157
158
            /// For all admin pages.
159
            add_action( 'admin_print_footer_scripts', array( $this, '_replyToAddStyle' ), 999 );
160
            add_action( 'admin_print_footer_scripts', array( $this, '_replyToAddScript' ), 999 );
161
162
163
            // To add the custom attributes to the enqueued style and script tags.
164
            add_filter( 'script_loader_src', array( $this, '_replyToSetupArgumentCallback' ), 1, 2 );
165
            add_filter( 'style_loader_src', array( $this, '_replyToSetupArgumentCallback' ), 1, 2 );
166
167
        }
168
169
    /*
170
     * Methods that should be overridden in extended classes.
171
     * @internal
172
     */
173
174
    // @deprecated 3.8.31 Unused
175
    // public function _forceToEnqueueStyle( $sSRC, $aCustomArgs=array() ) {}
176
    // public function _forceToEnqueueScript( $sSRC, $aCustomArgs=array() ) {}
177
178
    /**
179
     * A helper function for the _replyToEnqueueScripts() and the `_replyToEnqueueStyle()` methods.
180
     *
181
     * @since       2.1.5
182
     * @since       3.7.0      Fixed a typo in the method name.
183
     * @internal
184
     * @remark      The widget fields type does not have conditions unlike the meta-box type that requires to check currently loaded post type.
185
     * @remark      This method should be redefined in the extended class.
186
     */
187
    protected function _enqueueSRCByCondition( $aEnqueueItem ) {
188
        $this->_enqueueSRC( $aEnqueueItem );
189
    }
190
191
    /*
192
     * Shared methods
193
     */
194
    	/**
195
         * Checks the src url of the enqueued script/style to determine whether or not to set up a attribute modification callback.
196
         *
197
         * If it is one of the framework added item, the method sets up a hook to modify the url to add custom attributes.
198
         *
199
         * @since       3.3.0
200
         * @internal
201
         * @callback    action      script_loader_src
202
         * @callback    action      style_loader_src
203
         */
204
        public function _replyToSetupArgumentCallback( $sSRC, $sHandleID ) {
205
206
            if ( isset( $this->oProp->aResourceAttributes[ $sHandleID ] ) ) {
207
                $this->_aHandleIDs[ $sSRC ] = $sHandleID;
208
                add_filter( 'clean_url', array( $this, '_replyToModifyEnqueuedAttributes' ), 1, 3 );
209
                remove_filter( current_filter(), array( $this, '_replyToSetupArgumentCallback' ), 1 );
210
            }
211
            return $sSRC;
212
213
        }
214
            /**
215
             * Modifies the attributes of the enqueued script tag.
216
             *
217
             * @since   3.3.0
218
             * @internal
219
             */
220
            public function _replyToModifyEnqueuedAttributes( $sSanitizedURL, $sOriginalURL, $sContext ) {
221
222
                if ( 'display' !== $sContext ) {
223
                    return $sSanitizedURL;
224
                }
225
226
                // Returns the modified url which attributes are embedded at the end.
227
                if ( isset( $this->_aHandleIDs[ $sOriginalURL ] ) ) {
228
229
                    $_sHandleID     = $this->_aHandleIDs[ $sOriginalURL ];
230
                    $_aAttributes   = $this->oProp->aResourceAttributes[ $_sHandleID ];
231
232
                    if ( empty( $_aAttributes ) ) {
233
                        return $sSanitizedURL;
234
                    }
235
236
                    $_sAttributes   = $this->getAttributes( $_aAttributes );
237
                    return $sSanitizedURL . "' " . rtrim( $_sAttributes, "'\"" );
238
239
                }
240
241
                return $sSanitizedURL;
242
243
            }
244
245
    /**
246
     * Prints the inline stylesheet of the meta-box common CSS rules with the style tag.
247
     *
248
     * @internal
249
     * @since       3.0.0
250
     * @since       3.2.0       Moved to the base class from the meta box class.
251
     * @remark      The meta box class may be instantiated multiple times so prevent echoing the same styles multiple times.
252
     * @parameter   string      $sIDPrefix   The id selector embedded in the script tag.
253
     * @parameter   string      $sClassName  The class name that identify the call group. This is important for the meta-box class because it can be instantiated multiple times in one particular page.
254
     */
255
    protected function _printCommonStyles( $sIDPrefix, $sClassName ) {
0 ignored issues
show
Unused Code introduced by
The parameter $sClassName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

255
    protected function _printCommonStyles( $sIDPrefix, /** @scrutinizer ignore-unused */ $sClassName ) {

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

Loading history...
256
257
        if ( $this->hasBeenCalled( 'COMMON_STYLES: ' . get_class( $this ) . '::' . __METHOD__ ) ) {
258
            return;
259
        }
260
        $_oCaller = $this->oProp->oCaller;
261
        echo $this->___getCommonStyleTag( $_oCaller, $sIDPrefix );
262
        echo $this->___getCommonIEStyleTag( $_oCaller, $sIDPrefix );
263
264
    }
265
        /**
266
         * @internal
267
         * @since       3.5.7
268
         * @since       3.8.22  Renamed from `_getStyleTag()`.
269
         * @return      string
270
         */
271
        private function ___getCommonStyleTag( $oCaller, $sIDPrefix ) {
272
273
            $_sStyle     = $this->addAndApplyFilters(
274
                $oCaller,
275
                array(
276
                    "style_common_admin_page_framework",            // 3.2.1+
277
                    "style_common_{$this->oProp->sClassName}",
278
                ),
279
                '' // AdminPageFramework_CSS::getDefaultCSS() @deprecated 3.9.0 No longer uses internal stylesheets
280
            );
281
            $_sStyle     = $this->isDebugMode() ? $_sStyle : $this->getCSSMinified( $_sStyle );
282
            $_sStyle     = trim( $_sStyle );
283
            if ( $_sStyle ) {
284
                return "<style type='text/css' id='" . esc_attr( strtolower( $sIDPrefix ) ) . "'>"
285
                        . $_sStyle
286
                    . "</style>";
287
            }
288
289
290
        }
291
        /**
292
         * @internal
293
         * @since       3.5.7
294
         * @since       3.8.22  Renamed from `_getIEStyleTag()`.
295
         * @return      string
296
         */
297
        private function ___getCommonIEStyleTag( $oCaller, $sIDPrefix ) {
298
299
            $_sStyleIE   = $this->addAndApplyFilters(
300
                $oCaller,
301
                array(
302
                    "style_ie_common_admin_page_framework",         // 3.2.1+
303
                    "style_ie_common_{$this->oProp->sClassName}",
304
                ),
305
                AdminPageFramework_CSS::getDefaultCSSIE()
306
            );
307
            $_sStyleIE  = $this->isDebugMode() ? $_sStyleIE : $this->getCSSMinified( $_sStyleIE );
308
            $_sStyleIE  = trim( $_sStyleIE );
309
            return $_sStyleIE
310
                ? "<!--[if IE]><style type='text/css' id='" . esc_attr( strtolower( $sIDPrefix . "-ie" ) ) . "'>"
311
                        . $_sStyleIE
312
                    . "</style><![endif]-->"
313
                : '';
314
315
        }
316
317
    /**
318
     * Prints the inline scripts of the meta-box common scripts.
319
     *
320
     * @internal
321
     * @since       3.0.0
322
     * @since       3.2.0       Moved to the base class from the meta box class.
323
     * @remark      The meta box class may be instantiated multiple times so prevent echoing the same styles multiple times.
324
     * @parametr    string      $sIDPrefix      The id selector embedded in the script tag.
325
     * @parametr    string      $sClassName     The class name that identify the call group. This is important for the meta-box class because it can be instantiated multiple times in one particular page.
326
     */
327
    protected function _printCommonScripts( $sIDPrefix, $sClassName ) {
0 ignored issues
show
Unused Code introduced by
The parameter $sClassName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

327
    protected function _printCommonScripts( $sIDPrefix, /** @scrutinizer ignore-unused */ $sClassName ) {

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

Loading history...
328
329
        if ( $this->hasBeenCalled( 'COMMON_SCRIPT: ' . get_class( $this ) . '::' . __METHOD__ ) ) {
330
            return;
331
        }
332
333
        $_sScript = $this->addAndApplyFilters(
334
            $this->oProp->oCaller,
335
            array(
336
                "script_common_admin_page_framework",       // 3.2.1+
337
                "script_common_{$this->oProp->sClassName}",
338
            ),
339
            AdminPageFramework_Property_Base::$_sDefaultScript
340
        );
341
        $_sScript = trim( $_sScript );
342
        if ( ! $_sScript ) {
343
            return;
344
        }
345
        echo "<script type='text/javascript' id='" . esc_attr( strtolower( $sIDPrefix ) ) . "'>"
346
                . '/* <![CDATA[ */'
347
                . $_sScript
348
                . '/* ]]> */'
349
            . "</script>";
350
351
    }
352
353
    /**
354
     * Prints the inline stylesheet of this class stored in this class property.
355
     *
356
     * @since       3.0.0
357
     * @since       3.2.0       Made the properties storing styles empty. Moved to the base class.
358
     * @internal
359
     * @return      void
360
     */
361
    protected function _printClassSpecificStyles( $sIDPrefix ) {
362
363
        $_oCaller   = $this->oProp->oCaller;
364
        echo $this->_getClassSpecificStyleTag( $_oCaller, $sIDPrefix );
365
        echo $this->_getClassSpecificIEStyleTag( $_oCaller, $sIDPrefix );
366
367
        // As of 3.2.0, this method also gets called in the footer to ensure there is not any left styles.
368
        // This happens when a head tag item is added after the head tag is already rendered such as for widget forms.
369
        $this->oProp->sStyle    = '';
370
        $this->oProp->sStyleIE  = '';
371
372
    }
373
        /**
374
         *
375
         * @internal
376
         * @since       3.5.7
377
         * @return      string
378
         */
379
        private function _getClassSpecificStyleTag( $_oCaller, $sIDPrefix ) {
380
381
            static $_iCallCount = 0;
382
383
            $_sFilterName = "style_{$this->oProp->sClassName}";
384
            if ( $this->hasBeenCalled( 'FILTER: ' . $_sFilterName ) ) { // 3.8.22
385
                return '';
386
            }
387
            $_sStyle = $this->addAndApplyFilters( $_oCaller, $_sFilterName, $this->oProp->sStyle );
388
            $_sStyle = $this->isDebugMode() ? $_sStyle : $this->getCSSMinified( $_sStyle );
389
            $_sStyle = trim( $_sStyle );
390
            if ( ! $_sStyle ) {
391
                return '';
392
            }
393
            $_iCallCount++;
394
            $_sID = strtolower( "{$sIDPrefix}-" . $this->oProp->sClassName . "_{$_iCallCount}" );
395
            return "<style type='text/css' id='" . esc_attr( $_sID ) . "'>"
396
                    . $_sStyle
397
                . "</style>";
398
399
        }
400
        /**
401
         *
402
         * @internal
403
         * @since       3.5.7
404
         * @return      string
405
         */
406
        private function _getClassSpecificIEStyleTag( $_oCaller, $sIDPrefix ) {
407
408
            static $_iCallCountIE = 1;
409
410
            $_sFilterName = "style_ie_{$this->oProp->sClassName}";
411
            if ( $this->hasBeenCalled( 'FILTER: ' . $_sFilterName ) ) { // 3.8.22
412
                return '';
413
            }
414
            $_sStyleIE = $this->addAndApplyFilters( $_oCaller, $_sFilterName, $this->oProp->sStyleIE );
415
            $_sStyleIE = $this->isDebugMode() ? $_sStyleIE : $this->getCSSMinified( $_sStyleIE );
416
            $_sStyleIE = trim( $_sStyleIE );
417
            if ( ! $_sStyleIE ) {
418
                return '';
419
            }
420
            $_iCallCountIE++;
421
            $_sID  = strtolower( "{$sIDPrefix}-ie-{$this->oProp->sClassName}_{$_iCallCountIE}" );
422
            return "<!--[if IE]><style type='text/css' id='" . esc_attr( $_sID ) . "'>"
423
                    . $_sStyleIE
424
                . "</style><![endif]-->";
425
426
        }
427
428
    /**
429
     * Prints the inline scripts of this class stored in this class property.
430
     *
431
     * @since       3.0.0
432
     * @since       3.2.0       Made the property empty that stores scripts. Moved to the base class.
433
     * @internal
434
     */
435
    protected function _printClassSpecificScripts( $sIDPrefix ) {
436
437
        static $_iCallCount = 1;
438
        $_sFilterName = "script_{$this->oProp->sClassName}";
439
        if ( $this->hasBeenCalled( 'FILTER: ' . $_sFilterName ) ) { // 3.8.22
440
            return '';
441
        }
442
        $_sScript = $this->addAndApplyFilters( $this->oProp->oCaller, $_sFilterName, $this->oProp->sScript );
443
        $_sScript = trim( $_sScript );
444
        if ( ! $_sScript ) {
445
            return '';
446
        }
447
448
        $_iCallCount++;
449
        $_sID = strtolower( "{$sIDPrefix}-{$this->oProp->sClassName}_{$_iCallCount}" );
450
        echo "<script type='text/javascript' id='" . esc_attr( $_sID ) . "'>"
451
                . '/* <![CDATA[ */'
452
                . $_sScript
453
                . '/* ]]> */'
454
            . "</script>";
455
456
        // As of 3.2.0, this method also gets called in the footer to ensure there is not any left scripts.
457
        // This happens when a head tag item is added after the head tag is already rendered such as for widget forms.
458
        $this->oProp->sScript = '';
459
460
    }
461
462
    /**
463
     * Appends the CSS rules of the framework in the head tag.
464
     *
465
     * @since       2.0.0
466
     * @since       2.1.5       Moved from `AdminPageFramework_MetaBox`. Changed the name from `addAtyle()` to `replyToAddStyle()`.
467
     * @callback    action      admin_head
468
     * @internal
469
     */
470
    public function _replyToAddStyle() {
471
472
        $_oCaller = $this->oProp->oCaller;
473
        if ( ! $_oCaller->isInThePage() ) {
474
            return;
475
        }
476
477
        $this->_printCommonStyles( 'admin-page-framework-style-common', get_class() );
478
        $this->_printClassSpecificStyles( $this->_sClassSelector_Style . '-' . $this->oProp->sStructureType );
479
480
    }
481
    /**
482
     * Appends the JavaScript script of the framework in the head tag.
483
     *
484
     * @callback    action      admin_head
485
     * @since       2.0.0
486
     * @since       2.1.5       Moved from AdminPageFramework_MetaBox. Changed the name from `addScript()` to `replyToAddScript()`.
487
     * @since       3.2.0       Moved from AdminPageFramework_Resource_post_meta_box.
488
     * @internal
489
     */
490
    public function _replyToAddScript() {
491
492
        $_oCaller = $this->oProp->oCaller;
493
        if ( ! $_oCaller->isInThePage() ) {
494
            return;
495
        }
496
497
        $this->_printCommonScripts( 'admin-page-framework-script-common', get_class() );
498
        $this->_printClassSpecificScripts( $this->_sClassSelector_Script . '-' . $this->oProp->sStructureType );
499
500
    }
501
502
    /**
503
     * Performs actual enqueuing items.
504
     *
505
     * @since       2.1.2
506
     * @since       2.1.5       Moved from the main class.
507
     * @param       array       $aEnqueueItem
508
     * @internal
509
     */
510
    protected function _enqueueSRC( $aEnqueueItem ) {
511
512
        $_sSRC = $this->___getSRCFormatted( $aEnqueueItem );
513
514
        // For styles
515
        if ( 'style' === $aEnqueueItem[ 'sType' ] ) {
516
            $this->___enqueueStyle( $_sSRC, $aEnqueueItem );
517
            return;
518
        }
519
520
        $this->___enqueueScript( $_sSRC, $aEnqueueItem );
521
522
    }
523
        /**
524
         * @param string $sSRC
525
         * @param array $aEnqueueItem
526
         * @since 3.9.0
527
         */
528
        private function ___enqueueScript( $sSRC, array $aEnqueueItem ) {
529
            wp_enqueue_script(
530
                $aEnqueueItem[ 'handle_id' ],
531
                $sSRC,
532
                $aEnqueueItem[ 'dependencies' ],
533
                $aEnqueueItem[ 'version' ],
534
                did_action( 'admin_body_class' ) || ( boolean ) $aEnqueueItem[ 'in_footer' ]
535
            );
536
            if ( $aEnqueueItem[ 'translation' ] ) {
537
                wp_localize_script(
538
                    $aEnqueueItem[ 'handle_id' ],
539
                    empty( $aEnqueueItem[ 'translation_var' ] ) ? $aEnqueueItem[ 'handle_id' ] : $aEnqueueItem[ 'translation_var' ],
540
                    $aEnqueueItem[ 'translation' ]
541
                );
542
            }
543
            if ( $aEnqueueItem[ 'conditional' ] ) {
544
                wp_script_add_data( $aEnqueueItem[ 'handle_id' ], 'conditional', $aEnqueueItem[ 'conditional' ] );
545
            }
546
        }
547
        /**
548
         * @param string $sSRC
549
         * @param array $aEnqueueItem
550
         * @since 3.9.0
551
         */
552
        private function ___enqueueStyle( $sSRC, array $aEnqueueItem ) {
553
            wp_enqueue_style(
554
                $aEnqueueItem[ 'handle_id' ],
555
                $sSRC,
556
                $aEnqueueItem[ 'dependencies' ],
557
                $aEnqueueItem[ 'version' ],
558
                $aEnqueueItem[ 'media' ]
559
            );
560
            $_aAddData = array( 'conditional', 'rtl', 'suffix', 'alt', 'title' );
561
            foreach( $_aAddData as $_sDataKey ) {
562
                if ( ! isset( $aEnqueueItem[ $_sDataKey ] ) ) {
563
                    continue;
564
                }
565
                wp_style_add_data( $aEnqueueItem[ 'handle_id' ], $_sDataKey, $aEnqueueItem[ $_sDataKey ] );
566
            }
567
        }
568
569
        /**
570
         * Formats the SRC value.
571
         * If a path is given and a .min file exists, it will be loaded.
572
         * @param  array $aEnqueueItem
573
         * @return string
574
         * @since  3.8.31
575
         */
576
        private function ___getSRCFormatted( array $aEnqueueItem ) {
577
578
            if ( ! $this->oProp->bAutoloadMinifiedResource ) {
579
                return $aEnqueueItem[ 'sSRC' ];
580
            }
581
582
            // If the site debug mode is on, use the one that user gave.
583
            if ( $this->isDebugMode() ) {
584
                return $aEnqueueItem[ 'sSRC' ];
585
            }
586
587
            // If the user gave a url, use it.
588
            if ( $this->isURL( $aEnqueueItem[ 'sSRCRaw' ] ) ) {
589
                return $aEnqueueItem[ 'sSRC' ];
590
            }
591
592
593
            // At this point, the user gave a path.
594
            $_sMinPrefix = '.min';
595
596
            // If the user already handles a min version, then use it.
597
            if ( false !== stripos( $aEnqueueItem[ 'sSRC' ], $_sMinPrefix ) ) {
598
                return $aEnqueueItem[ 'sSRC' ];
599
            }
600
601
            $_aPathParts = pathinfo( $aEnqueueItem[ 'sSRCRaw' ] )
602
                + array( 'dirname' => '', 'filename' => '', 'basename' => '', 'extension' => '' ); // avoid undefined index warnings
603
604
            // If there is no extension, avoid using a minified version.
605
            if ( ! $_aPathParts[ 'extension' ] ) {
606
                return $aEnqueueItem[ 'sSRC' ];
607
            }
608
609
            $_aPathPartsURL = pathinfo( $aEnqueueItem[ 'sSRC' ] )
610
                + array( 'dirname' => '', 'filename' => '', 'basename' => '', 'extension' => '' ); // avoid undefined index warnings
611
612
            $_sPathMinifiedVersion = $_aPathParts[ 'dirname' ] . '/' . $_aPathParts[ 'filename' ] . $_sMinPrefix . '.' . $_aPathParts[ 'extension' ];
613
            return file_exists( $_sPathMinifiedVersion )
614
                ? $_aPathPartsURL[ 'dirname' ] . '/' . $_aPathPartsURL[ 'filename' ] . $_sMinPrefix . '.' . $_aPathPartsURL[ 'extension' ]
615
                : $aEnqueueItem[ 'sSRC' ];
616
617
        }
618
619
    /**
620
     * Enqueues framework required common scripts.
621
     * @since 3.9.0
622
     * @deprecated 3.9.0 Unused
623
     */
624
    public function _replyToEnqueueCommonScripts() {
625
        if ( $this->hasBeenCalled( 'COMMON_EXTERNAL_SCRIPTS: ' . __METHOD__ ) ) {
626
            return;
627
        }
628
        // Currently no common JS script is needed
629
        // $this->_addEnqueuingResourceByType(
630
        //     AdminPageFramework_Registry::$sDirPath . '/factory/_common/asset/js/common.js',
631
        //     array(
632
        //         'dependencies' => array( 'jquery' ),
633
        //         'in_footer' => true,
634
        //     ),
635
        //     'script'
636
        // );
637
    }
638
    /**
639
     * Enqueues framework required common stylesheets.
640
     * @since    3.9.0
641
     * @callback action wp_enqueue_scripts
642
     */
643
    public function _replyToEnqueueCommonStyles() {
644
        if ( $this->hasBeenCalled( 'COMMON_EXTERNAL_STYLES: ' . __METHOD__ ) ) {
645
            return;
646
        }
647
        $this->_addEnqueuingResourceByType(
648
            AdminPageFramework_Registry::$sDirPath . '/factory/_common/asset/css/common.css',
649
            array(
650
                'version' => AdminPageFramework_Registry::VERSION,
651
            ),
652
            'style'
653
        );
654
    }
655
656
    /**
657
     * Takes care of added enqueuing scripts by checking the currently loading page.
658
     *
659
     * @remark      A callback for the admin_enqueue_scripts hook.
660
     * @since       2.1.2
661
     * @since       2.1.5   Moved from the main class. Changed the name from `enqueueStylesCalback` to `replyToEnqueueStyles()`.
662
     * @since       3.0.0   Changed the name to `_replyToEnqueueStyles()`.
663
     * @since       3.2.0   Changed it unset the enqueued item so that the method can be called multiple times.
664
     * @internal
665
     */
666
    public function _replyToEnqueueStyles() {
667
        foreach( $this->oProp->aEnqueuingStyles as $_sKey => $_aEnqueuingStyle ) {
668
            $this->_enqueueSRCByCondition( $_aEnqueuingStyle );
669
            unset( $this->oProp->aEnqueuingStyles[ $_sKey ] );
670
        }
671
    }
672
673
    /**
674
     * Takes care of added enqueuing scripts by page slug and tab slug.
675
     *
676
     * @remark      A callback for the admin_enqueue_scripts hook.
677
     * @since       2.1.2
678
     * @since       2.1.5   Moved from the main class. Changed the name from `enqueueScriptsCallback` to `callbackEnqueueScripts()`.
679
     * @since       3.0.0   Changed the name to `_replyToEnqueueScripts()`.
680
     * @since       3.2.0   Changed it unset the enqueued item so that the method can be called multiple times.
681
     * @internal
682
     */
683
    public function _replyToEnqueueScripts() {
684
        foreach( $this->oProp->aEnqueuingScripts as $_sKey => $_aEnqueuingScript ) {
685
            $this->_enqueueSRCByCondition( $_aEnqueuingScript );
686
            unset( $this->oProp->aEnqueuingScripts[ $_sKey ] );
687
        }
688
    }
689
690
    /**
691
     * A plural version of _addEnqueuingResourceByType()
692
     * @since  3.8.31
693
     * @param  array    $aSRCs          An array of SRCs
694
     * @param  array    $aCustomArgs    A custom argument array.
695
     * @param  string   $sType          Accepts 'style' or 'script'
696
     * @return string[] Added resource handle IDs.
697
     */
698
    public function _enqueueResourcesByType( $aSRCs, array $aCustomArgs=array(), $sType='style' ) {
699
        $_aHandleIDs = array();
700
        foreach( $aSRCs as $_sSRC ) {
701
            $_aHandleIDs[] = call_user_func_array( array( $this, '_addEnqueuingResourceByType' ), array( $_sSRC, $aCustomArgs, $sType ) );
702
        }
703
        return $_aHandleIDs;
704
    }
705
706
    /**
707
     * Store an enqueuing resource item to the property by type to process later at once.
708
     *
709
     * @since       3.5.3
710
     * @since       3.8.31      Moved from `AdminPageFramework_Resource_admin_page`.
711
     * @since       3.8.31      Renamed from `_enqueueResourceByType()`
712
     * @param       string      $sSRC           The source path or url.
713
     * @param       array       $aCustomArgs    A custom argument array.
714
     * @param       string      $sType          Accepts 'style' or 'script'
715
     * @return      string      The script handle ID if added. If the passed url is not a valid url string, an empty string will be returned.
716
     * @internal
717
     */
718
    public function _addEnqueuingResourceByType( $sSRC, array $aCustomArgs=array(), $sType='style' ) {
719
720
        $sSRC       = trim( $sSRC );
721
        if ( empty( $sSRC ) ) {
722
            return '';
723
        }
724
        $_sRawSRC   = wp_normalize_path( $sSRC );
725
        $_sSRC      = $this->getResolvedSRC( $_sRawSRC );
726
727
        // Get the property name for the type
728
        $_sContainerPropertyName     = $this->___getContainerPropertyNameByType( $sType );
729
        $_sEnqueuedIndexPropertyName = $this->___getEnqueuedIndexPropertyNameByType( $sType );
730
731
        $this->oProp->{$_sContainerPropertyName}[ $_sSRC ] = array_filter( $this->getAsArray( $aCustomArgs ), array( $this, 'isNotNull' ) )
732
            + array(
733
                'sSRCRaw'   => $_sRawSRC,
734
                'sSRC'      => $_sSRC,
735
                'sType'     => $sType,
736
                'handle_id' => $sType . '_' . strtolower( $this->oProp->sClassName ) . '_' .  ( ++$this->oProp->{$_sEnqueuedIndexPropertyName} ),
737
            )
738
            + self::$_aStructure_EnqueuingResources;
739
740
        // Store the attributes in another container by url.
741
        $this->oProp->aResourceAttributes[ $this->oProp->{$_sContainerPropertyName}[ $_sSRC ]['handle_id'] ] = $this->oProp->{$_sContainerPropertyName}[ $_sSRC ]['attributes'];
742
743
        return $this->oProp->{$_sContainerPropertyName}[ $_sSRC ][ 'handle_id' ];
744
745
    }
746
        /**
747
         * Returns the property name that contains the information of resources by type.
748
         * @since   3.5.3
749
         * @since   3.8.31      Moved from `AdminPageFramework_Resource_admin_page`.
750
         * @return  string      the property name that contains the information of resources by type.
751
         */
752
        private function ___getContainerPropertyNameByType( $sType ) {
753
            switch ( $sType ) {
754
                default:
755
                case 'style':
756
                    return 'aEnqueuingStyles';
757
                case 'script':
758
                    return 'aEnqueuingScripts';
759
            }
760
        }
761
        /**
762
         * Returns the property name that contains the added count of resources by type.
763
         * @since   3.5.3
764
         * @since   3.8.31      Moved from `AdminPageFramework_Resource_admin_page`.
765
         * @return  string      the property name that contains the added count of resources by type.
766
         */
767
        private function ___getEnqueuedIndexPropertyNameByType( $sType ) {
768
            switch ( $sType ) {
769
                default:
770
                case 'style':
771
                    return 'iEnqueuedStyleIndex';
772
                case 'script':
773
                    return 'iEnqueuedScriptIndex';
774
            }
775
        }
776
777
}