Completed
Branch dev (a4a708)
by
unknown
21:06
created

AdminPageFramework_Property_Base::__get()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 19
Code Lines 10

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 19
rs 9.2
cc 4
eloc 10
nc 4
nop 1
1
<?php
2
/**
3
 * Admin Page Framework
4
 * 
5
 * http://en.michaeluno.jp/admin-page-framework/
6
 * Copyright (c) 2013-2015 Michael Uno; Licensed MIT
7
 * 
8
 */
9
10
/**
11
 * The base class for Property classes.
12
 * 
13
 * Stores necessary data to render pages and its elements such as forms, including callback functions, resource (asset) localtions (paths and urls), inline script and stylesheet etc.
14
 * 
15
 * Provides the common methods  and properties for the property classes that are used by the main class, the meta box class, and the post type class.
16
 * @since       2.1.0
17
 * @package     AdminPageFramework
18
 * @subpackage  Property
19
 * @internal
20
 */ 
21
abstract class AdminPageFramework_Property_Base extends AdminPageFramework_WPUtility {
1 ignored issue
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
22
23
    /**
24
     * Represents the structure of the script info array.
25
     * @internal
26
     * @since       2.0.0
27
     * @since       3.0.0     Moved from the link class.
28
     */ 
29
    private static $_aStructure_CallerInfo = array(
30
        'sPath'         => null,
31
        'sType'         => null,
32
        'sName'         => null,     
33
        'sURI'          => null,
34
        'sVersion'      => null,
35
        'sThemeURI'     => null,
36
        'sScriptURI'    => null,
37
        'sAuthorURI'    => null,
38
        'sAuthor'       => null,
39
        'sDescription'  => null,
40
    );    
41
    
42
    /**
43
     * Stores the library information.
44
     * 
45
     * @remark Do not assign anything here because it is checked whether it is set.
46
     * @since 3.0.0
47
     */
48
    static public $_aLibraryData;
49
50
    /**
51
     * Defines the property type.
52
     * 
53
     * @since       3.3.1   This was defined in each extended classes.
54
     * @internal
55
     */
56
    public $_sPropertyType = '';    
57
    
58
    /**
59
     * Stores the main (caller) object.
60
     * 
61
     * @since 2.1.5
62
     */
63
    protected $oCaller;    
64
    
65
    /**
66
     * Stores the caller script file path.
67
     * 
68
     * @since 3.0.0
69
     */
70
    public $sCallerPath;
71
    
72
    /**
73
     * Stores the caller script data
74
     * 
75
     * @remark Do not even declare the variable name so that it triggers the getter method.
76
     * @since Unknown
77
     */
78
    // public $aScriptInfo;
79
    
80
    /**
81
     * Stores the extended class name that instantiated the property object.
82
     * 
83
     * @since     
84
     */
85
    public $sClassName;
86
    
87
    /**
88
     * The MD5 hash string of the extended class name.
89
     * @since     
90
     */
91
    public $sClassHash;
92
    
93
    /**
94
     * Stores the script to be embedded in the head tag.
95
     * 
96
     * @remark This should be an empty string by default since the related methods uses the append operator.
97
     * @since 2.0.0
98
     * @since 2.1.5 Moved from each extended property class.
99
     * @internal
100
     */             
101
    public $sScript = '';    
102
103
    /**
104
     * Stores the CSS rules to be embedded in the head tag.
105
     * 
106
     * @remark This should be an empty string by default since the related methods uses the append operator.
107
     * @since 2.0.0
108
     * @since 2.1.5 Moved from each extended property class.
109
     * @internal
110
     */         
111
    public $sStyle = '';
112
    
113
    /**
114
     * Stores the CSS rules for IE to be embedded in the head tag.
115
     * 
116
     * @remark This should be an empty string by default since the related methods uses the append operator.
117
     * @since 2.0.0 to 2.1.4
118
     * @internal
119
     */ 
120
    public $sStyleIE = '';    
121
122
    /**
123
     * Stores the field type definitions.
124
     * 
125
     * @since 2.1.5
126
     * @internal
127
     */
128
    public $aFieldTypeDefinitions = array();
129
    
130
    /**
131
     * The default JavaScript script loaded in the head tag of the created admin pages.
132
     * 
133
     * @since 3.0.0
134
     * @internal
135
     */
136
    public static $_sDefaultScript = "";
137
    
138
    /**
139
     * The default CSS rules loaded in the head tag of the created admin pages.
140
     * 
141
     * @since       2.0.0
142
     * @var         string
143
     * @static
144
     * @remark      It is accessed from the main class and meta box class.
145
     * @access      public    
146
     * @deprecated  3.2.0
147
     * @internal    
148
     */
149
    public static $_sDefaultStyle ="";    
150
        
151
    /**
152
     * The default CSS rules for IE loaded in the head tag of the created admin pages.
153
     * @since       2.1.1
154
     * @since       2.1.5       Moved the contents to the taxonomy field definition so it become an empty string.
155
     * @deprecated  3.2.0
156
     * @internal
157
     */
158
    public static $_sDefaultStyleIE = '';
159
        
160
    /**
161
     * Stores enqueuing script URLs and their criteria by md5 hash of the source url.
162
     * @since       2.1.2
163
     * @since       2.1.5       Moved to the base class.
164
     */
165
    public $aEnqueuingScripts = array();
166
    /**    
167
     * Stores enqueuing style URLs and their criteria by md5 hash of the source url.
168
     * @since       2.1.2
169
     * @since       2.1.5       Moved to the base class.
170
     */    
171
    public $aEnqueuingStyles = array();
172
173
174
    /**
175
     * Stores enqueued script/style argument array by its url.
176
     * @since       3.3.0
177
     */
178
    public $aResourceAttributes = array();
179
180
    
181
    /**
182
     * Stores the index of enqueued scripts.
183
     * 
184
     * @since       2.1.2
185
     * @since       2.1.5       Moved to the base class.
186
     */
187
    public $iEnqueuedScriptIndex = 0;
188
    /**
189
     * Stores the index of enqueued styles.
190
     * 
191
     * The index number will be incremented as a script is enqueued regardless a previously added enqueue item has been removed or not.
192
     * This is because this index number will be used for the script handle ID which is automatically generated.
193
     * 
194
     * @since       2.1.2
195
     * @since       2.1.5     Moved to the base class.
196
     */    
197
    public $iEnqueuedStyleIndex = 0;     
198
    
199
    /**
200
     * Stores is_admin() value to be reused. 
201
     * 
202
     * @since       3.0.0
203
     */
204
    public $bIsAdmin;
205
    
206
    /**
207
     * Stores the flag that indicates whether the library is minified or not.
208
     * @since       3.0.0
209
     * @deprecated  3.1.3   Use AdminPageFramework_Registry::$bIsMinifiedVersion
210
     */
211
    public $bIsMinifiedVersion;
212
        
213
    /**
214
     * Stores the capability for displayable elements.
215
     * 
216
     * @since       2.0.0
217
     */     
218
    public $sCapability;
219
    
220
    /**
221
     * Defines the fields type.
222
     * 
223
     * Can be either 'admin_page', 'network_admin_page', 'post_meta_box', 'page_meta_box', 'post_type', 'taxonomy_field'
224
     * 
225
     * @since       3.0.4
226
     * @internal
227
     */
228
    public $sStructureType;
229
        
230
    /**
231
     * Stores the text domain.
232
     * 
233
     * @since       3.0.4
234
     * @internal
235
     */ 
236
    public $sTextDomain;
237
    
238
    /**
239
     * Stores the current page's base name.
240
     * 
241
     * @since       3.0.5
242
     * @internal
243
     */
244
    public $sPageNow;
245
    
246
    /**
247
     * Indicates whether the setUp() method is loaded.
248
     *  
249
     * @since       3.1.0
250
     * @internal
251
     * @deprecated  DEVVER      To check if the `setUp()` is called, perform did_action( 'set_up_' . {instantiated class name} )
252
     */
253
    public $_bSetupLoaded;
254
    
255
    /**
256
     * Indicates whether the current page is in admin-ajax.php
257
     * 
258
     * @since       3.1.3
259
     * @internal
260
     */
261
    public $bIsAdminAjax;
262
        
263
    /**
264
     * Stores the label of the settings link embedded to the plugin listing table cell of the plugin title.
265
     * 
266
     * @since       3.1.0
267
     * @since       3.5.5       Moved from `AdminPageFramework_Property_Page` as the post type class also access it.
268
     * @remark      The default value should be `null` as the user may explicitly set an empty value.
269
     * The `null` value will be replaced with the system default text 'Settings' while an empty string '' will remove the link.
270
     */     
271
    public $sLabelPluginSettingsLink = null;
272
    
273
    /**
274
     * Stores the information to insert into the page footer.
275
     * 
276
     * The initially assigned text strings, `__SCRIPT_CREDIT__` and `__FRAMEWORK_CREDIT__` are reserved for the default values which will be replaced when the footer is being rendered.
277
     * 
278
     * @since       2.0.0
279
     * @since       3.5.5       Moved from `AdminpageFramework_Property_Page` as this is used by the post type link class and admin page link class.
280
     */             
281
    public $aFooterInfo = array(
282
        'sLeft'     => '__SCRIPT_CREDIT__',
283
        'sRight'    => '__FRAMEWORK_CREDIT__',
284
    );    
285
286
    /**
287
     * The utility object.
288
     * @since       3.5.3
289
     * @deprecated  DEVVER
290
     */
291
    public $oUtil;
292
              
293
    /**
294
     * Stores the action hook name that gets triggered when the form registration is performed.
295
     * 'admin_page' and 'network_admin_page' will use a custom hook for it.
296
     * @since       DEVVER
297
     * @access      public
298
     */
299
    public $_sFormRegistrationHook = 'current_screen';
300
              
301
    /**
302
     * Stores arguments for the form object.
303
     * @since       DEVVER
304
     */
305
    public $aFormArguments = array(
306
        'caller_id'                         => '',
307
        'structure_type'                    => '',
308
        'action_hook_form_registration'     => '',
309
    );
310
    
311
    /**
312
     * Stores callbacks for the form object.
313
     * @since       DEVVER
314
     */
315
    public $aFormCallbacks = array(
316
        'hfID'              => null,    // the input id attribute
317
        'hfTagID'           => null,    // the field container id attribute
318
        'hfName'            => null,    // the field name attribute
319
        'hfNameFlat'        => null,    // the flat field name attribute
320
        'hfInputName'       => null,    // 3.6.0+   the field input name attribute
321
        'hfInputNameFlat'   => null,    // 3.6.0+   the flat field input name 
322
        'hfClass'           => null,    // the class attribute       
323
    );
324
              
325
    /**
326
     * Sets up necessary property values.
327
     */
328
    public function __construct( $oCaller, $sCallerPath, $sClassName, $sCapability, $sTextDomain, $sStructureType ) {
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
329
                
330
        $this->oCaller          = $oCaller;
331
        $this->sCallerPath      = $this->getAOrB(
332
            $sCallerPath,
333
            $sCallerPath,
334
            null
335
        );
336
337
        $this->sClassName       = $sClassName; // sanitize name space path delimiter.
338
        $this->sClassHash       = md5( $sClassName );    
339
        $this->sCapability      = $this->getAOrB(
340
            empty( $sCapability ),
341
            'manage_options',
342
            $sCapability
343
        );
344
        $this->sTextDomain      = $this->getAOrB(
345
            empty( $sTextDomain ),
346
            'admin-page-framework',
347
            $sTextDomain
348
        );
349
        $this->sStructureType      = $sStructureType;
350
        
351
        $GLOBALS[ 'aAdminPageFramework' ] = $this->getElementAsArray(
352
            $GLOBALS,
353
            'aAdminPageFramework',
354
            array( 'aFieldFlags' => array() )
355
        );
356
        
357
        $this->sPageNow         = $this->getPageNow();
358
        $this->bIsAdmin         = is_admin();
359
        $this->bIsAdminAjax     = in_array( $this->sPageNow, array( 'admin-ajax.php' ) );
360
           
361
        $this->aFormArguments = array(
362
            'caller_id'                         => $this->sClassName,
363
            'structure_type'                    => $this->_sPropertyType,  // @todo change this to admin_page
364
            'action_hook_form_registration'     => $this->_sFormRegistrationHook,
365
        ) + $this->aFormArguments;
366
           
367
        $this->aFormCallbacks = array(
368
            'is_in_the_page'                    => array( $oCaller, '_replyToDetermineWhetherToProcessFormRegistration' ),
369
            'load_fieldset_resource'            => array( $oCaller, '_replyToFieldsetReourceRegistration' ),
370
            
371
'is_fieldset_registration_allowed'  => null,
372
373
            'capability'                        => array( $oCaller, '_replyToGetCapabilityForForm' ),
374
            'saved_data'                        => array( $oCaller, '_replyToGetSavedFormData' ),
375
            
376
            // Outputs
377
            'section_head_output'               => array( $oCaller, '_replyToGetSectionHeaderOutput' ),
378
            'fieldset_output'                   => array( $oCaller, '_replyToGetFieldOutput' ),
379
             
380
            // 
381
            'sectionset_before_output'          => array( $oCaller, '_replyToFormatSectionsetDefinition' ),
382
            'fieldset_before_output'            => array( $oCaller, '_replyToFormatFieldsetDefinition' ),
383
            'fieldset_after_formatting'         => array( $oCaller, '_replyToModifyFieldsetDefinition' ),
384
            'fieldsets_after_formatting'        => array( $oCaller, '_replyToModifyFieldsetsDefinitions' ),
385
            
386
            'is_sectionset_visible'             => array( $oCaller, '_replyToDetermineSectionsetVisibility' ),
387
            'is_fieldset_visible'               => array( $oCaller, '_replyToDetermineFieldsetVisibility' ),
388
            
389
            'secitonsets_before_registration'   => array( $oCaller, '_replyToModifySectionsets' ),
390
            'fieldsets_before_registration'     => array( $oCaller, '_replyToModifyFieldsets' ),
391
            
392
            'handle_form_data'                  => array( $oCaller, '_replyToHandleSubmittedFormData' ),        
393
            
394
            // legacy callbacks
395
            'hfID'                              => array( $oCaller, '_replyToGetInputID' ), // the input id attribute
396
            'hfTagID'                           => array( $oCaller, '_replyToGetInputTagIDAttribute' ), // the fields & fieldset & field row container id attribute
397
            'hfName'                            => array( $oCaller, '_replyToGetFieldNameAttribute' ), // the input name attribute
398
            'hfNameFlat'                        => array( $oCaller, '_replyToGetFlatFieldName' ), // the flat input name attribute
399
            'hfInputName'                       => array( $oCaller, '_replyToGetInputNameAttribute' ),    // 3.6.0+   the field input name attribute
400
            'hfInputNameFlat'                   => array( $oCaller, '_replyToGetFlatInputName' ),    // 3.6.0+   the flat field input name                 
401
            'hfClass'                           => array( $oCaller, '_replyToGetInputClassAttribute' ), // the class attribute
402
            'hfSectionName'                     => array( $oCaller, '_replyToGetSectionName' ), // 3.6.0+            
403
        ) + $this->aFormCallbacks;
404
        
405
        $this->_setDeprecated();
406
        
407
    }
408
        /**
409
         * Sets deprecated property items for backward compatibility.
410
         * @since       DEVVER
411
         */
412
        private function _setDeprecated() {
413
            $this->oUtil            = new AdminPageFramework_WPUtility;
0 ignored issues
show
Deprecated Code introduced by
The property AdminPageFramework_Property_Base::$oUtil has been deprecated with message: DEVVER

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...
414
        }
415
        
416
    /**
417
     * Returns the caller object.
418
     * 
419
     * This is used from other sub classes that need to retrieve the caller object.
420
     * 
421
     * @since       2.1.5
422
     * @access      public    
423
     * @return      object The caller class object.
424
     * @internal
425
     */     
426
    public function _getCallerObject() {
427
        return $this->oCaller;
428
    }
429
    
430
    /**
431
     * Sets the library information property array.
432
     * @internal
433
     * @since       3.0.0
434
     */
435
    static public function _setLibraryData() {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
436
437
        self::$_aLibraryData = array(
438
            'sName'         => AdminPageFramework_Registry::NAME,
439
            'sURI'          => AdminPageFramework_Registry::URI,
440
            'sScriptName'   => AdminPageFramework_Registry::NAME,
441
            'sLibraryName'  => AdminPageFramework_Registry::NAME,
442
            'sLibraryURI'   => AdminPageFramework_Registry::URI,
443
            'sPluginName'   => '',
444
            'sPluginURI'    => '',
445
            'sThemeName'    => '',
446
            'sThemeURI'     => '',
447
            'sVersion'      => AdminPageFramework_Registry::getVersion(),
448
            'sDescription'  => AdminPageFramework_Registry::DESCRIPTION,
449
            'sAuthor'       => AdminPageFramework_Registry::AUTHOR,
450
            'sAuthorURI'    => AdminPageFramework_Registry::AUTHOR_URI,
451
            'sTextDomain'   => AdminPageFramework_Registry::TEXT_DOMAIN,
452
            'sDomainPath'   => AdminPageFramework_Registry::TEXT_DOMAIN_PATH,
453
            'sNetwork'      => '',
454
            '_sitewide'     => '',
455
        );
456
        return self::$_aLibraryData;
457
        
458
    }
459
    /**
460
     * Returns the set library data array.
461
     * 
462
     * @internal
463
     * @since       3.0.0
464
     */
465
    static public function _getLibraryData() {
1 ignored issue
show
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
466
        return isset( self::$_aLibraryData ) 
467
            ? self::$_aLibraryData 
468
            : self::_setLibraryData();     
469
    }
470
    
471
    /*
472
     * Methods for getting script info.
473
     */      
474
    /**
475
     * Retrieves the caller script information whether it's a theme or plugin or something else.
476
     * 
477
     * @since       2.0.0
478
     * @since       3.0.0       Moved from the link class.
479
     * @remark      The information can be used to embed into the footer etc.
480
     * @return      array       The information of the script.
481
     */  
482
    protected function getCallerInfo( $sCallerPath=null ) {
483
        
484
        $_aCallerInfo          = self::$_aStructure_CallerInfo;
485
        $_aCallerInfo['sPath'] = $sCallerPath;
486
        $_aCallerInfo['sType'] = $this->_getCallerType( $_aCallerInfo['sPath'] );
487
488
        if ( 'unknown' == $_aCallerInfo['sType'] ) {
489
            return $_aCallerInfo;
490
        }
491
        if ( 'plugin' == $_aCallerInfo['sType'] ) {
492
            return $this->getScriptData( $_aCallerInfo['sPath'], $_aCallerInfo['sType'] ) + $_aCallerInfo;
493
        }
494
        if ( 'theme' == $_aCallerInfo['sType'] ) {
495
            $_oTheme = wp_get_theme(); // stores the theme info object
496
            return array(
497
                'sName'         => $_oTheme->Name,
498
                'sVersion'      => $_oTheme->Version,
499
                'sThemeURI'     => $_oTheme->get( 'ThemeURI' ),
500
                'sURI'          => $_oTheme->get( 'ThemeURI' ),
501
                'sAuthorURI'    => $_oTheme->get( 'AuthorURI' ),
502
                'sAuthor'       => $_oTheme->get( 'Author' ),     
503
            ) + $_aCallerInfo;    
504
        }
505
        return array();
506
    }    
507
    
508
    /**
509
     * Determines the script type.
510
     * 
511
     * It tries to find what kind of script this is, theme, plugin or something else from the given path.
512
     * 
513
     * @since       2.0.0
514
     * @since       3.0.0       Moved from the link class.
515
     * @since       3.1.5       Changed the scope to protected as the post type property class access it.
516
     * @return      string      Returns either 'theme', 'plugin', or 'unknown'
517
     */ 
518
    protected function _getCallerType( $sScriptPath ) {
519
        
520
        if ( preg_match( '/[\/\\\\]themes[\/\\\\]/', $sScriptPath, $m ) ) {
521
            return 'theme';
522
        }
523
        if ( preg_match( '/[\/\\\\]plugins[\/\\\\]/', $sScriptPath, $m ) ) {
524
            return 'plugin';
525
        }
526
        return 'unknown';    
527
    
528
    }    
529
            
530
    /**
531
     * Retrieves the option array.
532
     * 
533
     * This method should be extended in the extended class.
534
     * 
535
     * @remark      This method is triggered from the __get() overload magic method to set the $aOptions property.
536
     * @since       3.1.0
537
     * @internal
538
     */
539
    protected function _getOptions() {
540
        return array();
541
    }
542
    
543
    /*
544
     * Magic methods
545
     * */
546
    /**
547
     * 
548
     * @since 3.1.3
549
     */
550
    public function __get( $sName ) {
551
        
552
        if ( 'aScriptInfo' === $sName ) {
553
            $this->sCallerPath = $this->sCallerPath 
554
                ? $this->sCallerPath 
555
                : $this->getCallerScriptPath( __FILE__ );
0 ignored issues
show
Documentation introduced by
__FILE__ is of type string, 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...
556
            $this->aScriptInfo = $this->getCallerInfo( $this->sCallerPath );
0 ignored issues
show
Bug introduced by
The property aScriptInfo does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
557
            return $this->aScriptInfo;    
558
        }
559
        
560
        // 3.4.1+ Moved from `AdminPageFramework_Property_Page` as meta box classes also access it.
561
        // If $this->aOptions is called for the first time, retrieve the option data from the database and assign them to the property.
562
        // Once this is done, calling $this->aOptions will not trigger the __get() magic method any more.
563
        if ( 'aOptions' === $sName ) {
564
            $this->aOptions = $this->_getOptions();
0 ignored issues
show
Bug introduced by
The property aOptions does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
565
            return $this->aOptions;    
566
        }        
567
        
568
    }
569
    
570
}