Completed
Push — master ( 9d15c6...02d311 )
by Mike
02:28
created

CreatePost::get_cmb1_metaboxes()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 27
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 27
rs 8.5806
cc 4
eloc 10
nc 4
nop 1
1
<?php
2
namespace testContent;
3
4
/**
5
 * Class to build test data for custom post types.
6
 *
7
 * @package    WordPress
8
 * @subpackage Evans
9
 * @author     Old Town Media
10
 */
11
class CreatePost{
12
13
	/**
14
	 * Create test data posts.
15
	 *
16
	 * This is where the magic begins. We accept a cpt id (slug) and potntially
17
	 * a number of posts to create. We then fetch the supports & metaboxes
18
	 * for that cpt and feed them into a function to create each post individually.
19
	 *
20
	 * @access private
21
	 *
22
	 * @see $this->get_cpt_supports, $this->get_metaboxes, $this->create_test_object
23
	 *
24
	 * @param string $slug a custom post type ID.
25
	 * @param boolean $echo Whether or not to echo. Optional.
26
	 * @param int $num Optional. Number of posts to create.
27
	 */
28
	public function create_post_type_content( $slug, $echo = false, $num = '' ){
29
30
		// If we're missing a custom post type id - don't do anything
31
		if ( empty( $slug ) ){
32
			return;
33
		}
34
35
		// Gather the necessary data to create the posts
36
		$supports 	= $this->get_cpt_supports( $slug );
37
		$metaboxes	= $this->get_metaboxes( $slug );
38
39
		// If we forgot to put in a quantity, make one for us
40
		if ( empty( $num ) ){
41
			$num = rand( 5, 30 );
42
		}
43
44
		// Create test posts
45 View Code Duplication
		for( $i = 0; $i < $num; $i++ ){
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
46
47
			$return = $this->create_test_object( $slug, $supports, $metaboxes );
48
49
			if ( $echo === true ){
50
				echo \json_encode( $return );
51
			}
52
53
		}
54
55
	}
56
57
58
	/**
59
	 * Creates the individual test data post.
60
	 *
61
	 * Create individual posts for testing with. Gathers basic information such
62
	 * as title, content, thumbnail, etc. and inserts them with the post. Also
63
	 * adds metaboxes if applicable .
64
	 *
65
	 * @access private
66
	 *
67
	 * @see TestContent, wp_insert_post, add_post_meta, update_post_meta, $this->random_metabox_content
68
	 *
69
	 * @param string $slug a custom post type ID.
70
	 * @param array $supports Features that the post type supports.
71
	 * @param array $supports All CMB2 metaboxes attached to the post type.
72
	 */
73
	private function create_test_object( $slug, $supports, $metaboxes ){
74
		$return = '';
75
76
		// Get a random title
77
		$title = TestContent::title();
78
79
		// First, insert our post
80
		$post = array(
81
		  'post_name'      => sanitize_title( $title ),
82
		  'post_status'    => 'publish',
83
		  'post_type'      => $slug,
84
		  'ping_status'    => 'closed',
85
		  'comment_status' => 'closed',
86
		);
87
88
		// Add title if supported
89
		if ( $supports['title'] === true ){
90
			$post['post_title'] = $title;
91
		}
92
93
		// Add main content if supported
94
		if ( $supports['editor'] === true ){
95
			$post['post_content'] = TestContent::paragraphs();
96
		}
97
98
		// Insert then post object
99
		$post_id = wp_insert_post( $post );
100
101
		// Then, set a test content flag on the new post for later deletion
102
		add_post_meta( $post_id, 'evans_test_content', '__test__', true );
103
104
		// Add thumbnail if supported
105
		if ( $supports['thumbnail'] === true || in_array( $slug, array( 'post', 'page' ) ) ){
106
			 update_post_meta( $post_id, '_thumbnail_id', TestContent::image( $post_id ) );
107
		}
108
109
		$taxonomies = get_object_taxonomies( $slug );
110
111
		// Assign the post to terms
112
		if ( !empty( $taxonomies ) ){
113
			$return .= $this->assign_terms( $post_id, $taxonomies );
114
		}
115
116
		// Spin up metaboxes
117
		if ( !empty( $metaboxes ) ){
118
			foreach ( $metaboxes as $cmb ) :
119
				$return .= $this->random_metabox_content( $post_id, $cmb );
120
			endforeach;
121
		}
122
123
		// Check if we have errors and return them or created message
124
		if ( is_wp_error( $return ) ){
125
			return $return;
126
		} else {
127
			return array(
128
				'type'		=> 'created',
129
				'object'	=> 'post',
130
				'pid'		=> $post_id,
131
				'post_type'	=> get_post_type( $post_id ),
132
				'link_edit'	=> admin_url( '/post.php?post='.$post_id.'&action=edit' ),
133
				'link_view'	=> get_permalink( $post_id ),
134
			);
135
		}
136
137
	}
138
139
140
	/**
141
	 * Assemble supports statements for a particular post type.
142
	 *
143
	 * @access private
144
	 *
145
	 * @see post_type_supports
146
	 *
147
	 * @param string $slug a custom post type ID.
148
	 * @return array Array of necessary supports booleans.
149
	 */
150
	private function get_cpt_supports( $slug ){
151
152
		$supports = array(
153
			'title'		=> post_type_supports( $slug, 'title' ),
154
			'editor'	=> post_type_supports( $slug, 'editor' ),
155
			'thumbnail'	=> post_type_supports( $slug, 'thumbnail' )
156
		);
157
158
		return $supports;
159
160
	}
161
162
163
	/**
164
	 * Assigns taxonomies to the new post.
165
	 *
166
	 * Loop through every taxonomy type associated with a custom post type &
167
	 * assign the post to a random item out of each taxonomy. Taxonomies must
168
	 * have at least one term in them for this to work.
169
	 *
170
	 * @access private
171
	 *
172
	 * @param int $post_id a custom post type ID.
173
	 * @param array $taxonomies taxonomies assigned to this cpt.
174
	 * @return object WP Error if there is one.
175
	 */
176
	private function assign_terms( $post_id, $taxonomies ){
177
178
		// Make sure it's an array & has items
179
		if ( empty( $taxonomies ) || !is_array( $taxonomies ) ){
180
			return;
181
		}
182
183
		foreach ( $taxonomies as $tax ){
184
185
			// Get the individual terms already existing
186
			$terms = get_terms( $tax, array( 'hide_empty'	=> false ) );
187
			$count = count( $terms ) - 1;
188
189
			// If there are no terms, skip to the next taxonomy
190
			if ( empty( $terms ) ){
191
				continue;
192
			}
193
194
			// Get a random index to use
195
			$index = rand( 0, $count );
196
197
			// Initialize our array
198
			$post_data = array(
199
				'ID'	=> $post_id
200
			);
201
202
			// Set the term data to update
203
			$post_data['tax_input'][ $tax ] = array( $terms[$index]->term_id );
204
205
			// Update the post with the taxonomy info
206
			$return = wp_update_post( $post_data );
207
208
			// Return the error if it exists
209
			if ( is_wp_error( $return ) ){
210
				return $return->get_error_messages();
211
			}
212
213
		}
214
215
	}
216
217
218
	/**
219
	 * Decide which cmb library to try and loop to get our metaboxes.
220
	 *
221
	 * Due to supporting multiple CMB libraries, we need to check which library
222
	 * is used on our site and then run the appropriate function. Currently
223
	 * supported libraries are CMB2 & Custom Metaboxes and Fields.
224
	 *
225
	 * @access private
226
	 *
227
	 * @see get_cmb2_metaboxes, get_cmb1_metaboxes
228
	 *
229
	 * @param string $slug Post Type slug ID.
230
	 * @return array Fields to fill in for our post object.
231
	 */
232
	private function get_metaboxes( $slug ){
233
234
		$fields = array();
235
236
		// CMB2
237
		if ( class_exists( 'CMB2', false ) ) {
238
			$fields = $this->get_cmb2_metaboxes( $slug );
239
		}
240
241
		// Custom Metaboxes and Fields (CMB1)
242
		if ( class_exists( 'cmb_Meta_Box', false ) ) {
243
			$fields = $this->get_cmb1_metaboxes( $slug );
244
		}
245
246
		// Return our array
247
		return $fields;
248
249
	}
250
251
252
	/**
253
	 * Gets all CMB2 custom metaboxes associated with a post type.
254
	 *
255
	 * Loops through all custom metabox fields registered with CMB2 and
256
	 * looks through them for matches on the given post type ID. Returns a single
257
	 * array of all boxes associated with the post type.
258
	 *
259
	 * @access private
260
	 *
261
	 * @see cmb2_meta_boxes
262
	 *
263
	 * @param string $slug a custom post type ID.
264
	 * @return array Array of fields.
265
	 */
266
	private function get_cmb2_metaboxes( $slug ){
267
268
		$fields = array();
269
270
		// Get all metaboxes from CMB2 library
271
		$all_metaboxes = apply_filters( 'cmb2_meta_boxes', array() );
272
273
		// Loop through all possible sets of metaboxes added the old way
274
		foreach ( $all_metaboxes as $metabox_array ){
275
276
			// If the custom post type ID matches this set of fields, set & stop
277
			if ( in_array( $slug, $metabox_array['object_types'] ) ) {
278
279
				// If this is the first group of fields, simply set the value
280
				// Else, merge this group with the previous one
281
				if ( empty( $fields ) ){
282
					$fields = $metabox_array['fields'];
283
				} else {
284
					$fields = array_merge( $fields, $metabox_array['fields'] );
285
				}
286
			}
287
288
		}
289
290
		// Loop through all metaboxes added the new way
291
		foreach ( \CMB2_Boxes::get_all() as $cmb ) {
292
293
			// Establish correct cmb types
294
			if ( is_string( $cmb->meta_box['object_types'] ) ){
295
				if ( $cmb->meta_box['object_types'] == $slug ){
296
					$match = true;
297
				}
298
			} else {
299
				if ( in_array( $slug, $cmb->meta_box['object_types'] ) ){
300
					$match = true;
301
				}
302
			}
303
304
			if ( $match !== true ){
0 ignored issues
show
Bug introduced by
The variable $match 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...
305
				continue;
306
			}
307
308
			if ( empty( $fields ) ){
309
				$fields = $cmb->meta_box['fields'];
310
			} else {
311
				$fields = array_merge( $fields, $cmb->meta_box['fields'] );
312
			}
313
314
		}
315
316
		return $fields;
317
318
	}
319
320
321
	/**
322
	 * Gets all CMB1 custom metaboxes associated with a post type.
323
	 *
324
	 * Loops through all custom metabox fields registered with CMB2 and
325
	 * looks through them for matches on the given post type ID. Returns a single
326
	 * array of all boxes associated with the post type.
327
	 *
328
	 * @access private
329
	 *
330
	 * @see cmb_meta_boxes
331
	 *
332
	 * @param string $slug a custom post type ID.
333
	 * @return array Array of fields.
334
	 */
335
	private function get_cmb1_metaboxes( $slug ){
336
337
		$fields = array();
338
339
		// Get all metaboxes from CMB2 library
340
		$all_metaboxes = apply_filters( 'cmb_meta_boxes', array() );
341
342
		// Loop through all possible sets of metaboxes
343
		foreach ( $all_metaboxes as $metabox_array ){
344
345
			// If the custom post type ID matches this set of fields, set & stop
346
			if ( in_array( $slug, $metabox_array['pages'] ) ) {
347
348
				// If this is the first group of fields, simply set the value
349
				// Else, merge this group with the previous one
350
				if ( empty( $fields ) ){
351
					$fields = $metabox_array['fields'];
352
				} else {
353
					$fields = array_merge( $fields, $metabox_array['fields'] );
354
				}
355
			}
356
357
		}
358
359
		return $fields;
360
361
	}
362
363
364
	/**
365
	 * Assigns the proper testing data to a custom metabox.
366
	 *
367
	 * Swaps through the possible types of CMB2 supported fields and
368
	 * insert the appropriate data based on type & id.
369
	 * Some types are not yet supported due to low frequency of use.
370
	 *
371
	 * @access private
372
	 *
373
	 * @see TestContent, add_post_meta
374
	 *
375
	 * @param int $post_id Single post ID.
376
	 * @param array $cmb custom metabox array from CMB2.
377
	 */
378
	private function random_metabox_content( $post_id, $cmb ){
379
		$value = '';
380
381
		// First check that our post ID & cmb array aren't empty
382
		if ( empty( $cmb ) || empty( $post_id ) ){
383
			return;
384
		}
385
386
		// Fetch the appropriate type of data and return
387
		switch( $cmb['type'] ){
388
389
			case 'text':
390
			case 'text_small':
391
			case 'text_medium':
392
393
				// If phone is in the id, fetch a phone #
394
				if ( stripos( $cmb['id'], 'phone' ) ){
395
					$value = TestContent::phone();
396
397
				// If email is in the id, fetch an email address
398
				} elseif ( stripos( $cmb['id'], 'email' ) ){
399
					$value = TestContent::email();
400
401
				// If time is in the id, fetch a time string
402
				} elseif ( stripos( $cmb['id'], 'time' ) ){
403
					$value = TestContent::time();
404
405
				// Otherwise, just a random text string
406
				} else {
407
					$value = TestContent::title( rand( 10, 50 ) );
408
				}
409
410
				break;
411
412
			case 'text_url':
413
414
				$value = TestContent::link();
415
416
				break;
417
418
			case 'text_email':
419
420
				$value = TestContent::email();
421
422
				break;
423
424
			// case 'text_time': 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...
425
426
			case 'select_timezone':
427
428
				$value = TestContent::timezone();
429
430
				break;
431
432
			case 'text_date':
433
434
				$value = TestContent::date( 'm/d/Y' );
435
436
				break;
437
438
			case 'text_date_timestamp':
439
			case 'text_datetime_timestamp':
440
441
				$value = TestContent::date( 'U' );
442
443
				break;
444
445
			// 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...
446
447
			case 'text_money':
448
449
				$value = rand( 0, 100000 );
450
451
				break;
452
453
			case 'test_colorpicker':
454
455
				$value = '#' . str_pad( dechex( mt_rand( 0, 0xFFFFFF ) ), 6, '0', STR_PAD_LEFT );
456
457
				break;
458
459
			case 'textarea':
460
			case 'textarea_small':
461
			case 'textarea_code':
462
463
				$value = TestContent::plain_text();
464
465
				break;
466
467
			case 'select':
468
			case 'radio_inline':
469
			case 'radio':
470
471
				// Grab a random item out of the array and return the key
472
				$new_val = array_slice( $cmb['options'], rand( 0, count( $cmb['options'] ) ), 1 );
473
				$value = key( $new_val );
474
475
				break;
476
477
			// 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...
478
			// 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...
479
			// 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...
480
481
			case 'checkbox':
482
483
				// 50/50 odds of being turned on
484
				if ( rand( 0, 1 ) == 1 ){
485
					$value = 'on';
486
				}
487
488
				break;
489
490
			case 'multicheck':
491
492
				$new_option = array();
493
494
				// Loop through each of our options
495
				foreach ( $cmb['options'] as $key => $value ){
496
497
					// 50/50 chance of being included
498
					if ( rand( 0, 1 ) ){
499
						$new_option[] = $key;
500
					}
501
502
				}
503
504
				$value = $new_option;
505
506
				break;
507
508
			case 'wysiwyg':
509
510
				$value = TestContent::paragraphs();
511
512
				break;
513
514
			case 'file':
515
516
				$value = TestContent::image( $post_id );
517
518
				break;
519
520
			// 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...
521
522
			case 'oembed':
523
524
				$value = TestContent::oembed();
525
526
				break;
527
528
		}
529
530
		// Value must exist to attempt to insert
531
		if ( !empty( $value ) && !is_wp_error( $value ) ){
532
533
			// Files must be treated separately - they use the attachment ID
534
			// & url of media for separate cmb values
535
			if ( $cmb['type'] != 'file' ){
536
				add_post_meta( $post_id, $cmb['id'], $value, true );
537
			} else {
538
				add_post_meta( $post_id, $cmb['id'].'_id', $value, true );
539
				add_post_meta( $post_id, $cmb['id'], wp_get_attachment_url( $value ), true );
540
			}
541
542
		// If we're dealing with a WP Error object, just return the message for debugging
543
		} elseif ( is_wp_error( $value ) ){
544
			return $value->get_error_message();
545
		}
546
547
	} // end random_metabox_content
548
549
}
550