Completed
Push — master ( ef04cf...199149 )
by Mike
02:19
created

Metaboxes::get_metaboxes()   B

Complexity

Conditions 4
Paths 8

Size

Total Lines 23
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 4
eloc 9
c 2
b 0
f 1
nc 8
nop 1
dl 0
loc 23
rs 8.7972
1
<?php
2
namespace testContent;
3
4
/**
5
 * Class for handling CMB data
6
 *
7
 * @package    WordPress
8
 * @subpackage Evans
9
 * @author     Old Town Media
10
 */
11
class Metaboxes{
12
13
	/**
14
	 * Decide which cmb library to try and loop to get our metaboxes.
15
	 *
16
	 * Due to supporting multiple CMB libraries, we need to check which library
17
	 * is used on our site and then run the appropriate function. Currently
18
	 * supported libraries are CMB2 & Custom Metaboxes and Fields.
19
	 *
20
	 * @see get_cmb2_metaboxes, get_cmb1_metaboxes
21
	 *
22
	 * @param string $slug Post Type slug ID.
23
	 * @return array Fields to fill in for our post object.
24
	 */
25
	public function get_metaboxes( $slug ){
26
27
		$fields = array();
28
29
		// CMB2
30
		if ( class_exists( 'CMB2', false ) ) {
31
			$fields = $this->get_cmb2_metaboxes( $slug );
32
		}
33
34
		// Custom Metaboxes and Fields (CMB1)
35
		if ( class_exists( 'cmb_Meta_Box', false ) ) {
36
			$fields = $this->get_cmb1_metaboxes( $slug );
37
		}
38
39
		// Advanced Custom Fields (ACF Free)
40
		if ( class_exists( 'acf', false ) ) {
41
			$fields = $this->get_acf_free_metaboxes( $slug );
42
		}
43
44
		// Return our array
45
		return $fields;
46
47
	}
48
49
50
	private function get_acf_free_metaboxes( $slug ){
51
52
		// This damn plugin. Is. A. Freaking. Nightmare.
53
		$fieldsets = $this->get_all_acf_field_groups();
54
55
		if ( empty( $fieldsets ) ){
56
			return true;
57
		}
58
59
		foreach ( $fieldsets as $fieldset ){
60
61
			if ( $this->is_acf_field_in_post_type( $slug, $fieldset ) ){
62
63
				// If this is the first group of fields, simply set the value
64
				// Else, merge this group with the previous one
65
				if ( empty( $fields ) ){
66
					$fields = $fieldset->fields;
67
				} else {
68
					$fields = array_merge( $fields, $fieldset->fields );
69
				}
70
71
			}
72
73
		}
74
75
		return $fields;
0 ignored issues
show
Bug introduced by
The variable $fields does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
76
77
	}
78
79
80
	private function is_acf_field_in_post_type( $slug, $fieldset ){
81
82
		if ( empty( $fieldset ) ){
83
			return;
84
		}
85
86
		foreach ( $fieldset->rules as $rule ){
87
			if ( $rule['param'] === 'post_type' && $rule['value'] === $slug ){
88
				return true;
89
			}
90
		}
91
92
		return false;
93
94
	}
95
96
97
	private function get_all_acf_field_groups(){
98
		$info = $rules = $fields = array();
99
100
		$args = array(
101
			'post_type'		=> 'acf',
102
			'posts_per_page'=> 500
103
		);
104
105
		$objects = new \WP_Query( $args );
106
107
		if ( $objects->have_posts() ) :
108
			while ( $objects->have_posts() ) : $objects->the_post();
109
110
				$data = get_metadata( 'post', get_the_id() );
111
112
				foreach ( $data['rule'] as $rule ){
113
					$rules[] = unserialize( $rule );
114
				}
115
116
				foreach ( $data as $key => $value ){
117
					if ( substr( $key, 0, 6 ) == 'field_' ) :
118
						$field_detail = unserialize( $value[0] );
119
						$fields[] = array(
120
							'key'	 => $field_detail['key'],
121
							'type'	 => $field_detail['type'],
122
							'name'	 => $field_detail['label'],
123
							'id'	 => $field_detail['name'],
124
							'source' =>'acf'
125
						);
126
					endif;
127
				}
128
129
				$info[] = (object) array(
130
					'rules'		=> $rules,
131
					'fields'	=> $fields
132
				);
133
134
			endwhile;
135
		endif;
136
137
		return $info;
138
139
	}
140
141
142
	/**
143
	 * Gets all CMB2 custom metaboxes associated with a post type.
144
	 *
145
	 * Loops through all custom metabox fields registered with CMB2 and
146
	 * looks through them for matches on the given post type ID. Returns a single
147
	 * array of all boxes associated with the post type.
148
	 *
149
	 * @access private
150
	 *
151
	 * @see cmb2_meta_boxes
152
	 *
153
	 * @param string $slug a custom post type ID.
154
	 * @return array Array of fields.
155
	 */
156
	private function get_cmb2_metaboxes( $slug ){
157
158
		$fields = array();
159
160
		// Get all metaboxes from CMB2 library
161
		$all_metaboxes = apply_filters( 'cmb2_meta_boxes', array() );
162
163
		// Loop through all possible sets of metaboxes added the old way
164
		foreach ( $all_metaboxes as $metabox_array ){
165
166
			// If the custom post type ID matches this set of fields, set & stop
167
			if ( in_array( $slug, $metabox_array['object_types'] ) ) {
168
169
				// If this is the first group of fields, simply set the value
170
				// Else, merge this group with the previous one
171
				if ( empty( $fields ) ){
172
					$fields = $metabox_array['fields'];
173
				} else {
174
					$fields = array_merge( $fields, $metabox_array['fields'] );
175
				}
176
			}
177
178
		}
179
180
		// Loop through all metaboxes added the new way
181
		foreach ( \CMB2_Boxes::get_all() as $cmb ) {
182
183
			// Create the default
184
			$match = false;
185
186
			// Establish correct cmb types
187
			if ( is_string( $cmb->meta_box['object_types'] ) ){
188
				if ( $cmb->meta_box['object_types'] == $slug ){
189
					$match = true;
190
				}
191
			} else {
192
				if ( in_array( $slug, $cmb->meta_box['object_types'] ) ){
193
					$match = true;
194
				}
195
			}
196
197
			if ( $match !== true ){
198
				continue;
199
			}
200
201
			if ( empty( $fields ) ){
202
				$fields = $cmb->meta_box['fields'];
203
			} else {
204
				$fields = array_merge( $fields, $cmb->meta_box['fields'] );
205
			}
206
207
		}
208
209
		return $fields;
210
211
	}
212
213
214
	/**
215
	 * Gets all CMB1 custom metaboxes associated with a post type.
216
	 *
217
	 * Loops through all custom metabox fields registered with CMB2 and
218
	 * looks through them for matches on the given post type ID. Returns a single
219
	 * array of all boxes associated with the post type.
220
	 *
221
	 * @access private
222
	 *
223
	 * @see cmb_meta_boxes
224
	 *
225
	 * @param string $slug a custom post type ID.
226
	 * @return array Array of fields.
227
	 */
228
	private function get_cmb1_metaboxes( $slug ){
229
230
		$fields = array();
231
232
		// Get all metaboxes from CMB2 library
233
		$all_metaboxes = apply_filters( 'cmb_meta_boxes', array() );
234
235
		// Loop through all possible sets of metaboxes
236
		foreach ( $all_metaboxes as $metabox_array ){
237
238
			// If the custom post type ID matches this set of fields, set & stop
239
			if ( in_array( $slug, $metabox_array['pages'] ) ) {
240
241
				// If this is the first group of fields, simply set the value
242
				// Else, merge this group with the previous one
243
				if ( empty( $fields ) ){
244
					$fields = $metabox_array['fields'];
245
				} else {
246
					$fields = array_merge( $fields, $metabox_array['fields'] );
247
				}
248
			}
249
250
		}
251
252
		return $fields;
253
254
	}
255
256
257
	/**
258
	 * Assigns the proper testing data to a custom metabox.
259
	 *
260
	 * Swaps through the possible types of CMB2 supported fields and
261
	 * insert the appropriate data based on type & id.
262
	 * Some types are not yet supported due to low frequency of use.
263
	 *
264
	 * @see TestContent, add_post_meta
265
	 *
266
	 * @param int $post_id Single post ID.
267
	 * @param array $cmb custom metabox array from CMB2.
268
	 */
269
	public function random_metabox_content( $post_id, $cmb, $connected ){
270
		$value = '';
271
272
		// First check that our post ID & cmb array aren't empty
273
		if ( empty( $cmb ) || empty( $post_id ) ){
274
			return;
275
		}
276
277
		// Fetch the appropriate type of data and return
278
		switch( $cmb['type'] ){
279
280
			case 'text':
281
			case 'text_small':
282
			case 'text_medium':
283
284
				// If phone is in the id, fetch a phone #
285
				if ( stripos( $cmb['id'], 'phone' ) ){
286
					$value = TestContent::phone();
287
288
				// If email is in the id, fetch an email address
289
				} elseif ( stripos( $cmb['id'], 'email' ) ){
290
					$value = TestContent::email();
291
292
				// If time is in the id, fetch a time string
293
				} elseif ( stripos( $cmb['id'], 'time' ) ){
294
					$value = TestContent::time();
295
296
				// Otherwise, just a random text string
297
				} else {
298
					$value = TestContent::title( rand( 10, 50 ) );
299
				}
300
301
				break;
302
303
			case 'text_url':
304
305
				$value = TestContent::link();
306
307
				break;
308
309
			case 'text_email':
310
311
				$value = TestContent::email();
312
313
				break;
314
315
			case 'text_time':
316
317
				$value = TestContent::time();
318
319
				break;
320
321
			case 'select_timezone':
322
323
				$value = TestContent::timezone();
324
325
				break;
326
327
			case 'text_date':
328
329
				$value = TestContent::date( 'm/d/Y' );
330
331
				break;
332
333
			case 'text_date_timestamp':
334
			case 'text_datetime_timestamp':
335
336
				$value = TestContent::date( 'U' );
337
338
				break;
339
340
			// case 'text_datetime_timestamp_timezone': break;
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
341
342
			case 'text_money':
343
344
				$value = rand( 0, 100000 );
345
346
				break;
347
348
			case 'test_colorpicker':
349
350
				$value = '#' . str_pad( dechex( mt_rand( 0, 0xFFFFFF ) ), 6, '0', STR_PAD_LEFT );
351
352
				break;
353
354
			case 'textarea':
355
			case 'textarea_small':
356
			case 'textarea_code':
357
358
				$value = TestContent::plain_text();
359
360
				break;
361
362
			case 'select':
363
			case 'radio_inline':
364
			case 'radio':
365
366
				// Grab a random item out of the array and return the key
367
				$new_val = array_slice( $cmb['options'], rand( 0, count( $cmb['options'] ) ), 1 );
368
				$value = key( $new_val );
369
370
				break;
371
372
			// case 'taxonomy_radio': break;
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
373
			// case 'taxonomy_select': break;
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
374
			// case 'taxonomy_multicheck': break;
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
375
376
			case 'checkbox':
377
378
				// 50/50 odds of being turned on
379
				if ( rand( 0, 1 ) == 1 ){
380
					$value = 'on';
381
				}
382
383
				break;
384
385
			case 'multicheck':
386
387
				$new_option = array();
388
389
				// Loop through each of our options
390
				foreach ( $cmb['options'] as $key => $value ){
391
392
					// 50/50 chance of being included
393
					if ( rand( 0, 1 ) ){
394
						$new_option[] = $key;
395
					}
396
397
				}
398
399
				$value = $new_option;
400
401
				break;
402
403
			case 'wysiwyg':
404
405
				$value = TestContent::paragraphs();
406
407
				break;
408
409
			case 'file':
410
411
				if ( true == $connected ){
412
					$value = TestContent::image( $post_id );
413
				}
414
415
				break;
416
417
			// case 'file_list': break;
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
418
419
			case 'oembed':
420
421
				$value = TestContent::oembed();
422
423
				break;
424
425
		}
426
427
		// Value must exist to attempt to insert
428
		if ( !empty( $value ) && !is_wp_error( $value ) ){
429
430
			$type 	= $cmb['type'];
431
			$id		= $cmb['id'];
432
			$value = apply_filters( "tc_{$type}_metabox", $value );	// Filter by metabox type
433
			$value = apply_filters( "tc_{$id}_metabox", $value ); // Filter by metabox ID
434
435
			// Files must be treated separately - they use the attachment ID
436
			// & url of media for separate cmb values
437
			if ( $cmb['type'] != 'file' ){
438
				add_post_meta( $post_id, $cmb['id'], $value, true );
439
			} else {
440
				add_post_meta( $post_id, $cmb['id'].'_id', $value, true );
441
				add_post_meta( $post_id, $cmb['id'], wp_get_attachment_url( $value ), true );
442
			}
443
444
			if ( $cmb['source'] === 'acf' ){
445
				add_post_meta( $post_id, '_' . $cmb['id'], $cmb['key'], true );
446
			}
447
448
		// If we're dealing with a WP Error object, just return the message for debugging
449
		} elseif ( is_wp_error( $value ) ){
450
			error_log( $value->get_error_message() );
451
			return $value->get_error_message();
452
		}
453
454
	} // end random_metabox_content
455
456
}
457