1 <?php
2 /**
3 * Admin Page Framework
4 *
5 * http://en.michaeluno.jp/admin-page-framework/
6 * Copyright (c) 2013-2014 Michael Uno; Licensed MIT
7 *
8 */
9 if ( ! class_exists( 'AdminPageFramework_MetaBox_Page_Model' ) ) :
10 /**
11 * Provides model methods for creating meta boxes in pages added by the framework.
12 *
13 * @abstract
14 * @since 3.0.4
15 * @package AdminPageFramework
16 * @subpackage PageMetaBox
17 */
18 abstract class AdminPageFramework_MetaBox_Page_Model extends AdminPageFramework_MetaBox_Page_Router {
19
20 /**
21 * Defines the fields type.
22 * @since 3.0.0
23 * @internal
24 */
25 static protected $_sFieldsType = 'page_meta_box';
26
27 /**
28 * Sets up properties and hooks.
29 *
30 * @since 3.0.4
31 */
32 function __construct( $sMetaBoxID, $sTitle, $asPageSlugs=array(), $sContext='normal', $sPriority='default', $sCapability='manage_options', $sTextDomain='admin-page-framework' ) {
33
34 /* The property object needs to be done first */
35 $this->oProp = new AdminPageFramework_Property_MetaBox_Page( $this, get_class( $this ), $sCapability, $sTextDomain, self::$_sFieldsType );
36 $this->oProp->aPageSlugs = is_string( $asPageSlugs ) ? array( $asPageSlugs ) : $asPageSlugs; // must be set before the isInThePage() method is used.
37
38 parent::__construct( $sMetaBoxID, $sTitle, $asPageSlugs, $sContext, $sPriority, $sCapability, $sTextDomain );
39
40 if ( $this->_isInThePage() ) :
41
42 /* Validation hooks */
43 foreach( $this->oProp->aPageSlugs as $_sIndexOrPageSlug => $_asTabArrayOrPageSlug ) {
44
45 if ( is_string( $_asTabArrayOrPageSlug ) ) {
46 $_sPageSlug = $_asTabArrayOrPageSlug;
47 add_filter( "validation_saved_options_{$_sPageSlug}", array( $this, '_replyToFilterPageOptions' ) );
48 add_filter( "validation_{$_sPageSlug}", array( $this, '_replyToValidateOptions' ), 10, 3 );
49 continue;
50 }
51
52 // At this point, the array key is the page slug.
53 $_sPageSlug = $_sIndexOrPageSlug;
54 $_aTabs = $_asTabArrayOrPageSlug;
55 add_filter( "validation_{$_sPageSlug}", array( $this, '_replyToValidateOptions' ), 10, 3 );
56 foreach( $_aTabs as $_sTabSlug ) {
57 add_filter( "validation_saved_options_{$_sPageSlug}_{$_sTabSlug}", array( $this, '_replyToFilterPageOptions' ) );
58 }
59
60 }
61
62 endif;
63
64 }
65
66
67 /**
68 * Returns the field output.
69 *
70 * @since 3.0.0
71 * @internal
72 */
73 protected function getFieldOutput( $aField ) {
74
75 /* Since meta box fields don't have the option_key key which is required to compose the name attribute in the regular pages. */
76 $sOptionKey = $this->_getOptionKey();
77 $aField['option_key'] = $sOptionKey ? $sOptionKey : null;
78 $aField['page_slug'] = isset( $_GET['page'] ) ? $_GET['page'] : ''; // set an empty string to make it yield true for isset() so that saved options will be checked.
79
80 return parent::getFieldOutput( $aField );
81
82 }
83
84 /**
85 * Returns the currently loading page's option key if the page has the admin page object.
86 * @since 3.0.0
87 * @internal
88 */
89 private function _getOptionkey() {
90 return isset( $_GET['page'] )
91 ? $this->oProp->getOptionKey( $_GET['page'] )
92 : null;
93 }
94
95 /**
96 * Adds the defined meta box.
97 *
98 * @internal
99 * @since 3.0.0
100 * @remark uses <em>add_meta_box()</em>.
101 * @remark Before this method is called, the pages and in-page tabs need to be registered already.
102 * @remark A callback for the <em>add_meta_boxes</em> hook.
103 * @return void
104 */
105 public function _replyToAddMetaBox( $sPageHook='' ) {
106
107 foreach( $this->oProp->aPageSlugs as $sKey => $asPage ) {
108
109 if ( is_string( $asPage ) ) {
110 $this->_addMetaBox( $asPage );
111 continue;
112 }
113 if ( ! is_array( $asPage ) ) continue;
114
115 $sPageSlug = $sKey;
116 foreach( $asPage as $sTabSlug ) {
117
118 if ( ! $this->oProp->isCurrentTab( $sTabSlug ) ) continue;
119
120 $this->_addMetaBox( $sPageSlug );
121
122 }
123
124 }
125
126 }
127 /**
128 * Adds meta box with the given page slug.
129 * @since 3.0.0
130 * @internal
131 */
132 private function _addMetaBox( $sPageSlug ) {
133
134 add_meta_box(
135 $this->oProp->sMetaBoxID, // id
136 $this->oProp->sTitle, // title
137 array( $this, '_replyToPrintMetaBoxContents' ), // callback
138 $this->oProp->_getScreenIDOfPage( $sPageSlug ), // screen ID
139 $this->oProp->sContext, // context
140 $this->oProp->sPriority, // priority
141 null // argument // deprecated
142 );
143
144 }
145
146 /**
147 * Filters the page option array.
148 *
149 * This is triggered from the system validation method of the main Admin Page Framework factory class with the validation_saved_options_{page slug} filter hook.
150 *
151 * @since 3.0.0
152 * @param array
153 */
154 public function _replyToFilterPageOptions( $aPageOptions ) {
155
156 return $this->oForm->dropRepeatableElements( $aPageOptions );
157
158 }
159
160 /**
161 * Validates the submitted option values.
162 *
163 * This method is triggered with the validation_{page slug} or validation_{page slug}_{tab slug} method of the main Admin Page Framework factory class.
164 *
165 * @internal
166 * @sicne 3.0.0
167 * @param array $aNewPageOptions The array holing the field values of the page sent from the framework page class (the main class).
168 * @param array $aOldPageOptions The array holing the saved options of the page. Note that this will be empty if non of generic page fields are created.
169 */
170 public function _replyToValidateOptions( $aNewPageOptions, $aOldPageOptions ) {
171
172 // The field values of this class will not be included in the parameter array. So get them.
173 $_aFieldsModel = $this->oForm->getFieldsModel();
174 $_aNewMetaBoxInput = $this->oUtil->castArrayContents( $_aFieldsModel, $_POST );
175 $_aOldMetaBoxInput = $this->oUtil->castArrayContents( $_aFieldsModel, $aOldPageOptions );
176 $_aOtherOldMetaBoxInput = $this->oUtil->invertCastArrayContents( $aOldPageOptions, $_aFieldsModel );
177
178 // Apply filters - third party scripts will have access to the input.
179 $_aNewMetaBoxInput = stripslashes_deep( $_aNewMetaBoxInput ); // fixes magic quotes
180 $_aNewMetaBoxInput = $this->oUtil->addAndApplyFilters( $this, "validation_{$this->oProp->sClassName}", $_aNewMetaBoxInput, $_aOldMetaBoxInput, $this );
181
182 // Now merge the input values with the passed page options, and plus the old data to cover different in-page tab field options.
183 return $this->oUtil->uniteArrays( $_aNewMetaBoxInput, $aNewPageOptions, $_aOtherOldMetaBoxInput );
184
185 }
186
187 /**
188 * Registers form fields and sections.
189 *
190 * @since 3.0.0
191 * @internal
192 */
193 public function _replyToRegisterFormElements( $oScreen ) {
194
195 // Schedule to add head tag elements and help pane contents.
196 if ( ! $this->_isInThePage() ) return;
197
198 $this->_loadDefaultFieldTypeDefinitions();
199
200 // Format the fields array.
201 $this->oForm->format();
202 $this->oForm->applyConditions(); // will create the conditioned elements.
203
204 // Add the repeatable section elements to the fields definition array.
205 $this->oForm->setDynamicElements( $this->oProp->aOptions ); // will update $this->oForm->aConditionedFields
206
207 $this->_registerFields( $this->oForm->aConditionedFields );
208
209 }
210
211 }
212 endif;