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