Completed
Pull Request — trunk (#698)
by Justin
37:05 queued 28:16
created

helper-functions.php ➔ cmb2_get_field()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 7
c 0
b 0
f 0
nc 8
nop 4
dl 0
loc 13
ccs 2
cts 2
cp 1
crap 5
rs 8.8571
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 18 and the first side effect is on line 111.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * CMB2 Helper Functions
4
 *
5
 * @category  WordPress_Plugin
6
 * @package   CMB2
7
 * @author    WebDevStudios
8
 * @license   GPL-2.0+
9 6
 * @link      http://webdevstudios.com
10 1
 */
11
12
/**
13 5
 * Helper function to provide directory path to CMB2
14 5
 * @since  2.0.0
15 5
 * @param  string  $path Path to append
16 5
 * @return string        Directory with optional path appended
17 5
 */
18
function cmb2_dir( $path = '' ) {
19
	return CMB2_DIR . $path;
20
}
21
22
/**
23
 * Autoloads files with CMB2 classes when needed
24
 * @since  1.0.0
25
 * @param  string $class_name Name of the class being requested
26 10
 */
27 10
function cmb2_autoload_classes( $class_name ) {
28 10
	if ( 0 !== strpos( $class_name, 'CMB2' ) ) {
29
		return;
30
	}
31
32
	$path = 'includes';
33
34
	if ( 'CMB2_Type' === $class_name || 0 === strpos( $class_name, 'CMB2_Type_' ) ) {
35
		$path .= '/types';
36
	}
37 2
38 2
	include_once( cmb2_dir( "$path/{$class_name}.php" ) );
39 2
}
40
41
/**
42
 * Get instance of the CMB2_Utils class
43
 * @since  2.0.0
44
 * @return CMB2_Utils object CMB2 utilities class
45
 */
46
function cmb2_utils() {
47
	static $cmb2_utils;
48 4
	$cmb2_utils = $cmb2_utils ? $cmb2_utils : new CMB2_Utils();
49
	return $cmb2_utils;
50
}
51
52
/**
53
 * Get instance of the CMB2_Ajax class
54
 * @since  2.0.0
55
 * @return CMB2_Ajax object CMB2 ajax class
56
 */
57
function cmb2_ajax() {
58
	return CMB2_Ajax::get_instance();
59
}
60
61
/**
62
 * Get instance of the CMB2_Option class for the passed metabox ID
63
 * @since  2.0.0
64
 * @return CMB2_Option object Options class for setting/getting options for metabox
65
 */
66 1
function cmb2_options( $key ) {
67
	return CMB2_Options::get( $key );
68
}
69
70
/**
71
 * Get a cmb oEmbed. Handles oEmbed getting for non-post objects
72
 * @since  2.0.0
73
 * @param  array   $args Arguments. Accepts:
74
 *
75
 *         'url'         - URL to retrieve the oEmbed from,
76
 *         'object_id'   - $post_id,
77 2
 *         'object_type' - 'post',
78
 *         'oembed_args' - $embed_args, // array containing 'width', etc
79
 *         'field_id'    - false,
80
 *         'cache_key'   - false,
81
 *         'wp_error'    - true/false, // To return a wp_error object if no embed found.
82
 *
83
 * @return string        oEmbed string
84
 */
85
function cmb2_get_oembed( $args = array() ) {
86
	$oembed = cmb2_ajax()->get_oembed_no_edit( $args );
87
88
	// Send back our embed
89
	if ( $oembed['embed'] && $oembed['embed'] != $oembed['fallback'] ) {
90 1
		return '<div class="cmb2-oembed">' . $oembed['embed'] . '</div>';
91 1
	}
92
93
	$error = sprintf( __( 'No oEmbed Results Found for %s. View more info at %s.', 'cmb2' ), $oembed['fallback'], ' <a href="http://codex.wordpress.org/Embeds" target="_blank">codex.wordpress.org/Embeds</a>' );
94
95
	if ( isset( $args['wp_error'] ) && $args['wp_error'] ) {
96
		return new WP_Error( 'cmb2_get_oembed_result', $wp_error, compact( 'oembed', 'args' ) );
0 ignored issues
show
Bug introduced by
The variable $wp_error does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
97
	}
98
99
	// Otherwise, send back error info that no oEmbeds were found
100
	return '<p class="ui-state-error-text">' . $error . '</p>';
101
}
102
103
/**
104
 * Outputs the return of cmb2_get_oembed.
105
 * @since  2.2.2
106
 * @see cmb2_get_oembed
107
 */
108 6
function cmb2_do_oembed( $args = array() ) {
109 6
	echo cmb2_get_oembed( $args );
110
}
111 6
add_action( 'cmb2_do_oembed', 'cmb2_do_oembed' );
112
113
/**
114
 * A helper function to get an option from a CMB2 options array
115 6
 * @since  1.0.1
116 6
 * @param  string  $option_key Option key
117
 * @param  string  $field_id   Option array field key
118 6
 * @param  mixed   $default    Optional default fallback value
119
 * @return array               Options array or specific field
120
 */
121
function cmb2_get_option( $option_key, $field_id = '', $default = false ) {
122
	return cmb2_options( $option_key )->get( $field_id, $default );
123
}
124
125
/**
126 6
 * A helper function to update an option in a CMB2 options array
127 6
 * @since  2.0.0
128 6
 * @param  string  $option_key Option key
129
 * @param  string  $field_id   Option array field key
130 6
 * @param  mixed   $value      Value to update data with
131 6
 * @param  boolean $single     Whether data should not be an array
132 6
 * @return boolean             Success/Failure
133 6
 */
134 6
function cmb2_update_option( $option_key, $field_id, $value, $single = true ) {
135
	if ( cmb2_options( $option_key )->update( $field_id, $value, false, $single ) ) {
136
		return cmb2_options( $option_key )->set();
137
	}
138
139
	return false;
140
}
141
142
/**
143
 * Get a CMB2 field object.
144
 * @since  1.1.0
145
 * @param  array  $meta_box    Metabox ID or Metabox config array
146
 * @param  array  $field_id    Field ID or all field arguments
147
 * @param  int    $object_id   Object ID
148
 * @param  string $object_type Type of object being saved. (e.g., post, user, comment, or options-page).
149
 *                             Defaults to metabox object type.
150 1
 * @return CMB2_Field|null     CMB2_Field object unless metabox config cannot be found
151 1
 */
152
function cmb2_get_field( $meta_box, $field_id, $object_id = 0, $object_type = '' ) {
153
154
	$object_id = $object_id ? $object_id : get_the_ID();
155
	$cmb = $meta_box instanceof CMB2 ? $meta_box : cmb2_get_metabox( $meta_box, $object_id );
156
157
	if ( ! $cmb ) {
158
		return;
159
	}
160
161
	$cmb->object_type( $object_type ? $object_type : $cmb->mb_object_type() );
0 ignored issues
show
Security Bug introduced by
It seems like $object_type ? $object_t... $cmb->mb_object_type() can also be of type false; however, CMB2::object_type() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
162 8
163 1
	return $cmb->get_field( $field_id );
164
}
165
166 8
/**
167 8
 * Get a field's value.
168 8
 * @since  1.1.0
169
 * @param  array  $meta_box    Metabox ID or Metabox config array
170 1
 * @param  array  $field_id    Field ID or all field arguments
171
 * @param  int    $object_id   Object ID
172 1
 * @param  string $object_type Type of object being saved. (e.g., post, user, comment, or options-page).
173
 *                             Defaults to metabox object type.
174
 * @return mixed               Maybe escaped value
175 8
 */
176 7
function cmb2_get_field_value( $meta_box, $field_id, $object_id = 0, $object_type = '' ) {
177 7
	$field = cmb2_get_field( $meta_box, $field_id, $object_id, $object_type );
178 8
	return $field->escaped_value();
179
}
180
181
/**
182
 * Because OOP can be scary
183
 * @since  2.0.2
184
 * @param  array $meta_box_config Metabox Config array
185
 * @return CMB2 object            Instantiated CMB2 object
186
 */
187
function new_cmb2_box( array $meta_box_config ) {
188
	return cmb2_get_metabox( $meta_box_config );
189
}
190
191 1
/**
192 1
 * Retrieve a CMB2 instance by the metabox ID
193
 * @since  2.0.0
194 1
 * @param  mixed  $meta_box    Metabox ID or Metabox config array
195
 * @param  int    $object_id   Object ID
196 1
 * @param  string $object_type Type of object being saved. (e.g., post, user, comment, or options-page).
197 1
 *                             Defaults to metabox object type.
198 1
 * @return CMB2 object
199
 */
200 1
function cmb2_get_metabox( $meta_box, $object_id = 0, $object_type = '' ) {
201
202
	if ( $meta_box instanceof CMB2 ) {
203
		return $meta_box;
204
	}
205
206
	if ( is_string( $meta_box ) ) {
207
		$cmb = CMB2_Boxes::get( $meta_box );
208
	} else {
209
		// See if we already have an instance of this metabox
210
		$cmb = CMB2_Boxes::get( $meta_box['id'] );
211
		// If not, we'll initate a new metabox
212 1
		$cmb = $cmb ? $cmb : new CMB2( $meta_box, $object_id );
213 1
	}
214
215
	if ( $cmb && $object_id ) {
216 1
		$cmb->object_id( $object_id );
217
	}
218
219
	if ( $cmb && $object_type ) {
220
		$cmb->object_type( $object_type );
221 1
	}
222
223
	return $cmb;
224
}
225
226
/**
227
 * Returns array of sanitized field values from a metabox (without saving them)
228 1
 * @since  2.0.3
229 1
 * @param  mixed $meta_box         Metabox ID or Metabox config array
230 1
 * @param  array $data_to_sanitize Array of field_id => value data for sanitizing (likely $_POST data).
231 1
 * @return mixed                   Array of sanitized values or false if no CMB2 object found
232
 */
233
function cmb2_get_metabox_sanitized_values( $meta_box, array $data_to_sanitize ) {
234
	$cmb = cmb2_get_metabox( $meta_box );
235
	return $cmb ? $cmb->get_sanitized_values( $data_to_sanitize ) : false;
236 1
}
237 1
238 1
/**
239 1
 * Retrieve a metabox form
240
 * @since  2.0.0
241 1
 * @param  mixed   $meta_box  Metabox config array or Metabox ID
242 1
 * @param  int     $object_id Object ID
243 1
 * @param  array   $args      Optional arguments array
244 1
 * @return string             CMB2 html form markup
245
 */
246 1
function cmb2_get_metabox_form( $meta_box, $object_id = 0, $args = array() ) {
247
248 1
	$object_id = $object_id ? $object_id : get_the_ID();
249
	$cmb       = cmb2_get_metabox( $meta_box, $object_id );
250
251 1
	ob_start();
252 1
	// Get cmb form
253
	cmb2_print_metabox_form( $cmb, $object_id, $args );
254 1
	$form = ob_get_contents();
255 1
	ob_end_clean();
256 1
257
	return apply_filters( 'cmb2_get_metabox_form', $form, $object_id, $cmb );
258 1
}
259
260
/**
261
 * Display a metabox form & save it on submission
262
 * @since  1.0.0
263
 * @param  mixed   $meta_box  Metabox config array or Metabox ID
264
 * @param  int     $object_id Object ID
265
 * @param  array   $args      Optional arguments array
266
 */
267
function cmb2_print_metabox_form( $meta_box, $object_id = 0, $args = array() ) {
0 ignored issues
show
Coding Style introduced by
cmb2_print_metabox_form uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
268
269
	$object_id = $object_id ? $object_id : get_the_ID();
270
	$cmb = cmb2_get_metabox( $meta_box, $object_id );
271
272
	// if passing a metabox ID, and that ID was not found
273
	if ( ! $cmb ) {
274
		return;
275
	}
276
277
	$args = wp_parse_args( $args, array(
278
		'form_format' => '<form class="cmb-form" method="post" id="%1$s" enctype="multipart/form-data" encoding="multipart/form-data"><input type="hidden" name="object_id" value="%2$s">%3$s<input type="submit" name="submit-cmb" value="%4$s" class="button-primary"></form>',
279
		'save_button' => __( 'Save', 'cmb2' ),
280
		'object_type' => $cmb->mb_object_type(),
281
		'cmb_styles'  => $cmb->prop( 'cmb_styles' ),
282
		'enqueue_js'  => $cmb->prop( 'enqueue_js' ),
283
	) );
284
285
	// Set object type explicitly (rather than trying to guess from context)
286
	$cmb->object_type( $args['object_type'] );
287
288
	// Save the metabox if it's been submitted
289
	// check permissions
290
	// @todo more hardening?
291
	if (
292
		$cmb->prop( 'save_fields' )
293
		// check nonce
294
		&& isset( $_POST['submit-cmb'], $_POST['object_id'], $_POST[ $cmb->nonce() ] )
295
		&& wp_verify_nonce( $_POST[ $cmb->nonce() ], $cmb->nonce() )
296
		&& $object_id && $_POST['object_id'] == $object_id
297
	) {
298
		$cmb->save_fields( $object_id, $cmb->object_type(), $_POST );
299
	}
300
301
	// Enqueue JS/CSS
302
	if ( $args['cmb_styles'] ) {
303
		CMB2_hookup::enqueue_cmb_css();
304
	}
305
306
	if ( $args['enqueue_js'] ) {
307
		CMB2_hookup::enqueue_cmb_js();
308
	}
309
310
	$form_format = apply_filters( 'cmb2_get_metabox_form_format', $args['form_format'], $object_id, $cmb );
311
312
	$format_parts = explode( '%3$s', $form_format );
313
314
	// Show cmb form
315
	printf( $format_parts[0], $cmb->cmb_id, $object_id );
316
	$cmb->show_form();
317
318
	if ( isset( $format_parts[1] ) && $format_parts[1] ) {
319
		printf( str_ireplace( '%4$s', '%1$s', $format_parts[1] ), $args['save_button'] );
320
	}
321
322
}
323
324
/**
325
 * Display a metabox form (or optionally return it) & save it on submission
326
 * @since  1.0.0
327
 * @param  mixed   $meta_box  Metabox config array or Metabox ID
328
 * @param  int     $object_id Object ID
329
 * @param  array   $args      Optional arguments array
330
 */
331
function cmb2_metabox_form( $meta_box, $object_id = 0, $args = array() ) {
332
	if ( ! isset( $args['echo'] ) || $args['echo'] ) {
333
		cmb2_print_metabox_form( $meta_box, $object_id, $args );
334
	} else {
335
		return cmb2_get_metabox_form( $meta_box, $object_id, $args );
336
	}
337
}
338
339
if ( ! function_exists( 'date_create_from_format' ) ) {
340
341
	/**
342
	 * Reimplementation of DateTime::createFromFormat for PHP < 5.3. :(
343
	 * Borrowed from http://stackoverflow.com/questions/5399075/php-datetimecreatefromformat-in-5-2
344
	 *
345
	 * @param $date_format
346
	 * @param $date_value
347
	 *
348
	 * @return DateTime
349
	 */
350
	function date_create_from_format( $date_format, $date_value ) {
351
352
		$schedule_format = str_replace(
353
			array( 'M', 'Y', 'm', 'd', 'H', 'i', 'a' ),
354
			array('%b', '%Y', '%m', '%d', '%H', '%M', '%p' ),
355
			$date_format
356
		);
357
358
		/*
359
		 * %Y, %m and %d correspond to date()'s Y m and d.
360
		 * %I corresponds to H, %M to i and %p to a
361
		 */
362
		$parsed_time = strptime( $date_value, $schedule_format );
363
364
		$ymd = sprintf(
365
			/*
366
			 * This is a format string that takes six total decimal
367
			 * arguments, then left-pads them with zeros to either
368
			 * 4 or 2 characters, as needed
369
			 */
370
			'%04d-%02d-%02d %02d:%02d:%02d',
371
			$parsed_time['tm_year'] + 1900,  // This will be "111", so we need to add 1900.
372
			$parsed_time['tm_mon'] + 1,      // This will be the month minus one, so we add one.
373
			$parsed_time['tm_mday'],
374
			$parsed_time['tm_hour'],
375
			$parsed_time['tm_min'],
376
			$parsed_time['tm_sec']
377
		);
378
379
		return new DateTime($ymd);
380
	}
381
}
382