Passed
Push — master ( 26770f...806cdd )
by Chris
03:20
created

CMB_Meta_Box::show()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 5
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * Create meta boxes
5
 */
6
class CMB_Meta_Box {
7
8
	protected $_meta_box;
9
	private $fields = array();
10
11
	function __construct( $meta_box ) {
12
13
		$this->_meta_box = $meta_box;
14
15
		if ( empty( $this->_meta_box['id'] ) )
16
			$this->_meta_box['id'] = sanitize_title( $this->_meta_box['title'] );
17
18
		add_action( 'add_meta_boxes', array( &$this, 'init_fields_for_post' ) );
19
		add_action( 'cmb_init_fields', array( &$this, 'init_fields' ) );
20
21
		add_action( 'admin_menu', array( &$this, 'add' ) );
22
		add_action( 'save_post', array( &$this, 'save_for_post' ) );
23
		add_action( 'edit_attachment', array( &$this, 'save_for_post' ) );
24
		add_action( 'cmb_save_fields', array( &$this, 'save' ) );
25
26
		add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_scripts' ), 9 );
27
		add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue_styles' ), 9 );
28
29
	}
30
31
	public function init_fields( $post_id = 0 ) {
32
33
		foreach ( $this->_meta_box['fields'] as $key => $field ) {
34
35
			$values = array();
36
37
			$args = $field;
38
			unset( $args['id'] );
39
			unset( $args['type'] );
40
			unset( $args['name'] );
41
42
			$class = _cmb_field_class_for_type( $field['type'] );
43
44
			// If we are on a post edit screen - get metadata value of the field for this post
45
			if ( $post_id ) {
46
				$values = (array) get_post_meta( $post_id, $field['id'], false );
47
			}
48
49
			if ( class_exists( $class ) ) {
50
				$this->fields[] = new $class( $field['id'], $field['name'], (array) $values, $args );
51
			}
52
53
		}
54
55
	}
56
57
	public function init_fields_for_post() {
58
59
		global $post, $temp_ID;
60
61
		// Get the current ID
62
		if( isset( $_GET['post'] ) )
63
			$post_id = $_GET['post'];
64
65
		elseif( isset( $_POST['post_ID'] ) )
66
			$post_id = $_POST['post_ID'];
67
68
		elseif ( ! empty( $post->ID ) )
69
			$post_id = $post->ID;
70
71
		if ( is_page() || ! isset( $post_id ) )
72
			return false;
73
74
		$this->init_fields( (int) $post_id );
75
76
	}
77
78
	function enqueue_scripts() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
79
80
		wp_enqueue_script( 'cmb-scripts', trailingslashit( CMB_URL ) . 'js/cmb.js', array( 'jquery' ) );
81
82
		wp_localize_script( 'cmb-scripts', 'CMBData', array(
83
			'strings' => array(
84
				'confirmDeleteField' => __( 'Are you sure you want to delete this field?', 'cmb' )
85
			)
86
		) );
87
88
		foreach ( $this->fields as $field )
89
			$field->enqueue_scripts();
90
91
	}
92
93
	function enqueue_styles() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
94
95
		$suffix = CMB_DEV ? '' : '.min';
96
97
		if ( version_compare( get_bloginfo( 'version' ), '3.8', '>=' ) )
98
			wp_enqueue_style( 'cmb-styles', trailingslashit( CMB_URL ) . "css/dist/cmb$suffix.css" );
99
		else
100
			wp_enqueue_style( 'cmb-styles', trailingslashit( CMB_URL ) . 'css/legacy.css' );
101
102
		foreach ( $this->fields as $field )
103
			$field->enqueue_styles();
104
105
	}
106
107
	// Add metabox
108
	function add() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
109
110
		$this->_meta_box['context'] = empty($this->_meta_box['context']) ? 'normal' : $this->_meta_box['context'];
111
		$this->_meta_box['priority'] = empty($this->_meta_box['priority']) ? 'low' : $this->_meta_box['priority'];
112
113
		// Backwards compatablilty.
114
		if ( isset( $this->_meta_box['show_on']['key'] ) ) {
115
			$this->_meta_box['show_on'][ $this->_meta_box['show_on']['key'] ] = $this->_meta_box['show_on']['value'];
116
			unset( $this->_meta_box['show_on']['key'] );
117
			unset( $this->_meta_box['show_on']['value'] );
118
		}
119
120
		foreach ( (array) $this->_meta_box['pages'] as $page ) {
121
			if ( $this->is_metabox_displayed() ) {
122
				add_meta_box( $this->_meta_box['id'], $this->_meta_box['title'], array(&$this, 'show'), $page, $this->_meta_box['context'], $this->_meta_box['priority'] ) ;
123
			}
124
		}
125
126
	}
127
128
	/**
129
	 * Handle 'Show On' and 'Hide On' Filters
130
	 */
131
	function is_metabox_displayed() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
132
		$display = true;
133
		$display = $this->add_for_id( $display );
134
		$display = $this->hide_for_id( $display );
135
		$display = $this->add_for_page_template( $display );
136
		$display = $this->hide_for_page_template( $display );
137
		return $display;
138
	}
139
140
	// Add CMB for ID
141
	function add_for_id( $display ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
142
143
		if ( ! isset( $this->_meta_box['show_on']['id'] ) ) {
144
			return $display;
145
		}
146
147
		// Don't show CMB if we can't identify ID of a post
148
		$post_id = $this->get_post_id();
149
150
		if ( ! isset( $post_id ) ) {
151
			return false;
152
		}
153
154
		// If value isn't an array, turn it into one
155
		$this->_meta_box['show_on']['id'] = ! is_array( $this->_meta_box['show_on']['id'] ) ? array( $this->_meta_box['show_on']['id'] ) : $this->_meta_box['show_on']['id'];
156
157
		return in_array( $post_id, $this->_meta_box['show_on']['id'] );
158
159
	}
160
161
	// Hide CMB for ID
162
	function hide_for_id( $display ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
163
164
		if ( ! isset( $this->_meta_box['hide_on']['id'] ) ) {
165
			return $display;
166
		}
167
168
		// Return if we can't identify ID of a post
169
		$post_id = $this->get_post_id();
170
		if ( ! isset( $post_id ) ) {
171
			return $display;
172
		}
173
174
		// If value isn't an array, turn it into one
175
		$this->_meta_box['hide_on']['id'] = ! is_array( $this->_meta_box['hide_on']['id'] ) ? array( $this->_meta_box['hide_on']['id'] ) : $this->_meta_box['hide_on']['id'];
176
177
		return ! in_array( $post_id, $this->_meta_box['hide_on']['id'] );
178
179
	}
180
181
	// Add CMB for Page Template
182
	function add_for_page_template( $display ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
183
184
		if ( ! isset( $this->_meta_box['show_on']['page-template'] ) ) {
185
			return $display;
186
		}
187
188
		// Return false if we can't identify ID of a post
189
		$post_id = $this->get_post_id();
190
		if ( ! isset( $post_id ) ) {
191
			return false;
192
		}
193
194
		// Get current template
195
		$current_template = get_post_meta( $post_id, '_wp_page_template', true );
196
197
		// If value isn't an array, turn it into one
198
		$this->_meta_box['show_on']['page-template'] = ! is_array( $this->_meta_box['show_on']['page-template'] ) ? array( $this->_meta_box['show_on']['page-template'] ) : $this->_meta_box['show_on']['page-template'];
199
200
		return in_array( $current_template, $this->_meta_box['show_on']['page-template'] );
201
202
	}
203
204
	// Hide CMB for Page Template
205
	function hide_for_page_template( $display ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
206
207
		if ( ! isset( $this->_meta_box['hide_on']['page-template'] ) ) {
208
			return $display;
209
		}
210
211
		// Return $display if we can't identify ID of a post and hence its current template
212
		$post_id = $this->get_post_id();
213
214
		if ( ! isset( $post_id ) ) {
215
			return $display;
216
		}
217
218
		// Get current template
219
		$current_template = get_post_meta( $post_id, '_wp_page_template', true );
220
221
		// If value isn't an array, turn it into one
222
		$this->_meta_box['hide_on']['page-template'] = ! is_array( $this->_meta_box['hide_on']['page-template'] ) ? array( $this->_meta_box['hide_on']['page-template'] ) : $this->_meta_box['hide_on']['page-template'];
223
224
		return ! in_array( $current_template, $this->_meta_box['hide_on']['page-template'] );
225
226
	}
227
228
	// display fields
229
	function show() { ?>
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
230
231
		<input type="hidden" name="wp_meta_box_nonce" value="<?php esc_attr_e( wp_create_nonce( basename(__FILE__) ) ); ?>" />
232
233
		<?php self::layout_fields( $this->fields );
234
235
	}
236
237
	/**
238
	 * Layout an array of fields, depending on their 'cols' property.
239
	 *
240
	 * This is a static method so other fields can use it that rely on sub fields
241
	 *
242
	 * @param  CMB_Field[]  $fields
243
	 */
244
	static function layout_fields( array $fields ) { ?>
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
245
246
		<div class="cmb_metabox">
247
248
			<?php $current_colspan = 0;
249
250
			foreach ( $fields as $field ) :
251
252
				if ( $current_colspan == 0 ) : ?>
253
254
					<div class="cmb-row">
255
256
				<?php endif;
257
258
				$current_colspan += $field->args['cols'];
259
260
				$classes = array( 'field', get_class($field) );
261
262
				if ( ! empty( $field->args['repeatable'] ) )
263
					$classes[] = 'repeatable';
264
265
				if ( ! empty( $field->args['sortable'] ) )
266
					$classes[] = 'cmb-sortable';
267
268
				$attrs = array(
269
					sprintf( 'id="%s"', sanitize_html_class( $field->id ) ),
270
					sprintf( 'class="%s"', esc_attr( implode(' ', array_map( 'sanitize_html_class', $classes ) ) ) )
271
				);
272
273
				// Field Repeatable Max.
274
				if ( isset( $field->args['repeatable_max']  ) )
275
					$attrs[] = sprintf( 'data-rep-max="%s"', intval( $field->args['repeatable_max'] ) );
276
277
				?>
278
279
				<div class="cmb-cell-<?php echo intval( $field->args['cols'] ); ?>">
280
281
						<div <?php echo implode( ' ', $attrs ); ?>>
282
							<?php $field->display(); ?>
283
						</div>
284
285
						<input type="hidden" name="_cmb_present_<?php esc_attr_e( $field->id ); ?>" value="1" />
286
287
				</div>
288
289
				<?php if ( $current_colspan == 12 || $field === end( $fields ) ) :
290
291
					$current_colspan = 0; ?>
292
293
					</div><!-- .cmb-row -->
294
295
				<?php endif; ?>
296
297
			<?php endforeach; ?>
298
299
		</div>
300
301
	<?php }
302
303
	function strip_repeatable( $values ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
304
305
		foreach ( $values as $key => $value ) {
306
307
			if ( false !== strpos( $key, 'cmb-group-x' ) || false !==  strpos( $key, 'cmb-field-x' ) )
308
				unset( $values[$key] );
309
310
			elseif ( is_array( $value ) )
311
				$values[$key] = $this->strip_repeatable( $value );
312
313
		}
314
315
		return $values;
316
	}
317
318
	// Save data from metabox
319
	function save( $post_id = 0 ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
320
321
		// Verify nonce
322
		if ( ! isset( $_POST['wp_meta_box_nonce'] ) || ! wp_verify_nonce( $_POST['wp_meta_box_nonce'], basename( __FILE__ ) ) )
323
			return $post_id;
324
325
		foreach ( $this->_meta_box['fields'] as $field ) {
326
327
			// Verify this meta box was shown on the page
328
			if ( ! isset( $_POST['_cmb_present_' . $field['id'] ] ) )
329
				continue;
330
331
			if ( isset( $_POST[ $field['id'] ] ) )
332
				$value = (array) $_POST[ $field['id'] ];
333
			else
334
				$value = array();
335
336
			$value = $this->strip_repeatable( $value );
337
338
			if ( ! $class = _cmb_field_class_for_type( $field['type'] ) ) {
339
				do_action( 'cmb_save_' . $field['type'], $field, $value );
340
			}
341
342
			$field_obj = new $class( $field['id'], $field['name'], $value, $field );
343
			if ( 'post_select' === $field['type'] || 'group' === $field['type'] ) {
344
				do_action('cmb_save_custom', $post_id, $field, $value);
345
			}
346
			$field_obj->save( $post_id, $value );
347
348
		}
349
350
		// If we are not on a post, need to refresh the field objects to reflect new values, as we do not get a redirect
351
		if ( ! $post_id ) {
352
			$this->fields = array();
353
			$this->init_fields();
354
		}
355
	}
356
357
	// Save the on save_post hook
358
	function save_for_post( $post_id ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
359
360
		// check autosave
361
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
362
			return $post_id;
363
364
		$this->save( $post_id );
365
366
	}
367
368
	function get_post_id() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
369
370
		$post_id = isset( $_GET['post'] ) ? $_GET['post'] : null;
371
372
		if ( ! $post_id && isset( $_POST['post_id'] ) ) {
373
			$post_id = $_POST['post_id'];
374
		}
375
376
		return $post_id;
377
378
	}
379
}
380