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' ) ) :
10 /**
11 * Provides methods for creating meta boxes for post types.
12 *
13 * <h2>Hooks</h2>
14 * <p>The class automatically creates WordPress action and filter hooks associated with the class methods.
15 * The class methods corresponding to the name of the below actions and filters can be extended to modify the page output. Those methods are the callbacks of the filters and actions.</p>
16 * <h3>Methods and Action Hooks</h3>
17 * <ul>
18 * <li><strong>start_{extended class name}</strong> – triggered at the end of the class constructor.</li>
19 * <li><strong>do_{extended class name}</strong> – triggered when the meta box gets rendered.</li>
20 * </ul>
21 * <h3>Methods and Filter Hooks</h3>
22 * <ul>
23 * <li><strong>field_types_{extended class name}</strong> – receives the field type definition array. The first parameter: the field type definition array.</li>
24 * <li><strong>field_{extended class name}_{field ID}</strong> – receives the form input field output of the given input field ID. The first parameter: output string. The second parameter: the array of option.</li>
25 * <li><strong>content_{extended class name}</strong> – receives the entire output of the meta box. The first parameter: the output HTML string.</li>
26 * <li><strong>style_common_{extended class name}</strong> – receives the output of the base CSS rules applied to the pages of the associated post types with the meta box.</li>
27 * <li><strong>style_ie_common_{extended class name}</strong> – receives the output of the base CSS rules for Internet Explorer applied to the pages of the associated post types with the meta box.</li>
28 * <li><strong>style_{extended class name}</strong> – receives the output of the CSS rules applied to the pages of the associated post types with the meta box.</li>
29 * <li><strong>style_ie_{extended class name}</strong> – receives the output of the CSS rules for Internet Explorer applied to the pages of the associated post types with the meta box.</li>
30 * <li><strong>script_common_{extended class name}</strong> – receives the output of the base JavaScript scripts applied to the pages of the associated post types with the meta box.</li>
31 * <li><strong>script_{extended class name}</strong> – receives the output of the JavaScript scripts applied to the pages of the associated post types with the meta box.</li>
32 * <li><strong>validation_{extended class name}</strong> – receives the form submission values as array. The first parameter: submitted input array. The second parameter: the original array stored in the database.</li>
33 * </ul>
34 * <h3>Remarks</h3>
35 * <p>The slugs must not contain a dot(.) or a hyphen(-) since it is used in the callback method name.</p>
36 *
37 * @abstract
38 * @since 2.0.0
39 * @use AdminPageFramework_Utility
40 * @use AdminPageFramework_Message
41 * @use AdminPageFramework_Debug
42 * @use AdminPageFramework_Property_MetaBox
43 * @package AdminPageFramework
44 * @subpackage MetaBox
45 */
46 abstract class AdminPageFramework_MetaBox extends AdminPageFramework_MetaBox_Base {
47
48 /**
49 * Defines the fields type.
50 * @since 3.0.0
51 * @internal
52 */
53 static protected $_sFieldsType = 'post_meta_box';
54
55 /**
56 * Constructs the class object instance of AdminPageFramework_MetaBox.
57 *
58 * Sets up properties and hooks.
59 *
60 * <h4>Example</h4>
61 * <code>
62 * new APF_MetaBox_BuiltinFieldTypes(
63 * 'sample_custom_meta_box', // meta box ID
64 * __( 'Demo Meta Box with Built-in Field Types', 'admin-page-framework-demo' ), // title
65 * array( 'apf_posts' ), // post type slugs: post, page, etc.
66 * 'normal', // context (what kind of metabox this is)
67 * 'default' // priority
68 * );
69 * </code>
70 * @see http://codex.wordpress.org/Function_Reference/add_meta_box#Parameters
71 * @since 2.0.0
72 * @param string The meta box ID.
73 * @param string The meta box title.
74 * @param string|array ( optional ) The post type(s) or screen ID that the meta box is associated with.
75 * @param string ( optional ) The part of the page where the edit screen section should be shown ('normal', 'advanced', or 'side') Default: normal.
76 * @param string ( optional ) The priority within the context where the boxes should show ('high', 'core', 'default' or 'low') Default: default.
77 * @param string ( optional ) The <a href="http://codex.wordpress.org/Roles_and_Capabilities">access level</a> to the meta box. Default: edit_posts.
78 * @param string ( optional ) The text domain applied to the displayed text messages. Default: admin-page-framework.
79 * @return void
80 */
81 function __construct( $sMetaBoxID, $sTitle, $asPostTypeOrScreenID=array( 'post' ), $sContext='normal', $sPriority='default', $sCapability='edit_posts', $sTextDomain='admin-page-framework' ) {
82
83 /* The property object needs to be done first */
84 $this->oProp = new AdminPageFramework_Property_MetaBox( $this, get_class( $this ), $sCapability );
85
86 parent::__construct( $sMetaBoxID, $sTitle, $asPostTypeOrScreenID, $sContext, $sPriority, $sCapability, $sTextDomain );
87
88 /* Do this after the parent constructor as the constructor creates the oProp object and before the isInThePage() method. */
89 $this->oProp->aPostTypes = is_string( $asPostTypeOrScreenID ) ? array( $asPostTypeOrScreenID ) : $asPostTypeOrScreenID;
90
91 if ( $this->_isInThePage() ) :
92
93 $this->oHeadTag = new AdminPageFramework_HeadTag_MetaBox( $this->oProp );
94 $this->oHelpPane = new AdminPageFramework_HelpPane_MetaBox( $this->oProp );
95
96 // Create a form object - this needs to be done after the fields type property is set. This is the reason that it's not doen in the base class.
97 $this->oProp->sFieldsType = self::$_sFieldsType;
98 $this->oForm = new AdminPageFramework_FormElement( $this->oProp->sFieldsType, $sCapability );
99
100 endif;
101
102 $this->oUtil->addAndDoAction( $this, "start_{$this->oProp->sClassName}" );
103
104
105 }
106 /**
107 * Determines whether the meta box belongs to the loading page.
108 *
109 * @since 3.0.3
110 * @internal
111 */
112 protected function _isInThePage() {
113
114 if ( ! in_array( $GLOBALS['pagenow'], array( 'post.php', 'post-new.php' ) ) ) {
115 return false;
116 }
117
118 if ( ! in_array( $this->oUtil->getCurrentPostType(), $this->oProp->aPostTypes ) ) {
119 return false;
120 }
121
122 return true;
123
124 }
125
126 /**
127 * The method for all necessary set-ups.
128 *
129 * <h4>Example</h4>
130 * <code> public function setUp() {
131 * $this->addSettingFields(
132 * array(
133 * 'field_id' => 'sample_metabox_text_field',
134 * 'title' => 'Text Input',
135 * 'description' => 'The description for the field.',
136 * 'type' => 'text',
137 * ),
138 * array(
139 * 'field_id' => 'sample_metabox_textarea_field',
140 * 'title' => 'Textarea',
141 * 'description' => 'The description for the field.',
142 * 'type' => 'textarea',
143 * 'default' => 'This is a default text.',
144 * )
145 * );
146 * }</code>
147 *
148 * @abstract
149 * @since 2.0.0
150 * @remark The user should override this method.
151 * @return void
152 */
153 public function setUp() {}
154
155 /**
156 * Enqueues styles by page slug and tab slug.
157 *
158 * @since 3.0.0
159 */
160 public function enqueueStyles( $aSRCs, $aPostTypes=array(), $aCustomArgs=array() ) {
161 return $this->oHeadTag->_enqueueStyles( $aSRCs, $aPostTypes, $aCustomArgs );
162 }
163 /**
164 * Enqueues a style by page slug and tab slug.
165 *
166 * @since 3.0.0
167 * @see http://codex.wordpress.org/Function_Reference/wp_enqueue_style
168 * @param string The source of the stylesheet to enqueue: the URL, the absolute file path, or the relative path to the root directory of WordPress. Example: '/css/mystyle.css'.
169 * <h4>Custom Argument Array</h4>
170 * <ul>
171 * <li><strong>handle_id</strong> - ( optional, string ) The handle ID of the stylesheet.</li>
172 * <li><strong>dependencies</strong> - ( optional, array ) The dependency array. For more information, see <a href="http://codex.wordpress.org/Function_Reference/wp_enqueue_style">codex</a>.</li>
173 * <li><strong>version</strong> - ( optional, string ) The stylesheet version number.</li>
174 * <li><strong>media</strong> - ( optional, string ) the description of the field which is inserted into after the input field tag.</li>
175 * </ul>
176 * @param array (optional) The post type slugs that the stylesheet should be added to. If not set, it applies to all the pages of the post types.
177 * @param array (optional) The argument array for more advanced parameters.
178 * @return string The script handle ID. If the passed url is not a valid url string, an empty string will be returned.
179 */
180 public function enqueueStyle( $sSRC, $aPostTypes=array(), $aCustomArgs=array() ) {
181 return $this->oHeadTag->_enqueueStyle( $sSRC, $aPostTypes, $aCustomArgs );
182 }
183 /**
184 * Enqueues scripts by page slug and tab slug.
185 *
186 * @since 3.0.0
187 */
188 public function enqueueScripts( $aSRCs, $aPostTypes=array(), $aCustomArgs=array() ) {
189 return $this->oHeadTag->_enqueueScripts( $aSRCs, $aPostTypes, $aCustomArgs );
190 }
191 /**
192 * Enqueues a script by page slug and tab slug.
193 *
194 * <h4>Example</h4>
195 * <code>$this->enqueueScript(
196 * plugins_url( 'asset/js/test.js' , __FILE__ ), // source url or path
197 * array( 'my_post_type_slug' ),
198 * array(
199 * 'handle_id' => 'my_script', // this handle ID also is used as the object name for the translation array below.
200 * 'translation' => array(
201 * 'a' => 'hello world!',
202 * 'style_handle_id' => $sStyleHandle, // check the enqueued style handle ID here.
203 * ),
204 * )
205 * );</code>
206 *
207 * @since 2.1.2
208 * @see http://codex.wordpress.org/Function_Reference/wp_enqueue_script
209 * @param string The source of the stylesheet to enqueue: the URL, the absolute file path, or the relative path to the root directory of WordPress. Example: '/js/myscript.js'.
210 * <h4>Custom Argument Array</h4>
211 * <ul>
212 * <li><strong>handle_id</strong> - ( optional, string ) The handle ID of the script.</li>
213 * <li><strong>dependencies</strong> - ( optional, array ) The dependency array. For more information, see <a href="http://codex.wordpress.org/Function_Reference/wp_enqueue_script">codex</a>.</li>
214 * <li><strong>version/strong> - ( optional, string ) The stylesheet version number.</li>
215 * <li><strong>translation</strong> - ( optional, array ) The translation array. The handle ID will be used for the object name.</li>
216 * <li><strong>in_footer</strong> - ( optional, boolean ) Whether to enqueue the script before </head > or before </body> Default: <em>false</em>.</li>
217 * </ul>
218 * @param string (optional) The page slug that the script should be added to. If not set, it applies to all the pages created by the framework.
219 * @param string (optional) The tab slug that the script should be added to. If not set, it applies to all the in-page tabs in the page.
220 * @param array (optional) The argument array for more advanced parameters.
221 * @return string The script handle ID. If the passed url is not a valid url string, an empty string will be returned.
222 */
223 public function enqueueScript( $sSRC, $aPostTypes=array(), $aCustomArgs=array() ) {
224 return $this->oHeadTag->_enqueueScript( $sSRC, $aPostTypes, $aCustomArgs );
225 }
226
227 /**
228 * Adds the defined meta box.
229 *
230 * @since 2.0.0
231 * @internal
232 * @remark uses <em>add_meta_box()</em>.
233 * @remark A callback for the <em>add_meta_boxes</em> hook.
234 * @return void
235 */
236 public function _replyToAddMetaBox() {
237
238 foreach( $this->oProp->aPostTypes as $sPostType )
239 add_meta_box(
240 $this->oProp->sMetaBoxID, // id
241 $this->oProp->sTitle, // title
242 array( $this, '_replyToPrintMetaBoxContents' ), // callback
243 $sPostType, // post type
244 $this->oProp->sContext, // context
245 $this->oProp->sPriority, // priority
246 null // deprecated $this->oForm->aFields // argument
247 );
248
249 }
250
251 /**
252 * Registers form fields and sections.
253 *
254 * @since 3.0.0
255 * @internal
256 */
257 public function _replyToRegisterFormElements() {
258
259 // Schedule to add head tag elements and help pane contents.
260 if ( ! $this->oUtil->isPostDefinitionPage( $this->oProp->aPostTypes ) ) return;
261
262 // Format the fields array.
263 $this->oForm->format();
264 $this->oForm->applyConditions(); // will set $this->oForm->aConditionedFields
265 // $this->oForm->applyFiltersToFields( $this, $this->oProp->sClassName );
266
267 // Set the option array - the framework will refer to this data when displaying the fields.
268 if ( isset( $this->oProp->aOptions ) )
269 $this->setOptionArray(
270 isset( $GLOBALS['post']->ID ) ? $GLOBALS['post']->ID : ( isset( $_GET['page'] ) ? $_GET['page'] : null ),
271 $this->oForm->aConditionedFields
272 ); // will set $this->oProp->aOptions
273
274 // Add the repeatable section elements to the fields definition array.
275 $this->oForm->setDynamicElements( $this->oProp->aOptions ); // will update $this->oForm->aConditionedFields
276
277 $this->_registerFields( $this->oForm->aConditionedFields );
278
279 }
280
281 }
282 endif;