Completed
Push — development ( 37e088...a1b3f7 )
by
unknown
02:52
created

Helper   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 461
Duplicated Lines 4.99 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 7
Bugs 3 Features 2
Metric Value
dl 23
loc 461
rs 8.3999
c 7
b 3
f 2
ccs 0
cts 165
cp 0
wmc 46
lcom 1
cbo 2

27 Methods

Rating   Name   Duplication   Size   Complexity  
A get_field() 0 7 2
A get_field_clone() 0 13 3
A get_value() 0 10 2
A set_value() 0 11 2
A get_the_post_meta() 0 3 1
A get_post_meta() 0 3 1
A set_post_meta() 0 3 1
A get_theme_option() 0 3 1
A set_theme_option() 0 3 1
A get_term_meta() 0 3 1
A set_term_meta() 0 3 1
A get_user_meta() 0 3 1
A set_user_meta() 0 3 1
A get_comment_meta() 0 3 1
A set_comment_meta() 0 3 1
A get_nav_menu_item_meta() 0 3 1
A set_nav_menu_item_meta() 0 3 1
A ksort_recursive() 0 10 3
A get_relation_type_from_array() 4 16 4
A normalize_label() 12 12 1
A normalize_type() 7 7 1
A type_to_class() 0 13 2
A class_to_type() 0 12 2
A sanitize_classes() 0 7 2
A is_valid_entity_id() 0 3 2
A get_field_name_characters_pattern() 0 3 1
B get_attachment_metadata() 0 66 6

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Helper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Helper, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Carbon_Fields\Helper;
4
5
use Carbon_Fields\Datastore\Datastore;
6
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
7
8
/**
9
 * Helper functions and main initialization class.
10
 */
11
class Helper {
12
13
	/**
14
	 * Get a field from a specific container type or id
15
	 *
16
	 * @param  string  $container_type Container type to search in. Optional if $container_id is supplied
17
	 * @param  string  $container_id   Container id to search in. Optional if $container_type is supplied
18
	 * @param  string  $field_name     Field name to search for
19
	 * @return boolean
20
	 */
21
	public static function get_field( $container_type, $container_id, $field_name ) {
22
		$repository = \Carbon_Fields\Carbon_Fields::resolve( 'container_repository' );
23
		if ( $container_id ) {
24
			return $repository->get_field_in_container( $field_name, $container_id );
25
		}
26
		return $repository->get_field_in_containers( $field_name, $container_type );
27
	}
28
29
	/**
30
	 * Get a clone of a field with a value loaded
31
	 *
32
	 * @param  int    $object_id      Object id to get value for (e.g. post_id, term_id etc.)
33
	 * @param  string $container_type Container type to search in. Optional if $container_id is supplied
34
	 * @param  string $container_id   Container id to search in. Optional if $container_type is supplied
35
	 * @param  string $field_name     Field name to search for
36
	 * @return mixed
37
	 */
38
	public static function get_field_clone( $object_id, $container_type, $container_id, $field_name ) {
39
		$field = static::get_field( $container_type, $container_id, $field_name );
40
41
		if ( ! $field ) {
42
			return null;
43
		}
44
45
		$clone = clone $field;
46
		if ( $object_id !== null ) {
47
			$clone->get_datastore()->set_object_id( $object_id );
48
		}
49
		return $clone;
50
	}
51
52
	/**
53
	 * Get a value formatted for end-users
54
	 *
55
	 * @param  int    $object_id      Object id to get value for (e.g. post_id, term_id etc.)
56
	 * @param  string $container_type Container type to search in
57
	 * @param  string $container_id
58
	 * @param  string $field_name     Field name
59
	 * @return mixed
60
	 */
61
	public static function get_value( $object_id, $container_type, $container_id, $field_name ) {
62
		$field = static::get_field_clone( $object_id, $container_type, $container_id, $field_name );
63
64
		if ( ! $field ) {
65
			return '';
66
		}
67
68
		$field->load();
69
		return $field->get_formatted_value();
70
	}
71
72
	/**
73
	 * Set value for a field
74
	 *
75
	 * @param int    $object_id      Object id to get value for (e.g. post_id, term_id etc.)
76
	 * @param string $container_type Container type to search in
77
	 * @param string $container_id
78
	 * @param string $field_name     Field name
79
	 * @param array $value Field expects a `value_set`; Complex_Field expects a `value_tree` - refer to DEVELOPMENT.md
80
	 */
81
	public static function set_value( $object_id, $container_type, $container_id, $field_name, $value ) {
82
		$field = static::get_field_clone( $object_id, $container_type, $container_id, $field_name );
83
84
		if ( ! $field ) {
85
			Incorrect_Syntax_Exception::raise( 'Could not find a field which satisfies the supplied pattern: ' . $field_name );
86
			return;
87
		}
88
89
		$field->set_value( $value );
90
		$field->save();
91
	}
92
93
	/**
94
	 * Shorthand for get_post_meta().
95
	 * Uses the ID of the current post in the loop.
96
	 *
97
	 * @param  string $name         Custom field name.
98
	 * @param  string $container_id
99
	 * @return mixed  Meta value.
100
	 */
101
	public static function get_the_post_meta( $name, $container_id = '' ) {
102
		return static::get_post_meta( get_the_ID(), $name, $container_id );
103
	}
104
105
	/**
106
	 * Get post meta field for a post.
107
	 *
108
	 * @param  int    $id           Post ID.
109
	 * @param  string $name         Custom field name.
110
	 * @param  string $container_id
111
	 * @return mixed  Meta value.
112
	 */
113
	public static function get_post_meta( $id, $name, $container_id = '' ) {
114
		return static::get_value( $id, 'post_meta', $container_id, $name );
115
	}
116
117
	/**
118
	 * Set post meta field for a post.
119
	 *
120
	 * @param  int    $id           Post ID
121
	 * @param  string $name         Custom field name
122
	 * @param  array  $value
123
	 * @param  string $container_id
124
	 */
125
	public static function set_post_meta( $id, $name, $value, $container_id = '' ) {
126
		return static::set_value( $id, 'post_meta', $container_id, $name, $value );
127
	}
128
129
	/**
130
	 * Get theme option field value.
131
	 *
132
	 * @param  string $name         Custom field name
133
	 * @param  string $container_id
134
	 * @return mixed  Option        value
135
	 */
136
	public static function get_theme_option( $name, $container_id = '' ) {
137
		return static::get_value( null, 'theme_options', $container_id, $name );
138
	}
139
140
	/**
141
	 * Set theme option field value.
142
	 *
143
	 * @param  string $name         Field name
144
	 * @param  array  $value
145
	 * @param  string $container_id
146
	 */
147
	public static function set_theme_option( $name, $value, $container_id = '' ) {
148
		return static::set_value( null, 'theme_options', $container_id, $name, $value );
149
	}
150
151
	/**
152
	 * Get term meta field for a term.
153
	 *
154
	 * @param  int    $id           Term ID.
155
	 * @param  string $name         Custom field name.
156
	 * @param  string $container_id
157
	 * @return mixed  Meta value.
158
	 */
159
	public static function get_term_meta( $id, $name, $container_id = '' ) {
160
		return static::get_value( $id, 'term_meta', $container_id, $name );
161
	}
162
163
	/**
164
	 * Set term meta field for a term.
165
	 *
166
	 * @param  int    $id           Term ID
167
	 * @param  string $name         Field name
168
	 * @param  array  $value
169
	 * @param  string $container_id
170
	 */
171
	public static function set_term_meta( $id, $name, $value, $container_id = '' ) {
172
		return static::set_value( $id, 'term_meta', $container_id, $name, $value );
173
	}
174
175
	/**
176
	 * Get user meta field for a user.
177
	 *
178
	 * @param  int    $id           User ID.
179
	 * @param  string $name         Custom field name.
180
	 * @param  string $container_id
181
	 * @return mixed  Meta value.
182
	 */
183
	public static function get_user_meta( $id, $name, $container_id = '' ) {
184
		return static::get_value( $id, 'user_meta', $container_id, $name );
185
	}
186
187
	/**
188
	 * Set user meta field for a user.
189
	 *
190
	 * @param  int    $id           User ID
191
	 * @param  string $name         Field name
192
	 * @param  array  $value
193
	 * @param  string $container_id
194
	 */
195
	public static function set_user_meta( $id, $name, $value, $container_id = '' ) {
196
		return static::set_value( $id, 'user_meta', $container_id, $name, $value );
197
	}
198
199
	/**
200
	 * Get comment meta field for a comment.
201
	 *
202
	 * @param  int    $id           Comment ID.
203
	 * @param  string $name         Custom field name.
204
	 * @param  string $container_id
205
	 * @return mixed  Meta value.
206
	 */
207
	public static function get_comment_meta( $id, $name, $container_id = '' ) {
208
		return static::get_value( $id, 'comment_meta', $container_id, $name );
209
	}
210
211
	/**
212
	 * Set comment meta field for a comment.
213
	 *
214
	 * @param  int    $id           Comment ID
215
	 * @param  string $name         Field name
216
	 * @param  array  $value
217
	 * @param  string $container_id
218
	 */
219
	public static function set_comment_meta( $id, $name, $value, $container_id = '' ) {
220
		return static::set_value( $id, 'comment_meta', $container_id, $name, $value );
221
	}
222
223
	/**
224
	 * Get nav menu item meta field for a nav menu item.
225
	 *
226
	 * @param  int    $id           Nav menu item ID.
227
	 * @param  string $name         Custom field name.
228
	 * @param  string $container_id
229
	 * @return mixed  Meta value.
230
	 */
231
	public static function get_nav_menu_item_meta( $id, $name, $container_id = '' ) {
232
		return static::get_value( $id, 'nav_menu_item', $container_id, $name );
233
	}
234
235
	/**
236
	 * Set nav menu item meta field for a nav menu item.
237
	 *
238
	 * @param  int    $id           Nav menu item ID
239
	 * @param  string $name         Field name
240
	 * @param  array  $value
241
	 * @param  string $container_id
242
	 */
243
	public static function set_nav_menu_item_meta( $id, $name, $value, $container_id = '' ) {
244
		return static::set_value( $id, 'nav_menu_item', $container_id, $name, $value );
245
	}
246
247
	/**
248
	 * Recursive sorting function by array key.
249
	 *
250
	 * @param  array   &$array     The input array.
251
	 * @param  int     $sort_flags Flags for controlling sorting behavior.
252
	 * @return boolean
253
	 */
254
	public static function ksort_recursive( &$array, $sort_flags = SORT_REGULAR ) {
255
		if ( ! is_array( $array ) ) {
256
			return false;
257
		}
258
		ksort( $array, $sort_flags );
259
		foreach ( $array as $key => $value ) {
260
			self::ksort_recursive( $array[ $key ], $sort_flags );
261
		}
262
		return true;
263
	}
264
265
	/**
266
	 * Get the relation type from an array similar to how meta_query works in WP_Query
267
	 *
268
	 * @param  array         $array
269
	 * @param  array<string> $allowed_relations
270
	 * @param  string        $relation_key
271
	 * @return string
272
	 */
273
	public static function get_relation_type_from_array( $array, $allowed_relations = array( 'AND', 'OR' ), $relation_key = 'relation' ) {
274
		$allowed_relations = array_values( $allowed_relations );
275
		$allowed_relations = array_map( 'strtoupper', $allowed_relations );
276
		$relation = isset( $allowed_relations[0] ) ? $allowed_relations[0] : '';
277
278
		if ( isset( $array[ $relation_key ] ) ) {
279
			$relation = strtoupper( $array[ $relation_key ] );
280
		}
281
282 View Code Duplication
		if ( ! in_array( $relation, $allowed_relations ) ) {
283
			Incorrect_Syntax_Exception::raise( 'Invalid relation type ' . $relation . '. ' .
284
			'The rule should be one of the following: "' . implode( '", "', $allowed_relations ) . '"' );
285
		}
286
287
		return $relation;
288
	}
289
290
	/**
291
	 * Normalize a label by updating case, stripping common prefixes etc.
292
	 *
293
	 * @param  string $label
294
	 * @return string
295
	 */
296 View Code Duplication
	public static function normalize_label( $label ) {
297
		// remove the leading underscore(if it's there)
298
		$label = preg_replace( '~^_~', '', $label );
299
300
		// remove the leading "crb_"(if it's there)
301
		$label = preg_replace( '~^crb_~', '', $label );
302
303
		// split the name into words and make them capitalized
304
		$label = mb_convert_case( str_replace( '_', ' ', $label ), MB_CASE_TITLE );
305
306
		return $label;
307
	}
308
309
	/**
310
	 * Normalize a type string representing an object type
311
	 *
312
	 * @param  string $type
313
	 * @return string
314
	 */
315 View Code Duplication
	public static function normalize_type( $type ) {
316
		$normalized_type = str_replace( ' ', '_', $type );
317
		$normalized_type = preg_replace( '/[_\s]+/', '_', $normalized_type );
318
		$normalized_type = preg_replace( '/^_|_$/', '', $normalized_type );
319
		$normalized_type = strtolower( $normalized_type );
320
		return $normalized_type;
321
	}
322
323
	/**
324
	 * Convert a string representing an object type to a fully qualified class name
325
	 *
326
	 * @param  string $type
327
	 * @param  string $namespace
328
	 * @param  string $class_suffix
329
	 * @return string
330
	 */
331
	public static function type_to_class( $type, $namespace = '', $class_suffix = '' ) {
332
		$classlike_type = static::normalize_type( $type );
333
		$classlike_type = str_replace( '_', ' ', $classlike_type );
334
		$classlike_type = ucwords( $classlike_type );
335
		$classlike_type = str_replace( ' ', '_', $classlike_type );
336
337
		$class = $classlike_type . $class_suffix;
338
		if ( $namespace ) {
339
			$class = $namespace . '\\' . $class;
340
		}
341
342
		return $class;
343
	}
344
345
	/**
346
	 * Convert a string representing an object type to a fully qualified class name
347
	 *
348
	 * @param  string $class
349
	 * @param  string $class_suffix
350
	 * @return string
351
	 */
352
	public static function class_to_type( $class, $class_suffix = '' ) {
353
		$reflection = new \ReflectionClass( $class );
354
		$type = $reflection->getShortName();
355
356
		if ( $class_suffix ) {
357
			$type = preg_replace( '/(' . preg_quote( $class_suffix, '/' ) . ')$/i', '', $type );
358
		}
359
360
		$type = static::normalize_type( $type );
361
362
		return $type;
363
	}
364
365
	/**
366
	 * Get an array of sanitized html classes
367
	 *
368
	 * @param  string|array<string> $classes
369
	 * @return array<string>
370
	 */
371
	public static function sanitize_classes( $classes ) {
372
		if ( ! is_array( $classes ) ) {
373
			$classes = array_values( array_filter( explode( ' ', $classes ) ) );
374
		}
375
		$classes = array_map( 'sanitize_html_class', $classes );
376
		return $classes;
377
	}
378
379
	/**
380
	 * Check if an id or name for containers and fields is valid
381
	 *
382
	 * @param  string  $id
383
	 * @return boolean
384
	 */
385
	public static function is_valid_entity_id( $id ) {
386
		return ! empty( $id ) && preg_match( '/\A[a-z0-9_\-]+\z/', $id );
387
	}
388
389
	/**
390
	 * Return a partial regex pettern matching allowed field name characters
391
	 *
392
	 * @return string
393
	 */
394
	public static function get_field_name_characters_pattern() {
395
		return 'a-z0-9_\-';
396
	}
397
398
	/**
399
	 * Returns attachment metadata from an ID.
400
	 *
401
	 * @param  string  $id
402
	 * @param  string  $type Value Type. Can be either id or url
403
	 * @return boolean
404
	 */
405
	public static function get_attachment_metadata( $id, $type ) {
406
		$attachment_meta = array(
407
			'thumb_url'         => '',
408
			'default_thumb_url' => '',
409
			'file_ext'          => '',
410
			'file_type'         => '',
411
			'file_name'         => '',
412
			'file_url'          => '',
413
			'edit_nonce'        => '',
414
			'title'             => '',
415
			'caption'           => '',
416
			'description'       => '',
417
			'alt'               => '',
418
			'date'              => '',
419
			'filesize'          => '',
420
			'width'             => '',
421
			'height'            => '',
422
		);
423
424
		if ( empty( $id ) ) {
425
			return $attachment_meta;
426
		}
427
428
		$attachment                   = get_post( $id );
429
		$attached_file                = get_attached_file( $attachment->ID );
430
		$meta                         = wp_get_attachment_metadata( $attachment->ID );
431
		list( $src, $width, $height ) = wp_get_attachment_image_src( $attachment->ID, 'full' );
0 ignored issues
show
Unused Code introduced by
The assignment to $src is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
432
433
		$attachment_meta['edit_nonce']  = wp_create_nonce( 'update-post_' . $id );
434
		$attachment_meta['title']       = get_the_title( $id );
435
		$attachment_meta['caption']     = get_post_field( 'post_excerpt', $id );
436
		$attachment_meta['description'] = get_post_field( 'post_content', $id );
437
		$attachment_meta['alt']         = get_post_meta( $id, '_wp_attachment_image_alt', true );
438
		$attachment_meta['date']        = mysql2date( __( 'F j, Y' ), $attachment->post_date );
439
		$attachment_meta['filesize']    = size_format( filesize( $attached_file ) );
440
		$attachment_meta['width']       = $width;
441
		$attachment_meta['height']      = $height;
442
443
		$attachment_meta['file_url']  = is_numeric( $id ) ? wp_get_attachment_url( $id ) : $id;
444
		$attachment_meta['file_name'] = basename( $attachment_meta['file_url'] );
445
		$attachment_meta['filetype']  = wp_check_filetype( $attachment_meta['file_url'] );
446
447
		$attachment_meta['file_ext']  = $attachment_meta['filetype']['ext']; // png, mp3, etc..
448
		$attachment_meta['file_type'] = preg_replace( '~\/.+$~', '', $attachment_meta['filetype']['type'] ); // image, video, etc..
449
450
		if ( $attachment_meta['file_type'] === 'audio' ) {
451
			$attachment_meta['artist'] = $meta['artist'];
452
			$attachment_meta['album']  = $meta['album'];
453
			$attachment_meta['length'] = $meta['length_formatted'];
454
		}
455
456
		$attachment_meta['default_thumb_url'] = wp_mime_type_icon( $id );
457
458
		if ( $attachment_meta['file_type'] == 'image' ) {
459
			$attachment_meta['thumb_url'] = $attachment_meta['file_url'];
460
461
			if ( $type == 'id' ) {
462
				$thumb_src = wp_get_attachment_image_src( $id, 'thumbnail' );
463
				$attachment_meta['thumb_url'] = $thumb_src[0];
464
			}
465
		} else {
466
			$attachment_meta['thumb_url'] = $attachment_meta['default_thumb_url'];
467
		}
468
469
		return $attachment_meta;
470
	}
471
}
472