Completed
Branch dev (410a92)
by
unknown
134:40 queued 124:59
created

_replyToDetermineToLoad()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 17
rs 9.4285
cc 2
eloc 5
nc 2
nop 0
1
<?php
2
/**
3
 * Admin Page Framework
4
 * 
5
 * http://en.michaeluno.jp/admin-page-framework/
6
 * Copyright (c) 2013-2016 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
 */
21
abstract class AdminPageFramework_Factory_Router {
22
    
23
    /**
24
     * Stores the property object.
25
     * 
26
     * @since       2.0.0
27
     * @access      public      The AdminPageFramework_Page_MetaBox class accesses it.
28
     */     
29
    public $oProp;    
30
    
31
    /**
32
     * The object that provides the debug methods. 
33
     * 
34
     * @internal
35
     * @access      public
36
     * @since       2.0.0
37
     * @since       3.1.0   Changed the scope to public from protected.
38
     */     
39
    public $oDebug;
40
    /**
41
     * Provides the utility methods. 
42
     * 
43
     * @internal
44
     * @since       2.0.0
45
     * @since       3.1.0     Changed the scope to public from protected.
46
     */         
47
    public $oUtil;
48
    /**
49
     * Provides the methods for text messages of the framework. 
50
     * 
51
     * @since       2.0.0
52
     * @since       3.1.0     Changed the scope to public from protected.
53
     * @access      public
54
     * @internal
55
     */         
56
    public $oMsg;
57
    
58
    /**
59
     * The form object that provides methods to handle form sections and fields.
60
     * @internal
61
     * @since       3.0.0
62
     * @since       3.5.2       Changed the scope to public from protected as the widget class needs to initialize this object.
63
     */     
64
    public $oForm;
65
    
66
    /**
67
     * Inserts page load information into the footer area of the page. 
68
     * 
69
     */
70
    protected $oPageLoadInfo;
71
    
72
    /**
73
     * Provides the methods to insert head tag elements.
74
     * 
75
     * @since   3.3.0   Changed the name from $oHeadTag as it has become to deal with footer elements.
76
     */
77
    protected $oResource;
78
    
79
    /**
80
     * Provides the methods to insert head tag elements.
81
     * @deprecated
82
     */
83
    protected $oHeadTag;
84
    
85
    /**
86
     * Provides methods to manipulate contextual help pane.
87
     */
88
    protected $oHelpPane;
89
    
90
    /**
91
     * Provides the methods for creating HTML link elements. 
92
     * 
93
     */    
94
    protected $oLink;
95
    
96
    /**
97
     * Stores sub-class names.
98
     * 
99
     * Used in the __get() method to check whether a method with the name of the property should be called or not.
100
     * 
101
     * @since       3.5.3
102
     */
103
    protected $_aSubClassNames = array(
104
        'oDebug', 
105
        'oUtil',
106
        'oMsg',
107
        'oForm',
108
        'oPageLoadInfo',
109
        'oResource',
110
        'oHelpPane',
111
        'oLink',
112
    );
113
    
114
    /**
115
     * Sets up built-in objects.
116
     */
117
    public function __construct( $oProp ) {
118
119
        // Let them overload so that these sub-class objects will not be instantiated until they are required.
120
        unset( 
121
            $this->oDebug, 
122
            $this->oUtil, 
123
            $this->oMsg, 
124
            $this->oForm, 
125
            $this->oPageLoadInfo,
126
            $this->oResource,
127
            $this->oHelpPane,
128
            $this->oLink
129
        );
130
        
131
        // Required sub-class objects
132
        $this->oProp = $oProp;
133
            
134
        if ( $this->oProp->bIsAdmin && ! $this->oProp->bIsAdminAjax ) {
135
            if ( did_action( 'current_screen' ) ) {
136
                $this->_replyToLoadComponents();
137
            } else {                
138
                add_action( 'current_screen', array( $this, '_replyToLoadComponents' ) );
139
            }
140
        }
141
        
142
        // Call the user constructor.
143
        $this->start();     // defined in the controller class.
0 ignored issues
show
Documentation Bug introduced by
The method start does not exist on object<AdminPageFramework_Factory_Router>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
144
        $this->oUtil->addAndDoAction( $this, 'start_' . $this->oProp->sClassName, $this );
145
        
146
    }    
147
        
148
    /**
149
     * Determines whether the class component classes should be instantiated or not.
150
     * 
151
     * @internal
152
     * @callback    action      current_screen
153
     * @return      void
154
     */
155
    public function _replyToLoadComponents( /* $oScreen */ ) {
156
157
        if ( ! $this->_isInThePage() ) { 
158
            return; 
159
        }
160
                    
161
        if ( ! isset( $this->oResource ) ) {
162
            $this->oResource = $this->_replyTpSetAndGetInstance_oResource();
163
        }
164
        
165
        if ( ! isset(  $this->oLink ) ) {
166
            $this->oLink = $this->_replyTpSetAndGetInstance_oLink();         
167
        }
168
        
169
        if ( $this->oUtil->isDebugMode() ) {
170
            $this->oPageLoadInfo = $this->oPageLoadInfo;
171
        }
172
        
173
    }
174
175
176
    /**
177
     * Determines whether the class object is instantiatable in the current page.
178
     * 
179
     * This method should be redefined in the extended class.
180
     * 
181
     * @since       3.1.0
182
     * @internal
183
     */ 
184
    protected function _isInstantiatable() { 
185
        return true; 
186
    }
187
    
188
    /**
189
     * Determines whether the instantiated object and its producing elements belong to the loading page.
190
     * 
191
     * This method should be redefined in the extended class.
192
     * 
193
     * @remark      This method should be called AFTER current screen is determined such as after the `current_screen` action hook.
194
     * @since       3.0.3
195
     * @since       3.2.0   Changed the visibility scope to `public` from `protected` as the head tag object will access it.
196
     * @todo        Change the visibility scope to `protected` as the public version of the method `isInThePage()` has been introduced to make the design consitent.
197
     * @internal
198
     */
199
    public function _isInThePage() { 
200
        return true; 
201
    }
202
         
203
    /**
204
     * Determines whether the `setUp()` method should be called.
205
     * 
206
     * @since       3.7.10
207
     * @callback    
208
     * @internal    
209
     * @return      void
210
     */
211
    public function _replyToDetermineToLoad() {
212
213
        if ( ! $this->_isInThePage() ) { 
214
            return; 
215
        }
216
217
        // Calls `setUp()` and the user will set up the meta box.
218
        $this->_setUp();
0 ignored issues
show
Documentation Bug introduced by
The method _setUp does not exist on object<AdminPageFramework_Factory_Router>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
219
        
220
        /**
221
         * This action hook must be called AFTER the _setUp() method 
222
         * as there are callback methods that hook into this hook 
223
         * and assumes required configurations have been made.
224
         */
225
        $this->oUtil->addAndDoAction( $this, "set_up_{$this->oProp->sClassName}", $this );
226
                          
227
    }          
228
         
229
         
230
    /**
231
     * Instantiate a form object based on the type.
232
     * 
233
     * @since       3.1.0
234
     * @internal
235
     * @return      object|null
236
     */
237
    protected function _getFormObject() {
238
    
239
        $this->oProp->setFormProperties();
240
        $_sFormClass = "AdminPageFramework_Form_{$this->oProp->_sPropertyType}";
241
        return new $_sFormClass(
242
            $this->oProp->aFormArguments, // Options - for the values that do not need to change through out the script execution. 
243
            $this->oProp->aFormCallbacks, // Callbacks - for the values which change dynamically depending on conditions such as the loaded page url.
244
            $this->oMsg
245
        );    
246
        
247
    }
248
     
249
    /**
250
     * Instantiates a link object based on the type.
251
     * 
252
     * @since       3.0.4
253
     * @since       3.7.10      Removed the parameters as those values will be set in the extended class.
254
     * @remark      Override this method in an extended class.
255
     * @internal
256
     * @return      null|object
257
     */
258
    protected function _getLinkObject() {
259
        return null;
260
    }
261
    
262
    /**
263
     * Instantiates a page load object based on the type.
264
     * 
265
     * @since       3.0.4
266
     * @since       3.7.10      Removed the parameters as those values will be set in the extended class.
267
     * @internal
268
     */
269
    protected function _getPageLoadObject() {
270
        return null;
271
    }
272
      
273
    /**
274
     * Responds to a request of an undefined property.
275
     * 
276
     * This is used to instantiate classes only when necessary, rather than instantiating them all at once.
277
     * 
278
     * @internal
279
     */
280
    public function __get( $sPropertyName ) {
281
            
282
        // Set and return the sub class object instance.
283
        if ( in_array( $sPropertyName, $this->_aSubClassNames ) ) {                        
284
            return call_user_func( 
285
                array( $this, "_replyTpSetAndGetInstance_{$sPropertyName}"  )
286
            );
287
        }
288
        
289
    }
290
        /**#@+
291
         * @internal
292
         * @return      object
293
         * @callback    function    call_user_func
294
         */          
295
        /**
296
         * Sets and returns the `oUtil` property.
297
         * @since       3.5.3
298
         */
299
        public function _replyTpSetAndGetInstance_oUtil() {
300
            $this->oUtil = new AdminPageFramework_FrameworkUtility;
301
            return $this->oUtil;
302
        }
303
        /**
304
         * Sets and returns the `oDebug` property.
305
         * @since       3.5.3
306
         */        
307
        public function _replyTpSetAndGetInstance_oDebug() {
308
            $this->oDebug = new AdminPageFramework_Debug;
309
            return $this->oDebug;
310
        }
311
        /**
312
         * Sets and returns the `oMsg` property.
313
         * @since       3.5.3
314
         */              
315
        public function _replyTpSetAndGetInstance_oMsg() {
316
            $this->oMsg = AdminPageFramework_Message::getInstance( $this->oProp->sTextDomain );
317
            return $this->oMsg;
318
        }
319
        /**
320
         * Sets and returns the `oForm` property.
321
         * @since       3.5.3
322
         */              
323
        public function _replyTpSetAndGetInstance_oForm() {
324
            $this->oForm = $this->_getFormObject();           
325
            return $this->oForm;
326
        }
327
        /**
328
         * Sets and returns the `oResouce` property.
329
         * @since       3.5.3
330
         */            
331
        public function _replyTpSetAndGetInstance_oResource() {
332
            if ( isset( $this->oResource ) ) {
333
                return $this->oResource;
334
            }
335
            $_sClassName     = "AdminPageFramework_Resource_{$this->oProp->_sPropertyType}";
336
            $this->oResource = new $_sClassName( $this->oProp );
337
            return $this->oResource;
338
        }
339
            /**
340
             * Kept for backward compatibility.
341
             * @since       3.7.10
342
             */
343
            public function _replyTpSetAndGetInstance_oHeadTag() {
344
                $this->oHead = $this->_replyTpSetAndGetInstance_oResource();
0 ignored issues
show
Bug introduced by
The property oHead 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...
345
                return $this->oHead;
346
            }        
347
        /**
348
         * Sets and returns the `oHelpPane` property.
349
         * @since       3.5.3
350
         */
351
        public function _replyTpSetAndGetInstance_oHelpPane() {
352
            $_sClassName     = "AdminPageFramework_HelpPane_{$this->oProp->_sPropertyType}";
353
            $this->oHelpPane = new $_sClassName( $this->oProp );            
354
            return $this->oHelpPane;
355
        }
356
        /**
357
         * Sets and returns the `oLink` property.
358
         * @since       3.5.3
359
         */
360
        public function _replyTpSetAndGetInstance_oLink() {
361
            $this->oLink = $this->_getLinkObject();
362
            return $this->oLink;
363
        }
364
        /**
365
         * Sets and returns the `oPageLoadInfo` property.
366
         * @since       3.5.3
367
         */        
368
        public function _replyTpSetAndGetInstance_oPageLoadInfo() {
369
            $this->oPageLoadInfo = $this->_getPageLoadObject();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $this->oPageLoadInfo is correct as $this->_getPageLoadObject() (which targets AdminPageFramework_Facto...r::_getPageLoadObject()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
370
            return $this->oPageLoadInfo;
371
        }
372
        /**#@-*/
373
        
374
    /**
375
     * Redirects dynamic function calls to the pre-defined internal method.
376
     * 
377
     * @internal
378
     */
379
    public function __call( $sMethodName, $aArguments=null ) {    
380
         
381
        $_mFirstArg = $this->oUtil->getElement( $aArguments, 0 );
382
        
383
        switch ( $sMethodName ) {
384
            case 'validate':
385
            case 'content':
386
                return $_mFirstArg;
387
                
388
        }
389
        
390
        // If it is called with the framework auto-callback,
391
        if ( has_filter( $sMethodName ) ) {
392
            return $this->_getAutoCallback( $sMethodName, $aArguments );
393
        }
394
                
395
        $this->_triggerUndefinedMethodWarning( $sMethodName );
396
        
397
    }     
398
        /**
399
         * Returns the first parameter value if the method name does not contain a backslash.
400
         * If it contains a backslash, the user uses a name-spaced class name. In that case,
401
         * the backslashes need to be converted to underscores to support valid PHP method names.
402
         * 
403
         * @since       3.7.0
404
         */
405
        private function _getAutoCallback( $sMethodName, $aArguments ) {
406
            
407
            // Check if the method name does not contain a backslash.
408
            if ( false === strpos( $sMethodName, "\\" ) ) {
409
                return $this->oUtil->getElement( $aArguments, 0 );  // the first element - the filter value
410
            }
411
                
412
            // If the method name contains a backslash, the user may be using a name space. 
413
            // In that case, convert the backslash to underscore and call the method.
414
            $_sAutoCallbackMethodName = str_replace( '\\', '_', $sMethodName );
415
            return method_exists( $this, $_sAutoCallbackMethodName )
416
                ? call_user_func_array(
417
                    array( $this, $_sAutoCallbackMethodName ),
418
                    $aArguments
419
                )
420
                : $this->oUtil->getElement( $aArguments, 0 );   // the first argument
421
            
422
        }
423
        
424
        /**
425
         * @since   3.7.0
426
         * @return  void
427
         */
428
        private function _triggerUndefinedMethodWarning( $sMethodName ) {
429
            trigger_error(
430
                AdminPageFramework_Registry::NAME . ': ' 
431
                    . sprintf( 
432
                        __( 'The method is not defined: %1$s', $this->oProp->sTextDomain ),
433
                        $sMethodName 
434
                    ), 
435
                E_USER_WARNING 
436
            );            
437
        }
438
            
439
        
440
    
441
    /**
442
     * Prevents the output from getting too long when the object is dumped.
443
     *
444
     * Field definition arrays contain the factory object reference and when the debug log method tries to dump it, the output gets too long.
445
     * So shorten it here.
446
     * 
447
     * @remark      Called when the object is called as a string.
448
     * @since       3.4.4
449
     */   
450
    public function __toString() {
451
        return $this->oUtil->getObjectInfo( $this );        
452
    }
453
 
454
    /**
455
     * Deprecated methods.
456
     */
457
    /**
458
     * @remark          This was not functional since 3.1.3
459
     * @deprecated      3.5.5
460
     */
461
    public function setFooterInfoRight() {}
462
    /**
463
     * @remark          This was not functional since 3.1.3
464
     * @deprecated      3.5.5
465
     */    
466
    public function setFooterInfoLeft() {}
467
 
468
}
469