1 <?php
2 /**
3 * UIX Metaboxes
4 *
5 * @package ui
6 * @author David Cramer
7 * @license GPL-2.0+
8 * @link
9 * @copyright 2016 David Cramer
10 */
11 namespace uix\ui;
12
13 /**
14 * Metabox class for adding metaboxes to post types in the post editor
15 * @package uix\ui
16 * @author David Cramer
17 */
18 class metabox extends panel {
19
20 /**
21 * The type of object
22 *
23 * @since 1.0.0
24 * @access public
25 * @var string
26 */
27 public $type = 'metabox';
28
29 /**
30 * Holds the current post object
31 *
32 * @since 1.0.0
33 * @access public
34 * @var WP_Post
35 */
36 public $post = null;
37
38 /**
39 * Status of the metabox to determin if assets should be loaded
40 *
41 * @since 1.0.0
42 * @access public
43 * @var bool
44 */
45 public $is_active = false;
46
47
48 /**
49 * setup actions and hooks to add metaboxes and save metadata
50 *
51 * @since 1.0.0
52 * @access protected
53 */
54 protected function actions() {
55
56 // run parent to keep init and enqueuing assets
57 parent::actions();
58 // set screen activation
59 add_action( 'current_screen', array( $this, 'set_active_status'), 25 );
60 // add metaboxes
61 add_action( 'add_meta_boxes', array( $this, 'add_metaboxes'), 25 );
62 // save metabox
63 add_action( 'save_post', array( $this, 'save_meta' ), 10, 2 );
64
65 }
66
67 /**
68 * Setup submission data
69 *
70 * @since 1.0.0
71 * @access public
72 */
73 public function setup(){
74 // do parent
75 parent::setup();
76 if( !isset( $this->struct['screen'] ) ){
77 $this->struct['screen'] = null;
78 }
79 }
80
81 /**
82 * set metabox styles
83 *
84 * @since 1.0.0
85 * @see \uix\ui\uix
86 * @access public
87 */
88 public function set_assets() {
89
90 $this->assets['style']['metabox'] = $this->url . 'assets/css/metabox' . UIX_ASSET_DEBUG . '.css';
91 parent::set_assets();
92 }
93
94
95 /**
96 * Enqueues specific tabs assets for the active pages
97 *
98 * @since 1.0.0
99 * @access protected
100 */
101 protected function enqueue_active_assets(){
102 ?><style type="text/css">
103 #<?php echo $this->id(); ?>.uix-top-tabs > .uix-panel-tabs > li[aria-selected="true"] a,
104 #side-sortables #<?php echo $this->id(); ?> > .uix-panel-tabs > li[aria-selected="true"] a{
105 box-shadow: 0 3px 0 <?php echo $this->base_color(); ?> inset;
106 }
107 #<?php echo $this->id(); ?> > .uix-panel-tabs > li[aria-selected="true"] a {
108 box-shadow: 3px 0 0 <?php echo $this->base_color(); ?> inset;
109 }
110 <?php
111 $this->chromeless();
112 ?>
113 </style>
114 <?php
115
116 }
117
118 /**
119 * Writes script required to make a metabox `chromeless`
120 *
121 * @since 1.0.0
122 * @access protected
123 */
124 protected function chromeless(){
125
126 if( !empty( $this->struct['chromeless'] ) ){ ?>
127 #metabox-<?php echo $this->id(); ?>{
128 background: transparent none repeat scroll 0 0;
129 border: 0 none;
130 box-shadow: none;
131 margin: 0 0 20px;
132 padding: 0;
133 }
134 #metabox-<?php echo $this->id(); ?> .handlediv.button-link,
135 #metabox-<?php echo $this->id(); ?> .hndle {display: none;}
136 #metabox-<?php echo $this->id(); ?> > .inside {padding: 0;}
137 <?php }
138
139 }
140 /**
141 * Checks the screen object to determin if the metabox should load assets
142 *
143 * @since 1.0.0
144 * @access public
145 * @uses "current_screen" hook
146 * @param screen $screen The current screen object;
147 */
148 public function set_active_status( $screen ){
149
150 if( $screen->base == 'post' && ( null === $this->struct['screen'] || in_array( $screen->id, ( array ) $this->struct['screen'] ) ) )
151 $this->is_active = true;
152
153 }
154 /**
155 * Add metaboxes to screen
156 *
157 * @since 1.0.0
158 * @access public
159 * @uses "add_meta_boxes" hook
160 */
161 public function add_metaboxes(){
162
163 // metabox defaults
164 $defaults = array(
165 'screen' => null,
166 'context' => 'advanced',
167 'priority' => 'default',
168 );
169
170 $metabox = array_merge( $defaults, $this->struct );
171
172 add_meta_box(
173 'metabox-' . $this->id(),
174 $metabox['name'],
175 array( $this, 'create_metabox' ),
176 $metabox['screen'],
177 $metabox['context'],
178 $metabox['priority']
179 );
180
181 }
182
183 /**
184 * Callback for the `add_meta_box` that sets the metabox data and renders it
185 *
186 * @since 1.0.0
187 * @uses "add_meta_box" function
188 * @access public
189 * @param wp_post $post Current post for the metabox
190 */
191 public function create_metabox( $post ){
192
193 $this->post = $post;
194
195 $pre_data = $this->get_data();
196 $data = array();
197 foreach( (array) $pre_data as $pkey => $pvalue ){
198 foreach( (array) $pvalue as $key => $value ){
199 $data[$pkey][$key] = get_post_meta($post->ID, $key, true);
200 }
201 }
202
203 $this->set_data( $data );
204
205 echo $this->render();
206
207 }
208
209 /**
210 * Render the Metabox
211 *
212 * @since 1.0.0
213 * @access public
214 * @return string HTML of rendered metabox
215 */
216 public function render(){
217
218
219 // render fields setup
220 return parent::render();
221
222
223 }
224
225
226 /**
227 * Saves a metabox data
228 *
229 * @uses "save_post" hook
230 * @since 1.0.0
231 * @access public
232 * @param int $post_id ID of the current post being saved
233 * @param wp_post $post Current post being saved
234 */
235 public function save_meta( $post_id, $post ){
236
237 $this->post = $post;
238 $data = $this->get_data();
239
240 if( ! $this->is_active() || empty( $data ) ){ return; }
241
242 // save compiled data
243 update_post_meta( $post_id, $this->slug, $data );
244 $data = call_user_func_array( 'array_merge', $data );
245
246 foreach( $data as $meta_key => $meta_value ){
247
248 $this->save_meta_data( $meta_key, $meta_value );
249 }
250
251
252 }
253
254 /**
255 * Save the meta data for the post
256 *
257 * @since 1.0.0
258 * @access private
259 * @param string $slug slug of the meta_key
260 * @param mixed $data Data to be saved
261 */
262 private function save_meta_data( $slug, $data ){
263
264 $prev = get_post_meta( $this->post->ID, $slug, true );
265
266 if ( null === $data && $prev ){
267 delete_post_meta( $this->post->ID, $slug );
268 }elseif ( $data !== $prev ) {
269 update_post_meta( $this->post->ID, $slug, $data );
270 }
271
272 }
273
274 /**
275 * Determin which metaboxes are used for the current screen and set them active
276 * @since 1.0.0
277 * @access public
278 */
279 public function is_active(){
280 return $this->is_active;
281 }
282
283 }