Issues (565)

_controller/AdminPageFramework_Resource_Base.php (1 issue)

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

115
        /** @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...
116
117
        if ( $this->isDoingAjax() ) {
118
            return;
119
        }
120
121
        $this->registerAction( 'current_screen', array( $this, '_replyToSetUpHooks' ) );
122
123
    }
124
125
        /**
126
         * @since 3.9.0
127
         */
128
        public function _replyToSetUpHooks() {
129
130
            if ( ! $this->oProp->oCaller->isInThePage() ) {
131
                return;
132
            }
133
134
            // Hook the admin header to insert custom admin stylesheets and scripts.
135
            // add_action( 'admin_enqueue_scripts', array( $this, '_replyToEnqueueCommonScripts' ), 1 );    // @deprecated 3.9.0
136
            add_action( 'admin_enqueue_scripts', array( $this, '_replyToEnqueueCommonStyles' ), 1  );
137
138
            add_action( 'admin_enqueue_scripts', array( $this, '_replyToEnqueueScripts' ) );
139
            add_action( 'admin_enqueue_scripts', array( $this, '_replyToEnqueueStyles' ) );
140
141
            /// A low priority is required to let dependencies loaded fast especially in customizer.php.
142
            add_action( did_action( 'admin_print_styles' ) ? 'admin_print_footer_scripts' : 'admin_print_styles', array( $this, '_replyToAddStyle' ), 999 );
143
            add_action( did_action( 'admin_print_scripts' ) ? 'admin_print_footer_scripts' : 'admin_print_scripts', array( $this, '_replyToAddScript' ), 999 );
144
145
            // Take care of items that could not be added in the head tag.
146
147
            /// For wp-admin/customizer.php
148
            add_action( 'customize_controls_print_footer_scripts', array( $this, '_replyToEnqueueScripts' ) );
149
            add_action( 'customize_controls_print_footer_scripts', array( $this, '_replyToEnqueueStyles' ) );
150
151
            /// For admin pages other than wp-admin/customizer.php
152
            add_action( 'admin_footer', array( $this, '_replyToEnqueueScripts' ) );
153
            add_action( 'admin_footer', array( $this, '_replyToEnqueueStyles' ) );
154
155
            /// For all admin pages.
156
            add_action( 'admin_print_footer_scripts', array( $this, '_replyToAddStyle' ), 999 );
157
            add_action( 'admin_print_footer_scripts', array( $this, '_replyToAddScript' ), 999 );
158
159
160
            // To add the custom attributes to the enqueued style and script tags.
161
            add_filter( 'script_loader_src', array( $this, '_replyToSetupArgumentCallback' ), 1, 2 );
162
            add_filter( 'style_loader_src', array( $this, '_replyToSetupArgumentCallback' ), 1, 2 );
163
164
        }
165
166
    /*
167
     * Methods that should be overridden in extended classes.
168
     * @internal
169
     */
170
171
    // @deprecated 3.8.31 Unused
172
    // public function _forceToEnqueueStyle( $sSRC, $aCustomArgs=array() ) {}
173
    // public function _forceToEnqueueScript( $sSRC, $aCustomArgs=array() ) {}
174
175
    /**
176
     * A helper function for the _replyToEnqueueScripts() and the `_replyToEnqueueStyle()` methods.
177
     *
178
     * @since    2.1.5
179
     * @since    3.7.0      Fixed a typo in the method name.
180
     * @internal
181
     * @remark   The widget fields type does not have conditions unlike the meta-box type that requires to check currently loaded post type.
182
     * @remark   This method should be redefined in the extended class.
183
     */
184
    protected function _enqueueSRCByCondition( $aEnqueueItem ) {
185
        $this->_enqueueSRC( $aEnqueueItem );
186
    }
187
188
    /*
189
     * Shared methods
190
     */
191
    	/**
192
         * Checks the src url of the enqueued script/style to determine whether or not to set up a attribute modification callback.
193
         *
194
         * If it is one of the framework added item, the method sets up a hook to modify the url to add custom attributes.
195
         *
196
         * @since    3.3.0
197
         * @internal
198
         * @callback add_action() script_loader_src
199
         * @callback add_action() style_loader_src
200
         */
201
        public function _replyToSetupArgumentCallback( $sSRC, $sHandleID ) {
202
            if ( isset( $this->oProp->aResourceAttributes[ $sHandleID ] ) ) {
203
                $this->_aHandleIDs[ $sSRC ] = $sHandleID;
204
                add_filter( 'clean_url', array( $this, '_replyToModifyEnqueuedAttributes' ), 1, 3 );
205
                remove_filter( current_filter(), array( $this, '_replyToSetupArgumentCallback' ), 1 );
206
            }
207
            return $sSRC;
208
        }
209
            /**
210
             * Modifies the attributes of the enqueued script tag.
211
             *
212
             * @since    3.3.0
213
             * @internal
214
             */
215
            public function _replyToModifyEnqueuedAttributes( $sSanitizedURL, $sOriginalURL, $sContext ) {
216
217
                if ( 'display' !== $sContext ) {
218
                    return $sSanitizedURL;
219
                }
220
221
                // Returns the modified url which attributes are embedded at the end.
222
                if ( isset( $this->_aHandleIDs[ $sOriginalURL ] ) ) {
223
224
                    $_sHandleID     = $this->_aHandleIDs[ $sOriginalURL ];
225
                    $_aAttributes   = $this->oProp->aResourceAttributes[ $_sHandleID ];
226
227
                    if ( empty( $_aAttributes ) ) {
228
                        return $sSanitizedURL;
229
                    }
230
231
                    $_sAttributes   = $this->getAttributes( $_aAttributes );
232
                    return $sSanitizedURL . "' " . rtrim( $_sAttributes, "'\"" );
233
234
                }
235
236
                return $sSanitizedURL;
237
238
            }
239
240
    /**
241
     * Prints the inline stylesheet of the meta-box common CSS rules with the style tag.
242
     *
243
     * @internal
244
     * @since    3.0.0
245
     * @since    3.2.0       Moved to the base class from the meta box class.
246
     * @remark   The meta box class may be instantiated multiple times so prevent echoing the same styles multiple times.
247
     * @param    string      $sIDPrefix   The id selector embedded in the script tag.
248
     * @param    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.
249
     */
250
    protected function _printCommonStyles( $sIDPrefix, $sClassName ) {
251
252
        if ( $this->hasBeenCalled( 'COMMON_STYLES: ' . get_class( $this ) . '::' . __METHOD__ ) ) {
253
            return;
254
        }
255
        $_oCaller = $this->oProp->oCaller;
256
        echo $this->___getCommonStyleTag( $_oCaller, $sIDPrefix );
257
        echo $this->___getCommonIEStyleTag( $_oCaller, $sIDPrefix );
258
259
    }
260
        /**
261
         * @internal
262
         * @since    3.5.7
263
         * @since    3.8.22  Renamed from `_getStyleTag()`.
264
         * @return   string
265
         */
266
        private function ___getCommonStyleTag( $oCaller, $sIDPrefix ) {
267
268
            $_sStyle     = $this->addAndApplyFilters(
269
                $oCaller,
270
                array(
271
                    "style_common_admin_page_framework",            // 3.2.1+
272
                    "style_common_{$this->oProp->sClassName}",
273
                ),
274
                '' // AdminPageFramework_CSS::getDefaultCSS() @deprecated 3.9.0 No longer uses internal stylesheets
275
            );
276
            $_sStyle     = $this->isDebugMode() ? $_sStyle : $this->getCSSMinified( $_sStyle );
277
            $_sStyle     = trim( $_sStyle );
278
            if ( $_sStyle ) {
279
                return "<style type='text/css' id='" . esc_attr( strtolower( $sIDPrefix ) ) . "'>"
280
                        . $_sStyle
281
                    . "</style>";
282
            }
283
284
285
        }
286
        /**
287
         * @internal
288
         * @since    3.5.7
289
         * @since    3.8.22  Renamed from `_getIEStyleTag()`.
290
         * @return   string
291
         */
292
        private function ___getCommonIEStyleTag( $oCaller, $sIDPrefix ) {
293
            $_sStyleIE   = $this->addAndApplyFilters(
294
                $oCaller,
295
                array(
296
                    "style_ie_common_admin_page_framework",         // 3.2.1+
297
                    "style_ie_common_{$this->oProp->sClassName}",
298
                ),
299
                AdminPageFramework_CSS::getDefaultCSSIE()
300
            );
301
            $_sStyleIE  = $this->isDebugMode() ? $_sStyleIE : $this->getCSSMinified( $_sStyleIE );
302
            $_sStyleIE  = trim( $_sStyleIE );
303
            return $_sStyleIE
304
                ? "<!--[if IE]><style type='text/css' id='" . esc_attr( strtolower( $sIDPrefix . "-ie" ) ) . "'>"
305
                        . $_sStyleIE
306
                    . "</style><![endif]-->"
307
                : '';
308
        }
309
310
    /**
311
     * Prints the inline scripts of the meta-box common scripts.
312
     *
313
     * @internal
314
     * @since    3.0.0
315
     * @since    3.2.0  Moved to the base class from the meta box class.
316
     * @remark   The meta box class may be instantiated multiple times so prevent echoing the same styles multiple times.
317
     * @param    string $sIDPrefix  The id selector embedded in the script tag.
318
     * @param    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.
319
     */
320
    protected function _printCommonScripts( $sIDPrefix, $sClassName ) {
321
322
        if ( $this->hasBeenCalled( 'COMMON_SCRIPT: ' . get_class( $this ) . '::' . __METHOD__ ) ) {
323
            return;
324
        }
325
326
        $_sScript = $this->addAndApplyFilters(
327
            $this->oProp->oCaller,
328
            array(
329
                "script_common_admin_page_framework",       // 3.2.1+
330
                "script_common_{$this->oProp->sClassName}",
331
            ),
332
            AdminPageFramework_Property_Base::$_sDefaultScript
333
        );
334
        $_sScript = trim( $_sScript );
335
        if ( ! $_sScript ) {
336
            return;
337
        }
338
        echo "<script type='text/javascript' id='" . esc_attr( strtolower( $sIDPrefix ) ) . "'>"
339
                . '/* <![CDATA[ */'
340
                . $_sScript
341
                . '/* ]]> */'
342
            . "</script>";
343
344
    }
345
346
    /**
347
     * Prints the inline stylesheet of this class stored in this class property.
348
     *
349
     * @since    3.0.0
350
     * @since    3.2.0 Made the properties storing styles empty. Moved to the base class.
351
     * @internal
352
     */
353
    protected function _printClassSpecificStyles( $sIDPrefix ) {
354
355
        $_oCaller   = $this->oProp->oCaller;
356
        echo $this->_getClassSpecificStyleTag( $_oCaller, $sIDPrefix );
357
        echo $this->_getClassSpecificIEStyleTag( $_oCaller, $sIDPrefix );
358
359
        // Since 3.2.0, this method also gets called in the footer to ensure there is not any left styles.
360
        // This happens when a head tag item is added after the head tag is already rendered such as for widget forms.
361
        $this->oProp->sStyle    = '';
362
        $this->oProp->sStyleIE  = '';
363
364
    }
365
        /**
366
         *
367
         * @internal
368
         * @since    3.5.7
369
         * @return   string
370
         */
371
        private function _getClassSpecificStyleTag( $_oCaller, $sIDPrefix ) {
372
373
            static $_iCallCount = 0;
374
375
            $_sFilterName = "style_{$this->oProp->sClassName}";
376
            if ( $this->hasBeenCalled( 'FILTER: ' . $_sFilterName ) ) { // 3.8.22
377
                return '';
378
            }
379
            $_sStyle = $this->addAndApplyFilters( $_oCaller, $_sFilterName, $this->oProp->sStyle );
380
            $_sStyle = $this->isDebugMode() ? $_sStyle : $this->getCSSMinified( $_sStyle );
381
            $_sStyle = trim( $_sStyle );
382
            if ( ! $_sStyle ) {
383
                return '';
384
            }
385
            $_iCallCount++;
386
            $_sID = strtolower( "{$sIDPrefix}-" . $this->oProp->sClassName . "_{$_iCallCount}" );
387
            return "<style type='text/css' id='" . esc_attr( $_sID ) . "'>"
388
                    . $_sStyle
389
                . "</style>";
390
391
        }
392
        /**
393
         *
394
         * @internal
395
         * @since    3.5.7
396
         * @return   string
397
         */
398
        private function _getClassSpecificIEStyleTag( $_oCaller, $sIDPrefix ) {
399
400
            static $_iCallCountIE = 1;
401
402
            $_sFilterName = "style_ie_{$this->oProp->sClassName}";
403
            if ( $this->hasBeenCalled( 'FILTER: ' . $_sFilterName ) ) { // 3.8.22
404
                return '';
405
            }
406
            $_sStyleIE = $this->addAndApplyFilters( $_oCaller, $_sFilterName, $this->oProp->sStyleIE );
407
            $_sStyleIE = $this->isDebugMode() ? $_sStyleIE : $this->getCSSMinified( $_sStyleIE );
408
            $_sStyleIE = trim( $_sStyleIE );
409
            if ( ! $_sStyleIE ) {
410
                return '';
411
            }
412
            $_iCallCountIE++;
413
            $_sID  = strtolower( "{$sIDPrefix}-ie-{$this->oProp->sClassName}_{$_iCallCountIE}" );
414
            return "<!--[if IE]><style type='text/css' id='" . esc_attr( $_sID ) . "'>"
415
                    . $_sStyleIE
416
                . "</style><![endif]-->";
417
418
        }
419
420
    /**
421
     * Prints the inline scripts of this class stored in this class property.
422
     *
423
     * @since    3.0.0
424
     * @since    3.2.0 Made the property empty that stores scripts. Moved to the base class.
425
     * @internal
426
     */
427
    protected function _printClassSpecificScripts( $sIDPrefix ) {
428
429
        static $_iCallCount = 1;
430
        $_sFilterName = "script_{$this->oProp->sClassName}";
431
        if ( $this->hasBeenCalled( 'FILTER: ' . $_sFilterName ) ) { // 3.8.22
432
            return '';
433
        }
434
        $_sScript = $this->addAndApplyFilters( $this->oProp->oCaller, $_sFilterName, $this->oProp->sScript );
435
        $_sScript = trim( $_sScript );
436
        if ( ! $_sScript ) {
437
            return '';
438
        }
439
440
        $_iCallCount++;
441
        $_sID = strtolower( "{$sIDPrefix}-{$this->oProp->sClassName}_{$_iCallCount}" );
442
        echo "<script type='text/javascript' id='" . esc_attr( $_sID ) . "'>"
443
                . '/* <![CDATA[ */'
444
                . $_sScript
445
                . '/* ]]> */'
446
            . "</script>";
447
448
        // As of 3.2.0, this method also gets called in the footer to ensure there is not any left scripts.
449
        // This happens when a head tag item is added after the head tag is already rendered such as for widget forms.
450
        $this->oProp->sScript = '';
451
452
    }
453
454
    /**
455
     * Appends the CSS rules of the framework in the head tag.
456
     *
457
     * @since    2.0.0
458
     * @since    2.1.5        Moved from `AdminPageFramework_MetaBox`. Changed the name from `addAtyle()` to `replyToAddStyle()`.
459
     * @callback add_action() admin_head
460
     * @internal
461
     */
462
    public function _replyToAddStyle() {
463
464
        $_oCaller = $this->oProp->oCaller;
465
        if ( ! $_oCaller->isInThePage() ) {
466
            return;
467
        }
468
469
        $this->_printCommonStyles( 'admin-page-framework-style-common', get_class() );
470
        $this->_printClassSpecificStyles( $this->_sClassSelector_Style . '-' . $this->oProp->sStructureType );
471
472
    }
473
    /**
474
     * Appends the JavaScript script of the framework in the head tag.
475
     *
476
     * @callback add_action() admin_head
477
     * @since    2.0.0
478
     * @since    2.1.5        Moved from AdminPageFramework_MetaBox. Changed the name from `addScript()` to `replyToAddScript()`.
479
     * @since    3.2.0        Moved from AdminPageFramework_Resource_post_meta_box.
480
     * @internal
481
     */
482
    public function _replyToAddScript() {
483
484
        $_oCaller = $this->oProp->oCaller;
485
        if ( ! $_oCaller->isInThePage() ) {
486
            return;
487
        }
488
489
        $this->_printCommonScripts( 'admin-page-framework-script-common', get_class() );
490
        $this->_printClassSpecificScripts( $this->_sClassSelector_Script . '-' . $this->oProp->sStructureType );
491
492
    }
493
494
    /**
495
     * Performs actual enqueuing items.
496
     *
497
     * @since       2.1.2
498
     * @since       2.1.5       Moved from the main class.
499
     * @param       array       $aEnqueueItem
500
     * @internal
501
     */
502
    protected function _enqueueSRC( $aEnqueueItem ) {
503
504
        $_sSRC = $this->___getSRCFormatted( $aEnqueueItem );
505
506
        // For styles
507
        if ( 'style' === $aEnqueueItem[ 'sType' ] ) {
508
            $this->___enqueueStyle( $_sSRC, $aEnqueueItem );
509
            return;
510
        }
511
512
        $this->___enqueueScript( $_sSRC, $aEnqueueItem );
513
514
    }
515
        /**
516
         * @param string $sSRC
517
         * @param array $aEnqueueItem
518
         * @since 3.9.0
519
         */
520
        private function ___enqueueScript( $sSRC, array $aEnqueueItem ) {
521
            wp_enqueue_script(
522
                $aEnqueueItem[ 'handle_id' ],
523
                $sSRC,
524
                $aEnqueueItem[ 'dependencies' ],
525
                $aEnqueueItem[ 'version' ],
526
                did_action( 'admin_body_class' ) || ( boolean ) $aEnqueueItem[ 'in_footer' ]
527
            );
528
            if ( $aEnqueueItem[ 'translation' ] ) {
529
                wp_localize_script(
530
                    $aEnqueueItem[ 'handle_id' ],
531
                    empty( $aEnqueueItem[ 'translation_var' ] ) ? $aEnqueueItem[ 'handle_id' ] : $aEnqueueItem[ 'translation_var' ],
532
                    $aEnqueueItem[ 'translation' ]
533
                );
534
            }
535
            if ( $aEnqueueItem[ 'conditional' ] ) {
536
                wp_script_add_data( $aEnqueueItem[ 'handle_id' ], 'conditional', $aEnqueueItem[ 'conditional' ] );
537
            }
538
        }
539
        /**
540
         * @param string $sSRC
541
         * @param array $aEnqueueItem
542
         * @since 3.9.0
543
         */
544
        private function ___enqueueStyle( $sSRC, array $aEnqueueItem ) {
545
            wp_enqueue_style(
546
                $aEnqueueItem[ 'handle_id' ],
547
                $sSRC,
548
                $aEnqueueItem[ 'dependencies' ],
549
                $aEnqueueItem[ 'version' ],
550
                $aEnqueueItem[ 'media' ]
551
            );
552
            $_aAddData = array( 'conditional', 'rtl', 'suffix', 'alt', 'title' );
553
            foreach( $_aAddData as $_sDataKey ) {
554
                if ( ! isset( $aEnqueueItem[ $_sDataKey ] ) ) {
555
                    continue;
556
                }
557
                wp_style_add_data( $aEnqueueItem[ 'handle_id' ], $_sDataKey, $aEnqueueItem[ $_sDataKey ] );
558
            }
559
        }
560
561
        /**
562
         * Formats the SRC value.
563
         * If a path is given and a .min file exists, it will be loaded.
564
         * @param  array $aEnqueueItem
565
         * @return string
566
         * @since  3.8.31
567
         */
568
        private function ___getSRCFormatted( array $aEnqueueItem ) {
569
570
            if ( ! $this->oProp->bAutoloadMinifiedResource ) {
571
                return $aEnqueueItem[ 'sSRC' ];
572
            }
573
574
            // If the site debug mode is on, use the one that user gave.
575
            if ( $this->isDebugMode() ) {
576
                return $aEnqueueItem[ 'sSRC' ];
577
            }
578
579
            // If the user gave a url, use it.
580
            if ( $this->isURL( $aEnqueueItem[ 'sSRCRaw' ] ) ) {
581
                return $aEnqueueItem[ 'sSRC' ];
582
            }
583
584
585
            // At this point, the user gave a path.
586
            $_sMinPrefix = '.min';
587
588
            // If the user already handles a min version, then use it.
589
            if ( false !== stripos( $aEnqueueItem[ 'sSRC' ], $_sMinPrefix ) ) {
590
                return $aEnqueueItem[ 'sSRC' ];
591
            }
592
593
            $_aPathParts = pathinfo( $aEnqueueItem[ 'sSRCRaw' ] )
594
                + array( 'dirname' => '', 'filename' => '', 'basename' => '', 'extension' => '' ); // avoid undefined index warnings
595
596
            // If there is no extension, avoid using a minified version.
597
            if ( ! $_aPathParts[ 'extension' ] ) {
598
                return $aEnqueueItem[ 'sSRC' ];
599
            }
600
601
            $_aPathPartsURL = pathinfo( $aEnqueueItem[ 'sSRC' ] )
602
                + array( 'dirname' => '', 'filename' => '', 'basename' => '', 'extension' => '' ); // avoid undefined index warnings
603
604
            $_sPathMinifiedVersion = $_aPathParts[ 'dirname' ] . '/' . $_aPathParts[ 'filename' ] . $_sMinPrefix . '.' . $_aPathParts[ 'extension' ];
605
            return file_exists( $_sPathMinifiedVersion )
606
                ? $_aPathPartsURL[ 'dirname' ] . '/' . $_aPathPartsURL[ 'filename' ] . $_sMinPrefix . '.' . $_aPathPartsURL[ 'extension' ]
607
                : $aEnqueueItem[ 'sSRC' ];
608
609
        }
610
611
    /**
612
     * Enqueues framework required common scripts.
613
     * @since 3.9.0
614
     * @deprecated 3.9.0 Unused at the moment
615
     */
616
    // public function _replyToEnqueueCommonScripts() {
617
    //     if ( $this->hasBeenCalled( 'COMMON_EXTERNAL_SCRIPTS: ' . __METHOD__ ) ) {
618
    //         return;
619
    //     }
620
        // Currently no common JS script is needed
621
        // $this->_addEnqueuingResourceByType(
622
        //     AdminPageFramework_Registry::$sDirPath . '/factory/_common/asset/js/common.js',
623
        //     array(
624
        //         'dependencies' => array( 'jquery' ),
625
        //         'in_footer' => true,
626
        //     ),
627
        //     'script'
628
        // );
629
    // }
630
    /**
631
     * Enqueues framework required common stylesheets.
632
     * @since    3.9.0
633
     * @callback action wp_enqueue_scripts
634
     */
635
    public function _replyToEnqueueCommonStyles() {
636
        if ( $this->hasBeenCalled( 'COMMON_EXTERNAL_STYLES: ' . __METHOD__ ) ) {
637
            return;
638
        }
639
        $this->_addEnqueuingResourceByType(
640
            AdminPageFramework_Registry::$sDirPath . '/factory/_common/asset/css/common.css',
641
            array(
642
                'version' => AdminPageFramework_Registry::VERSION,
643
            ),
644
            'style'
645
        );
646
    }
647
648
    /**
649
     * Takes care of added enqueuing scripts by checking the currently loading page.
650
     *
651
     * @remark      A callback for the admin_enqueue_scripts hook.
652
     * @since       2.1.2
653
     * @since       2.1.5   Moved from the main class. Changed the name from `enqueueStylesCalback` to `replyToEnqueueStyles()`.
654
     * @since       3.0.0   Changed the name to `_replyToEnqueueStyles()`.
655
     * @since       3.2.0   Changed it unset the enqueued item so that the method can be called multiple times.
656
     * @internal
657
     */
658
    public function _replyToEnqueueStyles() {
659
        foreach( $this->oProp->aEnqueuingStyles as $_sKey => $_aEnqueuingStyle ) {
660
            $this->_enqueueSRCByCondition( $_aEnqueuingStyle );
661
            unset( $this->oProp->aEnqueuingStyles[ $_sKey ] );
662
        }
663
    }
664
665
    /**
666
     * Takes care of added enqueuing scripts by page slug and tab slug.
667
     *
668
     * @remark      A callback for the admin_enqueue_scripts hook.
669
     * @since       2.1.2
670
     * @since       2.1.5   Moved from the main class. Changed the name from `enqueueScriptsCallback` to `callbackEnqueueScripts()`.
671
     * @since       3.0.0   Changed the name to `_replyToEnqueueScripts()`.
672
     * @since       3.2.0   Changed it unset the enqueued item so that the method can be called multiple times.
673
     * @internal
674
     */
675
    public function _replyToEnqueueScripts() {
676
        foreach( $this->oProp->aEnqueuingScripts as $_sKey => $_aEnqueuingScript ) {
677
            $this->_enqueueSRCByCondition( $_aEnqueuingScript );
678
            unset( $this->oProp->aEnqueuingScripts[ $_sKey ] );
679
        }
680
    }
681
682
    /**
683
     * A plural version of _addEnqueuingResourceByType()
684
     * @since  3.8.31
685
     * @param  array    $aSRCs          An array of SRCs
686
     * @param  array    $aCustomArgs    A custom argument array.
687
     * @param  string   $sType          Accepts 'style' or 'script'
688
     * @return string[] Added resource handle IDs.
689
     */
690
    public function _enqueueResourcesByType( $aSRCs, array $aCustomArgs=array(), $sType='style' ) {
691
        $_aHandleIDs = array();
692
        foreach( $aSRCs as $_sSRC ) {
693
            $_aHandleIDs[] = call_user_func_array( array( $this, '_addEnqueuingResourceByType' ), array( $_sSRC, $aCustomArgs, $sType ) );
694
        }
695
        return $_aHandleIDs;
696
    }
697
698
    /**
699
     * Store an enqueuing resource item to the property by type to process later at once.
700
     *
701
     * @since       3.5.3
702
     * @since       3.8.31      Moved from `AdminPageFramework_Resource_admin_page`.
703
     * @since       3.8.31      Renamed from `_enqueueResourceByType()`
704
     * @param       string      $sSRC           The source path or url.
705
     * @param       array       $aCustomArgs    A custom argument array.
706
     * @param       string      $sType          Accepts 'style' or 'script'
707
     * @return      string      The script handle ID if added. If the passed url is not a valid url string, an empty string will be returned.
708
     * @internal
709
     */
710
    public function _addEnqueuingResourceByType( $sSRC, array $aCustomArgs=array(), $sType='style' ) {
711
712
        $sSRC       = trim( $sSRC );
713
        if ( empty( $sSRC ) ) {
714
            return '';
715
        }
716
        $_sRawSRC   = wp_normalize_path( $sSRC );
717
        $_sSRC      = $this->getResolvedSRC( $_sRawSRC );
718
719
        // Get the property name for the type
720
        $_sContainerPropertyName     = $this->___getContainerPropertyNameByType( $sType );
721
        $_sEnqueuedIndexPropertyName = $this->___getEnqueuedIndexPropertyNameByType( $sType );
722
723
        $this->oProp->{$_sContainerPropertyName}[ $_sSRC ] = array_filter( $this->getAsArray( $aCustomArgs ), array( $this, 'isNotNull' ) )
724
            + array(
725
                'sSRCRaw'   => $_sRawSRC,
726
                'sSRC'      => $_sSRC,
727
                'sType'     => $sType,
728
                'handle_id' => $sType . '_' . strtolower( $this->oProp->sClassName ) . '_' .  ( ++$this->oProp->{$_sEnqueuedIndexPropertyName} ),
729
            )
730
            + self::$_aStructure_EnqueuingResources;
731
732
        // Store the attributes in another container by url.
733
        $this->oProp->aResourceAttributes[ $this->oProp->{$_sContainerPropertyName}[ $_sSRC ]['handle_id'] ] = $this->oProp->{$_sContainerPropertyName}[ $_sSRC ]['attributes'];
734
735
        return $this->oProp->{$_sContainerPropertyName}[ $_sSRC ][ 'handle_id' ];
736
737
    }
738
        /**
739
         * Returns the property name that contains the information of resources by type.
740
         * @since   3.5.3
741
         * @since   3.8.31      Moved from `AdminPageFramework_Resource_admin_page`.
742
         * @return  string      the property name that contains the information of resources by type.
743
         */
744
        private function ___getContainerPropertyNameByType( $sType ) {
745
            switch ( $sType ) {
746
                default:
747
                case 'style':
748
                    return 'aEnqueuingStyles';
749
                case 'script':
750
                    return 'aEnqueuingScripts';
751
            }
752
        }
753
        /**
754
         * Returns the property name that contains the added count of resources by type.
755
         * @since   3.5.3
756
         * @since   3.8.31      Moved from `AdminPageFramework_Resource_admin_page`.
757
         * @return  string      the property name that contains the added count of resources by type.
758
         */
759
        private function ___getEnqueuedIndexPropertyNameByType( $sType ) {
760
            switch ( $sType ) {
761
                default:
762
                case 'style':
763
                    return 'iEnqueuedStyleIndex';
764
                case 'script':
765
                    return 'iEnqueuedScriptIndex';
766
            }
767
        }
768
769
}