AdminPageFramework_Model_Form   A
last analyzed

Complexity

Total Complexity 39

Size/Duplication

Total Lines 422
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 39
eloc 156
dl 0
loc 422
rs 9.28
c 0
b 0
f 0

15 Methods

Rating   Name   Duplication   Size   Complexity  
A _replyToDetermineFieldsetVisibility() 0 9 2
A _replyToFieldsetResourceRegistration() 0 34 3
A _replyToDetermineWhetherToProcessFormRegistration() 0 6 2
A __construct() 0 18 4
A _replyToDetermineSectionsetVisibility() 0 12 4
A _registerHelpPaneItemsOfFormSections() 0 25 3
A _replyToGetCapabilityForForm() 0 12 1
A _replyToFormatFieldsetDefinition() 0 40 3
A _getSectionCapability() 0 23 4
A _replyToHandleSubmittedFormData() 0 7 1
A _replyToFormatSectionsetDefinition() 0 19 2
A _replyToModifySectionsets() 0 6 1
A _isSectionOfCurrentPage() 0 17 3
A _getSectionTabSlug() 0 6 2
A _getSectionPageSlug() 0 18 4
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
 * Interacts with the database for the forms.
12
 *
13
 * @abstract
14
 * @since           3.3.1
15
 * @since           3.6.3       Changed the name from `AdminPageFramework_Form_Model`.
16
 * @extends         AdminPageFramework_Router
17
 * @package         AdminPageFramework/Factory/AdminPage/Model
18
 * @internal
19
 */
20
abstract class AdminPageFramework_Model_Form extends AdminPageFramework_Router {
21
22
    /**
23
     * Stores the settings field errors.
24
     *
25
     * @remark      Do not set a default value here since it is checked whether it is null or not later.
26
     * @since       2.0.0
27
     * @since       3.6.3       Changed the visibility scope to public as a delegation class needs to access this property.
28
     * @var         array       Stores field errors.
29
     * @internal
30
     */
31
    public $aFieldErrors;
32
33
    /**
34
     * Stores the target page slug which will be applied when no page slug is specified for the `addSettingSection()` method.
35
     *
36
     * @since       3.0.0
37
     */
38
    protected $_sTargetPageSlug = null;
39
40
    /**
41
     * Stores the target tab slug which will be applied when no tab slug is specified for the `addSettingSection()` method.
42
     *
43
     * @since       3.0.0
44
     */
45
    protected $_sTargetTabSlug = null;
46
47
    /**
48
     * Stores the target section tab slug which will be applied when no section tab slug is specified for the `addSettingSection()` method.
49
     *
50
     * @since 3.0.0
51
     */
52
    protected $_sTargetSectionTabSlug = null;
53
54
    /**
55
     * Registers necessary hooks and sets up properties.
56
     *
57
     * @internal
58
     * @since       3.3.0
59
     * @since       3.3.1       Moved from `AdminPageFramework_Setting_Base`.
60
     */
61
    public function __construct( $sOptionKey=null, $sCallerPath=null, $sCapability='manage_options', $sTextDomain='admin-page-framework' ) {
62
63
        parent::__construct( $sOptionKey, $sCallerPath, $sCapability, $sTextDomain );
64
65
        // @deprecated  3.8.14
66
//        if ( $this->oProp->bIsAdminAjax ) {
67
//            return;
68
//        }
69
        if ( ! $this->oProp->bIsAdmin ) {
70
            return;
71
        }
72
73
        // @deprecated 3.8.32
74
        // new AdminPageFramework_Model__FormEmailHandler( $this );
75
76
        // Checking the GET and POST methods.
77
        if ( isset( $_REQUEST[ 'apf_remote_request_test' ] ) && '_testing' === $_REQUEST[ 'apf_remote_request_test' ] ) {   // sanitization unnecessary
78
            exit( 'OK' );
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
79
        }
80
81
    }
82
83
    /**
84
     * Validates submitted form data and saves them.
85
     *
86
     * @since       3.7.0
87
     * @callback    form        handle_form_data
88
     * @return      void
89
     */
90
    public function _replyToHandleSubmittedFormData( $aSavedData, $aArguments, $aSectionsets, $aFieldsets ) {
91
        new AdminPageFramework_Model__FormSubmission(
92
            $this,
93
            $aSavedData,
94
            $aArguments,
95
            $aSectionsets,
96
            $aFieldsets
97
        );
98
    }
99
100
    /**
101
     * Called upon fieldset resource registration.
102
     *
103
     * A contextual help pane item associated with this fieldset will be added.
104
     *
105
     * @remark      Overrides the method of the factory class.
106
     * @since       3.7.0
107
     * @return      void
108
     */
109
    public function _replyToFieldsetResourceRegistration( $aFieldset ) {
110
111
        $aFieldset = $aFieldset + array(
112
            'help'          => null,
113
            'title'         => null,
114
            'help_aside'    => null,
115
            'page_slug'     => null,
116
            'tab_slug'      => null,
117
            'section_title' => null,
118
            'section_id'    => null,
119
        );
120
        if ( ! $aFieldset[ 'help' ] ) {
121
            return;
122
        }
123
124
        // Get the first item of the section path.
125
        $_sRootSectionID = $this->oUtil->getElement(
126
            $this->oUtil->getAsArray( $aFieldset[ 'section_id' ] ),
127
            0
128
        );
129
130
        $this->addHelpTab(
0 ignored issues
show
Bug introduced by
The method addHelpTab() does not exist on AdminPageFramework_Model_Form. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

130
        $this->/** @scrutinizer ignore-call */ 
131
               addHelpTab(
Loading history...
131
            array(
132
                'page_slug'                 => $aFieldset[ 'page_slug' ],
133
                'page_tab_slug'             => $aFieldset[ 'tab_slug' ],
134
                'help_tab_title'            => $aFieldset[ 'section_title' ],
135
                'help_tab_id'               => $_sRootSectionID,
136
                'help_tab_content'          => "<span class='contextual-help-tab-title'>"
137
                        . $aFieldset[ 'title' ]
138
                    . "</span> - " . PHP_EOL
139
                    . $aFieldset[ 'help' ],
140
                'help_tab_sidebar_content'  => $aFieldset[ 'help_aside' ]
141
                    ? $aFieldset[ 'help_aside' ]
142
                    : "",
143
            )
144
        );
145
146
    }
147
148
    /**
149
     * Modifies registered sectionsets definition array.
150
     * @since       3.7.0
151
     * @remark      Overrides the method of the factory class.
152
     * @return      array       The modified sectionsets definition array.
153
     */
154
    public function _replyToModifySectionsets( $aSectionsets ) {
155
156
        // Help pane elements must be added before the head tag gets rendered.
157
        $this->_registerHelpPaneItemsOfFormSections( $aSectionsets );
158
159
        return parent::_replyToModifySectionsets( $aSectionsets );
160
161
    }
162
        /**
163
         * Parse the definition array and add help pane items.
164
         *
165
         * Help pane elements must be added before the head tag gets rendered.
166
         * @return      void
167
         * @since       3.7.0
168
         */
169
        public function _registerHelpPaneItemsOfFormSections( $aSectionsets ) {
170
// @todo Test if help pane item gets displayed
171
172
            foreach( $aSectionsets as $_aSectionset ) {
173
// @todo check capability and conditions
174
                $_aSectionset = $_aSectionset + array(
175
                    'help'          => null,
176
                    'page_slug'     => null,
177
                    'tab_slug'      => null,
178
                    'title'         => null,
179
                    'section_id'    => null,
180
                    'help'          => null,
181
                    'help_aside'    => null,
182
                );
183
                if ( empty( $_aSectionset[ 'help' ] ) ) {
184
                    continue;
185
                }
186
                $this->addHelpTab(
187
                    array(
188
                        'page_slug'                 => $_aSectionset[ 'page_slug' ],
189
                        'page_tab_slug'             => $_aSectionset[ 'tab_slug' ],
190
                        'help_tab_title'            => $_aSectionset[ 'title' ],
191
                        'help_tab_id'               => $_aSectionset[ 'section_id' ],
192
                        'help_tab_content'          => $_aSectionset[ 'help' ],
193
                        'help_tab_sidebar_content'  => $this->oUtil->getElement( $_aSectionset, 'help_aside', '' ),
194
                    )
195
                );
196
            }
197
        }
198
199
    /**
200
     * Determines whether the passed field should be visible or not.
201
     * @since       3.7.0
202
     * @return      boolean
203
     */
204
    public function _replyToDetermineSectionsetVisibility( $bVisible, $aSectionset ) {
205
206
        if ( ! current_user_can( $aSectionset[ 'capability' ] ) ) {
207
            return false;
208
        }
209
        if ( ! $aSectionset[ 'if' ] ) {
210
            return false;
211
        }
212
        if ( ! $this->_isSectionOfCurrentPage( $aSectionset ) ) {
213
            return false;
214
        }
215
        return $bVisible;
216
217
    }
218
        /**
219
         * Checks if the given section belongs to the currently loading tab.
220
         *
221
         * @since       2.0.0
222
         * @since       3.0.0       Moved from the setting class.
223
         * @since       3.7.0      Moved from `AdminPageFramework_FormDefinition_Page`.
224
         * @remark      Assumes the given section definition array is already formatted.
225
         * @return      boolean     Returns true if the section belongs to the current tab page. Otherwise, false.
226
         */
227
        private function _isSectionOfCurrentPage( array $aSectionset ) {
228
229
            // Make sure the value type is string so that when the page_slug is not set, it won't match.
230
            $_sCurrentPageSlug  = ( string ) $this->oProp->getCurrentPageSlug();
231
232
            // Make sure if it's in the loading page.
233
            if ( $aSectionset[ 'page_slug' ] !== $_sCurrentPageSlug  ) {
234
                return false;
235
            }
236
237
            // If no tag is specified, the user wants to display the section regardless of the tab.
238
            if ( ! $aSectionset[ 'tab_slug' ] ) {
239
                return true;
240
            }
241
242
            // If the checking tab slug and the current loading tab slug is the same, it should be registered.
243
            return  ( $aSectionset[ 'tab_slug' ] === $this->oProp->getCurrentTabSlug( $_sCurrentPageSlug ) );
244
245
        }
246
247
    /**
248
     * Determines whether the passed field should be visible or not.
249
     * @since       3.7.0
250
     * @return      boolean
251
     */
252
    public function _replyToDetermineFieldsetVisibility( $bVisible, $aFieldset ) {
253
254
        $_sCurrentPageSlug  = $this->oProp->getCurrentPageSlug();
255
256
        // If the specified field does not exist, do nothing.
257
        if ( $aFieldset[ 'page_slug' ] !== $_sCurrentPageSlug ) {
258
            return false;
259
        }
260
        return parent::_replyToDetermineFieldsetVisibility( $bVisible, $aFieldset );
261
262
    }
263
264
    /**
265
     * @since       3.7.0
266
     * @param       array   $aFieldset
267
     * @param       array   $aSectionsets
268
     * @return      array
269
     */
270
    public function _replyToFormatFieldsetDefinition( $aFieldset, $aSectionsets ) {
271
272
        if ( empty( $aFieldset ) ) {
273
            return $aFieldset;
274
        }
275
276
        $_aSectionPath = $this->oUtil->getAsArray( $aFieldset[ 'section_id' ] );
277
        $_sSectionPath = implode( '|', $_aSectionPath );
278
279
        $aFieldset[ 'option_key' ]      = $this->oProp->sOptionKey;
280
        $aFieldset[ 'class_name' ]      = $this->oProp->sClassName;
281
        $aFieldset[ 'page_slug' ]       = $this->oUtil->getElement(
282
            $aSectionsets,
283
            array( $_sSectionPath, 'page_slug' ),
284
            $this->oProp->getCurrentPageSlugIfAdded()
285
        );
286
        $aFieldset[ 'tab_slug' ]        = $this->oUtil->getElement(
287
            $aSectionsets,
288
            array( $_sSectionPath, 'tab_slug' ),
289
            $this->oProp->getCurrentInPageTabSlugIfAdded()
290
        );
291
292
        // used for the contextual help pane.
293
        $_aSectionset = $this->oUtil->getElementAsArray(
294
            $aSectionsets,
295
            $_sSectionPath
296
        );
297
        $aFieldset[ 'section_title' ]   = $this->oUtil->getElement(
298
            $_aSectionset,
299
            'title'
300
        );
301
        $aFieldset[ 'capability' ]   = $aFieldset[ 'capability' ]
302
            ? $aFieldset[ 'capability' ]
303
            : $this->_replyToGetCapabilityForForm(
304
                $this->oUtil->getElement( $_aSectionset, 'capability' ),
305
                $_aSectionset[ 'page_slug' ],
306
                $_aSectionset[ 'tab_slug' ]
307
            );
308
309
        return parent::_replyToFormatFieldsetDefinition( $aFieldset, $aSectionsets );
310
311
    }
312
313
    /**
314
     * @since       3.7.0
315
     * @return      array
316
     */
317
    public function _replyToFormatSectionsetDefinition( $aSectionset ) {
318
319
        if ( empty( $aSectionset ) ) {
320
            return $aSectionset;
321
        }
322
323
        $aSectionset = $aSectionset + array(
324
            'page_slug'     => null,
325
            'tab_slug'      => null,
326
            'capability'    => null,
327
        );
328
329
        $aSectionset[ 'page_slug' ]  = $this->_getSectionPageSlug( $aSectionset );
330
        $aSectionset[ 'tab_slug' ]   = $this->_getSectionTabSlug( $aSectionset );
331
332
        // 3.6.0+ Inherit the capability value from the page.
333
        $aSectionset[ 'capability' ] = $this->_getSectionCapability( $aSectionset );
334
335
        return parent::_replyToFormatSectionsetDefinition( $aSectionset );
336
337
    }
338
        /**
339
         * Attempts to find the capability of a given section.
340
         * @since       3.7.0
341
         * @return      string
342
         */
343
        private function _getSectionCapability( $aSectionset ) {
344
345
            if ( $aSectionset[ 'capability' ] ) {
346
                return $aSectionset[ 'capability' ];
347
            }
348
349
            // Find the capability of the parent section if nested.
350
            if ( 0 < $aSectionset[ '_nested_depth' ] ) {
351
                $_aSectionPath         = $aSectionset[ '_section_path_array' ];
352
                array_pop( $_aSectionPath ); // remove the last element
353
                $_sParentCapability = $this->oUtil->getElement(
354
                    $this->oForm->aSectionsets,
355
                    array_merge( $_aSectionPath, array( 'capability' ) )
356
                );
357
                if( $_sParentCapability ) {
358
                    return $_sParentCapability;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $_sParentCapability also could return the type string[] which is incompatible with the documented return type string.
Loading history...
359
                }
360
            }
361
362
            return $this->_replyToGetCapabilityForForm(
363
                $aSectionset[ 'capability' ],
364
                $aSectionset[ 'page_slug' ],
365
                $aSectionset[ 'tab_slug' ]
366
            );
367
368
        }
369
        /**
370
         * Attempts to find the page slug of a given section set definition.
371
         *
372
         * Nested sections may not have the page slug assigned.
373
         * In that case, it tries to set the value of the ancestor.
374
         *
375
         * @since       3.7.0
376
         * @return      string
377
         */
378
        private function _getSectionPageSlug( $aSectionset ) {
379
380
            if ( $aSectionset[ 'page_slug' ] ) {
381
                return $aSectionset[ 'page_slug' ];
382
            }
383
            if ( 0 < $aSectionset[ '_nested_depth' ] ) {
384
385
                $_aSectionPath         = $aSectionset[ '_section_path_array' ];
386
                $_sRootSectionID       = $this->oUtil->getFirstElement( $_aSectionPath );
387
                $_sRootSectionPageSlug = $this->oUtil->getElement(
388
                    $this->oForm->aSectionsets,
389
                    array( $_sRootSectionID, 'page_slug' )
390
                );
391
                if ( $_sRootSectionPageSlug ) {
392
                    return $_sRootSectionPageSlug;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $_sRootSectionPageSlug also could return the type string[] which is incompatible with the documented return type string.
Loading history...
393
                }
394
            }
395
            return $this->oProp->getCurrentPageSlugIfAdded();
396
            // @deprecated 3.7.2
397
            // return $this->oProp->sDefaultPageSlug;
398
399
        }
400
        /**
401
         * @since       3.7.2
402
         * @return      string|null
403
         */
404
        private function _getSectionTabSlug( $aSectionset ) {
405
406
            if ( $aSectionset[ 'tab_slug' ] ) {
407
                return $aSectionset[ 'tab_slug' ];
408
            }
409
            return $this->oProp->getCurrentInPageTabSlugIfAdded();
410
411
        }
412
    /**
413
     * @since       3.7.0
414
     * @return      boolean     Whether or not the form registration should be allowed in the current screen.
415
     */
416
    public function _replyToDetermineWhetherToProcessFormRegistration( $bAllowed ) {
417
        if ( $this->oProp->bIsAdminAjax ) {
418
            return true;
419
        }
420
        $_sPageSlug = $this->oProp->getCurrentPageSlug();
421
        return $this->oProp->isPageAdded( $_sPageSlug );
422
    }
423
    /**
424
     * Returns the inherited capability value from the page and in-page tab for form elements.
425
     *
426
     * @since       3.6.0
427
     * @since       3.7.0      Moved from `AdminPageFramework_FormDefinition_Page`.
428
     * @return      string
429
     */
430
    public function _replyToGetCapabilityForForm( $sCapability /*, $sPageSlug, $sTabSlug */ ) {
431
432
        $_aParameters     = func_get_args() + array( '', '', '' );
433
        $_sPageSlug       = $this->oUtil->getAOrB( $_aParameters[ 1 ], $_aParameters[ 1 ], $this->oProp->getCurrentPageSlug() );
434
        $_sTabSlug        = $this->oUtil->getAOrB( $_aParameters[ 2 ], $_aParameters[ 2 ], $this->oProp->getCurrentTabSlug( $_sPageSlug ) );
435
436
        // Note that the passed capability value to the method is same as the one set to the factory class constructor.
437
        $_sTabCapability  = $this->_getInPageTabCapability( $_sTabSlug, $_sPageSlug );
0 ignored issues
show
Bug introduced by
The method _getInPageTabCapability() does not exist on AdminPageFramework_Model_Form. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

437
        /** @scrutinizer ignore-call */ 
438
        $_sTabCapability  = $this->_getInPageTabCapability( $_sTabSlug, $_sPageSlug );
Loading history...
438
        $_sPageCapability = $this->_getPageCapability( $_sPageSlug );
0 ignored issues
show
Bug introduced by
The method _getPageCapability() does not exist on AdminPageFramework_Model_Form. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

438
        /** @scrutinizer ignore-call */ 
439
        $_sPageCapability = $this->_getPageCapability( $_sPageSlug );
Loading history...
439
        $_aCapabilities   = array_values( array_filter( array( $_sTabCapability, $_sPageCapability ) ) )
440
            + array( $this->oProp->sCapability );
441
        return $_aCapabilities[ 0 ];
442
443
    }
444
445
}
446