Completed
Branch master (a559c4)
by
unknown
04:06
created

_getAutoCallback()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 18
rs 9.4286
cc 3
eloc 9
nc 3
nop 2
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
 * Provides routing functionality to the Admin Page Framework factory object based on the fields type.
12
 * 
13
 * This class mainly deals with routing function calls and instantiation of objects based on the type.
14
 * 
15
 * @abstract
16
 * @since       3.0.4
17
 * @package     AdminPageFramework
18
 * @subpackage  Factory
19
 * @internal
20
 * @method      void    start()   User constructor. Defined in `AdminPageFramework_Factory_Controller`.
21
 * @method      void    _setUp()    
22
 */
23
abstract class AdminPageFramework_Factory_Router {
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...
24
    
25
    /**
26
     * Stores the property object.
27
     * 
28
     * @since       2.0.0
29
     * @access      public      The AdminPageFramework_Page_MetaBox class accesses it.
30
     */     
31
    public $oProp;    
32
    
33
    /**
34
     * The object that provides the debug methods. 
35
     * 
36
     * @internal
37
     * @access      public
38
     * @since       2.0.0
39
     * @since       3.1.0   Changed the scope to public from protected.
40
     */     
41
    public $oDebug;
42
    /**
43
     * Provides the utility methods. 
44
     * 
45
     * @internal
46
     * @since       2.0.0
47
     * @since       3.1.0     Changed the scope to public from protected.
48
     */         
49
    public $oUtil;
50
    /**
51
     * Provides the methods for text messages of the framework. 
52
     * 
53
     * @since       2.0.0
54
     * @since       3.1.0     Changed the scope to public from protected.
55
     * @access      public
56
     * @internal
57
     */         
58
    public $oMsg;
59
    
60
    /**
61
     * The form object that provides methods to handle form sections and fields.
62
     * @internal
63
     * @since       3.0.0
64
     * @since       3.5.2       Changed the scope to public from protected as the widget class needs to initialize this object.
65
     */     
66
    public $oForm;
67
    
68
    /**
69
     * Inserts page load information into the footer area of the page. 
70
     * 
71
     */
72
    protected $oPageLoadInfo;
73
    
74
    /**
75
     * Provides the methods to insert head tag elements.
76
     * 
77
     * @since   3.3.0   Changed the name from $oHeadTag as it has become to deal with footer elements.
78
     */
79
    protected $oResource;
80
    
81
    /**
82
     * Provides the methods to insert head tag elements.
83
     * @deprecated
84
     */
85
    protected $oHeadTag;
86
    
87
    /**
88
     * Provides methods to manipulate contextual help pane.
89
     */
90
    protected $oHelpPane;
91
    
92
    /**
93
     * Provides the methods for creating HTML link elements. 
94
     * 
95
     */    
96
    protected $oLink;
97
    
98
    /**
99
     * Stores sub-class names.
100
     * 
101
     * Used in the __get() method to check whether a method with the name of the property should be called or not.
102
     * 
103
     * @since       3.5.3
104
     */
105
    protected $_aSubClassNames = array(
106
        'oDebug', 
107
        'oUtil',
108
        'oMsg',
109
        'oForm',
110
        'oPageLoadInfo',
111
        'oResource',
112
        'oHelpPane',
113
        'oLink',
114
    );
115
    
116
    /**
117
     * Sets up built-in objects.
118
     */
119
    public function __construct( $oProp ) {
120
121
        // Let them overload.
122
        unset( 
123
            $this->oDebug, 
124
            $this->oUtil, 
125
            $this->oMsg, 
126
            $this->oForm, 
127
            $this->oPageLoadInfo,
128
            $this->oResource,
129
            $this->oHelpPane,
130
            $this->oLink
131
        );
132
        
133
        // Property object
134
        $this->oProp = $oProp;
135
    
136
        if ( $this->oProp->bIsAdmin && ! $this->oProp->bIsAdminAjax ) {
137
            add_action( 'current_screen', array( $this, '_replyToLoadComponents' ) );
138
        }
139
        
140
        // Call the start method - defined in the controller class.
141
        $this->start();    
142
        
143
    }    
144
        
145
        /**
146
         * Determines whether the class component classes should be instantiated or not.
147
         * 
148
         * @internal
149
         * @callback    action      current_screen
150
         * @return      void
151
         */
152
        public function _replyToLoadComponents( /* $oScreen */ ) {
153
154
            if ( 'plugins.php' === $this->oProp->sPageNow ) {
155
                // triggers __get() if not set.
156
                $this->oLink = $this->oLink;
157
            }
158
    
159
            if ( ! $this->_isInThePage() ) { 
160
                return; 
161
            }
162
            
163
            // Do not load widget resources in the head tag because widgets can be loaded in any page unless it is in customize.php.
164
            if ( in_array( $this->oProp->_sPropertyType, array( 'widget' ) ) && 'customize.php' !== $this->oProp->sPageNow ) {
165
                return;
166
            }
167
            
168
            $this->_setSubClasses();
169
            
170
        }
171
            /**
172
             * Sets sub-classes.
173
             * 
174
             * This method forces the overload method __get() to be triggered if those sub-class objects
175
             * are not set.
176
             * 
177
             * @since       3.5.3
178
             * @internal
179
             * @return      void
180
             */
181
            private function _setSubClasses() {
182
                $this->oResource        = $this->oResource;
183
                $this->oHeadTag         = $this->oResource; // backward compatibility                
0 ignored issues
show
Deprecated Code introduced by
The property AdminPageFramework_Factory_Router::$oHeadTag has been deprecated.

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...
184
                $this->oLink            = $this->oLink;
185
                $this->oPageLoadInfo    = $this->oPageLoadInfo;
186
            }
187
188
    /**
189
     * Determines whether the class object is instantiatable in the current page.
190
     * 
191
     * This method should be redefined in the extended class.
192
     * 
193
     * @since       3.1.0
194
     * @internal
195
     */ 
196
    protected function _isInstantiatable() { return true; }
197
    
198
    /**
199
     * Determines whether the instantiated object and its producing elements belong to the loading page.
200
     * 
201
     * This method should be redefined in the extended class.
202
     * 
203
     * @since       3.0.3
204
     * @since       3.2.0   Changed the scope to public from protected as the head tag object will access it.
205
     * @internal
206
     */
207
    public function _isInThePage() { return true; }
208
    
209
    /**
210
     * Stores class names by fields type for form element objects.
211
     * @since       3.5.3
212
     */    
213
    protected $_aFormElementClassNameMap = array(
214
        'page'                  => 'AdminPageFramework_FormDefinition_Page',
215
        'network_admin_page'    => 'AdminPageFramework_FormDefinition_Page',
216
        'post_meta_box'         => 'AdminPageFramework_FormDefinition_Meta',
217
        'page_meta_box'         => 'AdminPageFramework_FormDefinition',
218
        'post_type'             => 'AdminPageFramework_FormDefinition',
219
        'taxonomy'              => 'AdminPageFramework_FormDefinition',
220
        'widget'                => 'AdminPageFramework_FormDefinition',
221
        'user_meta'             => 'AdminPageFramework_FormDefinition_Meta',
222
    );        
223
    /**
224
     * Instantiate a form object based on the type.
225
     * 
226
     * @since       3.1.0
227
     * @internal
228
     * @return      object|null
229
     */
230
    protected function _getFormInstance( $oProp ) {
231
232
        if ( 
233
            in_array( 
234
                $oProp->sFieldsType, 
235
                array( 'page', 'network_admin_page', 'post_meta_box', 'post_type' )
236
            ) 
237
            && $oProp->bIsAdminAjax 
238
        ) {
239
            return null;
240
        }
241
        return $this->_getInstanceByMap( 
242
            $this->_aFormElementClassNameMap,   // map
243
            $oProp->sFieldsType,    // key
244
            $oProp->sFieldsType,    // parameter 1
245
            $oProp->sCapability,    // parameter 2
246
            $this   // parameter 3
247
        );
248
        
249
    }
250
    
251
    /**
252
     * Stores class names by fields type for help pane objects.
253
     * @since       3.5.3
254
     */    
255
    protected $_aResourceClassNameMap = array(
256
        'page'                  => 'AdminPageFramework_Resource_Page',
257
        'network_admin_page'    => 'AdminPageFramework_Resource_Page',
258
        'post_meta_box'         => 'AdminPageFramework_Resource_MetaBox',
259
        'page_meta_box'         => 'AdminPageFramework_Resource_MetaBox_Page',
260
        'post_type'             => 'AdminPageFramework_Resource_PostType',
261
        'taxonomy'              => 'AdminPageFramework_Resource_TaxonomyField',
262
        'widget'                => 'AdminPageFramework_Resource_Widget',
263
        'user_meta'             => 'AdminPageFramework_Resource_UserMeta',
264
    );        
265
    /**
266
     * Instantiate a resource handler object based on the type.
267
     * 
268
     * @since       3.0.4
269
     * @internal
270
     */
271
    protected function _getResourceInstance( $oProp ) {
272
        return $this->_getInstanceByMap( $this->_aResourceClassNameMap, $oProp->sFieldsType, $oProp );    
273
    }
274
    
275
    /**
276
     * Stores class names by fields type for help pane objects.
277
     * @since       3.5.3
278
     */    
279
    protected $_aHelpPaneClassNameMap = array(
280
        'page'                  => 'AdminPageFramework_HelpPane_Page',
281
        'network_admin_page'    => 'AdminPageFramework_HelpPane_Page',
282
        'post_meta_box'         => 'AdminPageFramework_HelpPane_MetaBox',
283
        'page_meta_box'         => 'AdminPageFramework_HelpPane_MetaBox_Page',
284
        'post_type'             => null,    // no help pane class for the post type factory class.
285
        'taxonomy'              => 'AdminPageFramework_HelpPane_TaxonomyField',
286
        'widget'                => 'AdminPageFramework_HelpPane_Widget',
287
        'user_meta'             => 'AdminPageFramework_HelpPane_UserMeta',
288
    );    
289
    /**
290
     * Instantiates a help pane object based on the type.
291
     * 
292
     * @since       3.0.4
293
     * @internal
294
     */
295
    protected function _getHelpPaneInstance( $oProp ) {
296
        return $this->_getInstanceByMap( $this->_aHelpPaneClassNameMap, $oProp->sFieldsType, $oProp );
297
    }
298
    
299
    /**
300
     * Stores class names by fields type for link objects.
301
     * @since       3.5.3
302
     */
303
    protected $_aLinkClassNameMap = array(
304
        'page'                  => 'AdminPageFramework_Link_Page',
305
        'network_admin_page'    => 'AdminPageFramework_Link_NetworkAdmin',
306
        'post_meta_box'         => null,
307
        'page_meta_box'         => null,
308
        'post_type'             => 'AdminPageFramework_Link_PostType', 
309
        'taxonomy'              => null,
310
        'widget'                => null,
311
        'user_meta'             => null,
312
    );    
313
    /**
314
     * Instantiates a link object based on the type.
315
     * 
316
     * @since       3.0.4
317
     * @internal
318
     */
319
    protected function _getLinkInstancce( $oProp, $oMsg ) {
320
        return $this->_getInstanceByMap( $this->_aLinkClassNameMap, $oProp->sFieldsType, $oProp, $oMsg );
321
    }
322
    
323
    /**
324
     * Stores class names by fields type for page load objects.
325
     * @since       3.5.3
326
     */
327
    protected $_aPageLoadClassNameMap = array(
328
        'page'                  => 'AdminPageFramework_PageLoadInfo_Page',
329
        'network_admin_page'    => 'AdminPageFramework_PageLoadInfo_NetworkAdminPage',
330
        'post_meta_box'         => null,
331
        'page_meta_box'         => null,
332
        'post_type'             => 'AdminPageFramework_PageLoadInfo_PostType', 
333
        'taxonomy'              => null,
334
        'widget'                => null,
335
        'user_meta'             => null,
336
    );
337
    /**
338
     * Instantiates a page load object based on the type.
339
     * 
340
     * @since 3.0.4
341
     * @internal
342
     */
343
    protected function _getPageLoadInfoInstance( $oProp, $oMsg ) {
344
        
345
        if ( ! isset( $this->_aPageLoadClassNameMap[ $oProp->sFieldsType ] ) ) {
346
            return null;
347
        }
348
        $_sClassName = $this->_aPageLoadClassNameMap[ $oProp->sFieldsType ];
349
        return call_user_func_array( array( $_sClassName, 'instantiate' ), array( $oProp, $oMsg ) );
350
351
    }
352
    
353
    /**
354
     * Returns a class object instance by the given map array and the key, plus one or two arguments.
355
     * 
356
     * @remark      There is a limitation that only can accept up to 3 parameters at the moment. 
357
     * @internal
358
     * @since       3.5.3
359
     * @return      null|object
360
     */
361
    private function _getInstanceByMap( /* array $aClassNameMap, $sKey, $mParam1, $mParam2, $mParam3 */ ) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
362
        
363
        $_aParams       = func_get_args();
364
        $_aClassNameMap = array_shift( $_aParams );
365
        $_sKey          = array_shift( $_aParams );
366
        
367
        if ( ! isset( $_aClassNameMap[ $_sKey ] ) ) {
368
            return null;
369
        }
370
        
371
        $_iParamCount = count( $_aParams );
372
        
373
        // passing more than 3 arguments is not supported at the moment.
374
        if ( $_iParamCount > 3 ) {
375
            return null;
376
        }
377
        
378
        // Insert the class name at the beginning of the parameter array.
379
        array_unshift( $_aParams, $_aClassNameMap[ $_sKey ] );    
380
        
381
        // Instantiate the class and return the instance.
382
        return call_user_func_array( 
383
            array( $this, "_replyToGetClassInstanceByArgumentOf{$_iParamCount}" ), 
384
            $_aParams
385
        );
386
    
387
    }
388
        /**#@+
389
         * @internal
390
         * @return      object
391
         */      
392
        /**
393
         * Instantiate a class with zero parameter.
394
         * @since       3.5.3
395
         */
396
        private function _replyToGetClassInstanceByArgumentOf0( $sClassName ) {
397
            return new $sClassName;
398
        }    
399
        /**
400
         * Instantiate a class with one parameter.
401
         * @since       3.5.3
402
         */        
403
        private function _replyToGetClassInstanceByArgumentOf1( $sClassName, $mArg ) {
404
            return new $sClassName( $mArg );
405
        }
406
        /**
407
         * Instantiate a class with two parameters.
408
         * @since       3.5.3
409
         */             
410
        private function _replyToGetClassInstanceByArgumentOf2( $sClassName, $mArg1, $mArg2 ) {
411
            return new $sClassName( $mArg1, $mArg2 );
412
        }      
413
        /**
414
         * Instantiate a class with two parameters.
415
         * @since       3.5.3
416
         */             
417
        private function _replyToGetClassInstanceByArgumentOf3( $sClassName, $mArg1, $mArg2, $mArg3 ) {
418
            return new $sClassName( $mArg1, $mArg2, $mArg3 );
419
        }              
420
        /**#@-*/        
421
    
422
    /**
423
     * Responds to a request of an undefined property.
424
     * 
425
     * This is used to instantiate classes only when necessary, rather than instantiating them all at once.
426
     * 
427
     * @internal
428
     */
429
    public function __get( $sPropertyName ) {
430
            
431
        switch( $sPropertyName ) {
432
            case 'oHeadTag':    // 3.3.0+ for backward compatibility
433
                $sPropertyName = 'oResource';
434
                break;
435
        }     
436
437
        // Set and return the sub class object instance.
438
        if ( in_array( $sPropertyName, $this->_aSubClassNames ) ) {            
439
            return call_user_func( 
440
                array( $this, "_replyTpSetAndGetInstance_{$sPropertyName}"  )
441
            );
442
        }
443
        
444
    }
445
        /**#@+
446
         * @internal
447
         * @return      object
448
         * @callback    function    call_user_func
449
         */          
450
        /**
451
         * Sets and returns the `oUtil` property.
452
         * @since       3.5.3
453
         */
454
        public function _replyTpSetAndGetInstance_oUtil() {
455
            $this->oUtil = new AdminPageFramework_WPUtility;
456
            return $this->oUtil;
457
        }
458
        /**
459
         * Sets and returns the `oDebug` property.
460
         * @since       3.5.3
461
         */        
462
        public function _replyTpSetAndGetInstance_oDebug() {
463
            $this->oDebug = new AdminPageFramework_Debug;
464
            return $this->oDebug;
465
        }
466
        /**
467
         * Sets and returns the `oMsg` property.
468
         * @since       3.5.3
469
         */              
470
        public function _replyTpSetAndGetInstance_oMsg() {
471
            $this->oMsg = AdminPageFramework_Message::getInstance( $this->oProp->sTextDomain );
472
            return $this->oMsg;
473
        }
474
        /**
475
         * Sets and returns the `oForm` property.
476
         * @since       3.5.3
477
         */              
478
        public function _replyTpSetAndGetInstance_oForm() {
479
            $this->oForm = $this->_getFormInstance( $this->oProp );
480
            return $this->oForm;
481
        }
482
        /**
483
         * Sets and returns the `oResouce` property.
484
         * @since       3.5.3
485
         */            
486
        public function _replyTpSetAndGetInstance_oResource() {
487
            $this->oResource = $this->_getResourceInstance( $this->oProp );
488
            return $this->oResource;
489
        }
490
        /**
491
         * Sets and returns the `oHelpPane` property.
492
         * @since       3.5.3
493
         */
494
        public function _replyTpSetAndGetInstance_oHelpPane() {
495
            $this->oHelpPane = $this->_getHelpPaneInstance( $this->oProp );
496
            return $this->oHelpPane;
497
        }
498
        /**
499
         * Sets and returns the `oLink` property.
500
         * @since       3.5.3
501
         */
502
        public function _replyTpSetAndGetInstance_oLink() {
503
            $this->oLink = $this->_getLinkInstancce( $this->oProp, $this->oMsg );
504
            return $this->oLink;
505
        }
506
        /**
507
         * Sets and returns the `oPageLoadInfo` property.
508
         * @since       3.5.3
509
         */        
510
        public function _replyTpSetAndGetInstance_oPageLoadInfo() {
511
            $this->oPageLoadInfo = $this->_getPageLoadInfoInstance( $this->oProp, $this->oMsg );
512
            return $this->oPageLoadInfo;
513
        }
514
        /**#@-*/
515
        
516
    /**
517
     * Redirects dynamic function calls to the pre-defined internal method.
518
     * 
519
     * @internal
520
     */
521
    public function __call( $sMethodName, $aArguments=null ) {    
522
         
523
        $_mFirstArg = $this->oUtil->getElement( $aArguments, 0 );
524
        
525
        switch ( $sMethodName ) {
526
            case 'validate':
527
            case 'content':
528
                return $_mFirstArg;
529
            case 'setup_pre':
530
                $this->_setUp();
531
                
532
                // This action hook must be called AFTER the _setUp() method as there are callback methods that hook into this hook and assumes required configurations have been made.
533
                $this->oUtil->addAndDoAction( 
534
                    $this, 
535
                    "set_up_{$this->oProp->sClassName}", 
536
                    $this 
537
                );
538
                $this->oProp->_bSetupLoaded = true;            
539
                return;
540
        }
541
        
542
        // If it is called with the framework auto-callback,
543
        if ( has_filter( $sMethodName ) ) {
544
            return $this->_getAutoCallback( $sMethodName, $aArguments );
545
        }
546
                
547
        $this->_triggerUndefinedMethodWarning( $sMethodName );
548
        
549
    }     
550
        /**
551
         * Returns the first parameter value if the method name does not contain a backslash.
552
         * If it contains a backslash, the user uses a name-spaced class name. In that case,
553
         * the backslashes need to be converted to underscores to support valid PHP method names.
554
         * 
555
         * @since       3.6.6
556
         */
557
        private function _getAutoCallback( $sMethodName, $aArguments ) {
558
            
559
            // Check if the method name contains a backslash.
560
            if ( false === strpos( $sMethodName, "\\" ) ) {
561
                return $this->oUtil->getElement( $aArguments, 0 );  // the first element - the filter value
562
            }
563
                
564
            // if the method name contains a backslash, the user may be using a name space. 
565
            // In that case, convert the backslash to underscore and call the method.
566
            $_sAutoCallbackClassName = str_replace( '\\', '_', $this->oProp->sClassName );
567
            return method_exists( $this, $_sAutoCallbackClassName )
568
                ? call_user_func_array(
569
                    array( $this, $_sAutoCallbackClassName ),
570
                    $aArguments
571
                )
572
                : $this->oUtil->getElement( $aArguments, 0 );   // the first argument
573
            
574
        }
575
        
576
        /**
577
         * @since   3.6.6
578
         * @return  void
579
         */
580
        private function _triggerUndefinedMethodWarning( $sMethodName ) {
581
            trigger_error(
582
                AdminPageFramework_Registry::NAME . ': ' 
583
                    . sprintf( 
584
                        __( 'The method is not defined: %1$s', $this->oProp->sTextDomain ),
585
                        $sMethodName 
586
                    ), 
587
                E_USER_WARNING 
588
            );            
589
        }
590
                
591
    
592
    /**
593
     * Prevents the output from getting too long when the object is dumped.
594
     *
595
     * Field definition arrays contain the factory object reference and when the debug log method tries to dump it, the output gets too long.
596
     * So shorten it here.
597
     * 
598
     * @remark      Called when the object is called as a string.
599
     * @since       3.4.4
600
     */   
601
    public function __toString() {
602
        return $this->oUtil->getObjectInfo( $this );        
603
    }
604
 
605
    /**
606
     * Deprecated methods.
607
     */
608
    /**
609
     * @remark          This was not functional since 3.1.3
610
     * @deprecated      3.5.5
611
     */
612
    public function setFooterInfoRight() {}
613
    /**
614
     * @remark          This was not functional since 3.1.3
615
     * @deprecated      3.5.5
616
     */    
617
    public function setFooterInfoLeft() {}
618
 
619
}