Completed
Push — develop ( 16cebd...958332 )
by David
01:30
created

metabox::get_data()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 20
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 5

Importance

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