Completed
Push — master ( 2cda3d...b14a7d )
by
unknown
04:35 queued 02:44
created

Helper::get_field()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 3
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
ccs 0
cts 5
cp 0
crap 6
1
<?php
2
3
namespace Carbon_Fields\Helper;
4
5
use Carbon_Fields\Datastore\Datastore;
6
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
7
use WP_Query;
8
9
/**
10
 * Helper functions and main initialization class.
11
 */
12
class Helper {
13
14
	/**
15
	 * Get a field from a specific container type or id
16
	 *
17
	 * @param  string  $container_type Container type to search in. Optional if $container_id is supplied
18
	 * @param  string  $container_id   Container id to search in. Optional if $container_type is supplied
19
	 * @param  string  $field_name     Field name to search for
20
	 * @return boolean
21
	 */
22
	public static function get_field( $container_type, $container_id, $field_name ) {
23
		$repository = \Carbon_Fields\Carbon_Fields::resolve( 'container_repository' );
24
		if ( $container_id ) {
25
			return $repository->get_field_in_container( $field_name, $container_id );
26
		}
27
		return $repository->get_field_in_containers( $field_name, $container_type );
28
	}
29
30
	/**
31
	 * Get a clone of a field with a value loaded
32
	 *
33
	 * @param  int    $object_id      Object id to get value for (e.g. post_id, term_id etc.)
34
	 * @param  string $container_type Container type to search in. Optional if $container_id is supplied
35
	 * @param  string $container_id   Container id to search in. Optional if $container_type is supplied
36
	 * @param  string $field_name     Field name to search for
37
	 * @return mixed
38
	 */
39
	public static function get_field_clone( $object_id, $container_type, $container_id, $field_name ) {
40
		$field = static::get_field( $container_type, $container_id, $field_name );
41
42
		if ( ! $field ) {
43
			return null;
44
		}
45
46
		$clone = clone $field;
47
		if ( $object_id !== null ) {
48
			$clone->get_datastore()->set_object_id( $object_id );
49
		}
50
		return $clone;
51
	}
52
53
	/**
54
	 * Get a value formatted for end-users
55
	 *
56
	 * @param  int    $object_id      Object id to get value for (e.g. post_id, term_id etc.)
57
	 * @param  string $container_type Container type to search in
58
	 * @param  string $container_id
59
	 * @param  string $field_name     Field name
60
	 * @return mixed
61
	 */
62
	public static function get_value( $object_id, $container_type, $container_id, $field_name ) {
63
		$field = static::get_field_clone( $object_id, $container_type, $container_id, $field_name );
64
65
		if ( ! $field ) {
66
			return '';
67
		}
68
69
		$field->load();
70
		return $field->get_formatted_value();
71
	}
72
73
	/**
74
	 * Set value for a field
75
	 *
76
	 * @param int    $object_id      Object id to get value for (e.g. post_id, term_id etc.)
77
	 * @param string $container_type Container type to search in
78
	 * @param string $container_id
79
	 * @param string $field_name     Field name
80
	 * @param array $value Field expects a `value_set`; Complex_Field expects a `value_tree` - refer to DEVELOPMENT.md
81
	 */
82
	public static function set_value( $object_id, $container_type, $container_id, $field_name, $value ) {
83
		$field = static::get_field_clone( $object_id, $container_type, $container_id, $field_name );
84
85
		if ( ! $field ) {
86
			Incorrect_Syntax_Exception::raise( 'Could not find a field which satisfies the supplied pattern: ' . $field_name );
87
			return;
88
		}
89
90
		$field->set_value( $value );
91
		$field->save();
92
	}
93
94
	/**
95
	 * Shorthand for get_post_meta().
96
	 * Uses the ID of the current post in the loop.
97
	 *
98
	 * @param  string $name         Custom field name.
99
	 * @param  string $container_id
100
	 * @return mixed  Meta value.
101
	 */
102
	public static function get_the_post_meta( $name, $container_id = '' ) {
103
		return static::get_post_meta( get_the_ID(), $name, $container_id );
104
	}
105
106
	/**
107
	 * Get post meta field for a post.
108
	 *
109
	 * @param  int    $id           Post ID.
110
	 * @param  string $name         Custom field name.
111
	 * @param  string $container_id
112
	 * @return mixed  Meta value.
113
	 */
114
	public static function get_post_meta( $id, $name, $container_id = '' ) {
115
		return static::get_value( $id, 'post_meta', $container_id, $name );
116
	}
117
118
	/**
119
	 * Set post meta field for a post.
120
	 *
121
	 * @param  int    $id           Post ID
122
	 * @param  string $name         Custom field name
123
	 * @param  array  $value
124
	 * @param  string $container_id
125
	 */
126
	public static function set_post_meta( $id, $name, $value, $container_id = '' ) {
127
		return static::set_value( $id, 'post_meta', $container_id, $name, $value );
128
	}
129
130
	/**
131
	 * Get theme option field value.
132
	 *
133
	 * @param  string $name         Custom field name
134
	 * @param  string $container_id
135
	 * @return mixed  Option        value
136
	 */
137
	public static function get_theme_option( $name, $container_id = '' ) {
138
		return static::get_value( null, 'theme_options', $container_id, $name );
139
	}
140
141
	/**
142
	 * Set theme option field value.
143
	 *
144
	 * @param  string $name         Field name
145
	 * @param  array  $value
146
	 * @param  string $container_id
147
	 */
148
	public static function set_theme_option( $name, $value, $container_id = '' ) {
149
		return static::set_value( null, 'theme_options', $container_id, $name, $value );
150
	}
151
152
	/**
153
	 * Get term meta field for a term.
154
	 *
155
	 * @param  int    $id           Term ID.
156
	 * @param  string $name         Custom field name.
157
	 * @param  string $container_id
158
	 * @return mixed  Meta value.
159
	 */
160
	public static function get_term_meta( $id, $name, $container_id = '' ) {
161
		return static::get_value( $id, 'term_meta', $container_id, $name );
162
	}
163
164
	/**
165
	 * Set term meta field for a term.
166
	 *
167
	 * @param  int    $id           Term ID
168
	 * @param  string $name         Field name
169
	 * @param  array  $value
170
	 * @param  string $container_id
171
	 */
172
	public static function set_term_meta( $id, $name, $value, $container_id = '' ) {
173
		return static::set_value( $id, 'term_meta', $container_id, $name, $value );
174
	}
175
176
	/**
177
	 * Get user meta field for a user.
178
	 *
179
	 * @param  int    $id           User ID.
180
	 * @param  string $name         Custom field name.
181
	 * @param  string $container_id
182
	 * @return mixed  Meta value.
183
	 */
184
	public static function get_user_meta( $id, $name, $container_id = '' ) {
185
		return static::get_value( $id, 'user_meta', $container_id, $name );
186
	}
187
188
	/**
189
	 * Set user meta field for a user.
190
	 *
191
	 * @param  int    $id           User ID
192
	 * @param  string $name         Field name
193
	 * @param  array  $value
194
	 * @param  string $container_id
195
	 */
196
	public static function set_user_meta( $id, $name, $value, $container_id = '' ) {
197
		return static::set_value( $id, 'user_meta', $container_id, $name, $value );
198
	}
199
200
	/**
201
	 * Get comment meta field for a comment.
202
	 *
203
	 * @param  int    $id           Comment ID.
204
	 * @param  string $name         Custom field name.
205
	 * @param  string $container_id
206
	 * @return mixed  Meta value.
207
	 */
208
	public static function get_comment_meta( $id, $name, $container_id = '' ) {
209
		return static::get_value( $id, 'comment_meta', $container_id, $name );
210
	}
211
212
	/**
213
	 * Set comment meta field for a comment.
214
	 *
215
	 * @param  int    $id           Comment ID
216
	 * @param  string $name         Field name
217
	 * @param  array  $value
218
	 * @param  string $container_id
219
	 */
220
	public static function set_comment_meta( $id, $name, $value, $container_id = '' ) {
221
		return static::set_value( $id, 'comment_meta', $container_id, $name, $value );
222
	}
223
224
	/**
225
	 * Get nav menu item meta field for a nav menu item.
226
	 *
227
	 * @param  int    $id           Nav menu item ID.
228
	 * @param  string $name         Custom field name.
229
	 * @param  string $container_id
230
	 * @return mixed  Meta value.
231
	 */
232
	public static function get_nav_menu_item_meta( $id, $name, $container_id = '' ) {
233
		return static::get_value( $id, 'nav_menu_item', $container_id, $name );
234
	}
235
236
	/**
237
	 * Set nav menu item meta field for a nav menu item.
238
	 *
239
	 * @param  int    $id           Nav menu item ID
240
	 * @param  string $name         Field name
241
	 * @param  array  $value
242
	 * @param  string $container_id
243
	 */
244
	public static function set_nav_menu_item_meta( $id, $name, $value, $container_id = '' ) {
245
		return static::set_value( $id, 'nav_menu_item', $container_id, $name, $value );
246
	}
247
248
	/**
249
	 * Recursive sorting function by array key.
250
	 *
251
	 * @param  array   &$array     The input array.
252
	 * @param  int     $sort_flags Flags for controlling sorting behavior.
253
	 * @return boolean
254
	 */
255
	public static function ksort_recursive( &$array, $sort_flags = SORT_REGULAR ) {
256
		if ( ! is_array( $array ) ) {
257
			return false;
258
		}
259
		ksort( $array, $sort_flags );
260
		foreach ( $array as $key => $value ) {
261
			self::ksort_recursive( $array[ $key ], $sort_flags );
262
		}
263
		return true;
264
	}
265
266
	/**
267
	 * Get the relation type from an array similar to how meta_query works in WP_Query
268
	 *
269
	 * @param  array         $array
270
	 * @param  array<string> $allowed_relations
271
	 * @param  string        $relation_key
272
	 * @return string
273
	 */
274
	public static function get_relation_type_from_array( $array, $allowed_relations = array( 'AND', 'OR' ), $relation_key = 'relation' ) {
275
		$allowed_relations = array_values( $allowed_relations );
276
		$allowed_relations = array_map( 'strtoupper', $allowed_relations );
277
		$relation = isset( $allowed_relations[0] ) ? $allowed_relations[0] : '';
278
279
		if ( isset( $array[ $relation_key ] ) ) {
280
			$relation = strtoupper( $array[ $relation_key ] );
281
		}
282
283 View Code Duplication
		if ( ! in_array( $relation, $allowed_relations ) ) {
284
			Incorrect_Syntax_Exception::raise( 'Invalid relation type ' . $relation . '. ' .
285
			'The rule should be one of the following: "' . implode( '", "', $allowed_relations ) . '"' );
286
		}
287
288
		return $relation;
289
	}
290
291
	/**
292
	 * Normalize a label by updating case, stripping common prefixes etc.
293
	 *
294
	 * @param  string $label
295
	 * @return string
296
	 */
297 View Code Duplication
	public static function normalize_label( $label ) {
298
		// remove the leading underscore(if it's there)
299
		$label = preg_replace( '~^_~', '', $label );
300
301
		// remove the leading "crb_"(if it's there)
302
		$label = preg_replace( '~^crb_~', '', $label );
303
304
		// split the name into words and make them capitalized
305
		$label = mb_convert_case( str_replace( '_', ' ', $label ), MB_CASE_TITLE );
306
307
		return $label;
308
	}
309
310
	/**
311
	 * Normalize a type string representing an object type
312
	 *
313
	 * @param  string $type
314
	 * @return string
315
	 */
316 View Code Duplication
	public static function normalize_type( $type ) {
317
		$normalized_type = str_replace( ' ', '_', $type );
318
		$normalized_type = preg_replace( '/[_\s]+/', '_', $normalized_type );
319
		$normalized_type = preg_replace( '/^_|_$/', '', $normalized_type );
320
		$normalized_type = strtolower( $normalized_type );
321
		return $normalized_type;
322
	}
323
324
	/**
325
	 * Convert a string representing an object type to a fully qualified class name
326
	 *
327
	 * @param  string $type
328
	 * @param  string $namespace
329
	 * @param  string $class_suffix
330
	 * @return string
331
	 */
332
	public static function type_to_class( $type, $namespace = '', $class_suffix = '' ) {
333
		$classlike_type = static::normalize_type( $type );
334
		$classlike_type = str_replace( '_', ' ', $classlike_type );
335
		$classlike_type = ucwords( $classlike_type );
336
		$classlike_type = str_replace( ' ', '_', $classlike_type );
337
338
		$class = $classlike_type . $class_suffix;
339
		if ( $namespace ) {
340
			$class = $namespace . '\\' . $class;
341
		}
342
343
		return $class;
344
	}
345
346
	/**
347
	 * Convert a string representing an object type to a fully qualified class name
348
	 *
349
	 * @param  string $class
350
	 * @param  string $class_suffix
351
	 * @return string
352
	 */
353
	public static function class_to_type( $class, $class_suffix = '' ) {
354
		$reflection = new \ReflectionClass( $class );
355
		$type = $reflection->getShortName();
356
357
		if ( $class_suffix ) {
358
			$type = preg_replace( '/(' . preg_quote( $class_suffix, '/' ) . ')$/i', '', $type );
359
		}
360
361
		$type = static::normalize_type( $type );
362
363
		return $type;
364
	}
365
366
	/**
367
	 * Get an array of sanitized html classes
368
	 *
369
	 * @param  string|array<string> $classes
370
	 * @return array<string>
371
	 */
372
	public static function sanitize_classes( $classes ) {
373
		if ( ! is_array( $classes ) ) {
374
			$classes = array_values( array_filter( explode( ' ', $classes ) ) );
375
		}
376
		$classes = array_map( 'sanitize_html_class', $classes );
377
		return $classes;
378
	}
379
380
	/**
381
	 * Check if an id or name for containers and fields is valid
382
	 *
383
	 * @param  string  $id
384
	 * @return boolean
385
	 */
386
	public static function is_valid_entity_id( $id ) {
387
		return ! empty( $id ) && preg_match( '/\A[a-z0-9_\-]+\z/', $id );
388
	}
389
390
	/**
391
	 * Return a partial regex pettern matching allowed field name characters
392
	 *
393
	 * @return string
394
	 */
395
	public static function get_field_name_characters_pattern() {
396
		return 'a-z0-9_\-';
397
	}
398
399
	/**
400
	 * Get an attachment ID given a file URL
401
	 * Modified version of https://wpscholar.com/blog/get-attachment-id-from-wp-image-url/
402
	 *
403
	 * @param  string  $url
404
	 * @return integet
405
	 */
406
	function get_attachment_id( $url ) {
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...
407
		$dir = wp_upload_dir();
408
		$filename = basename( $url );
409
410
		if ( strpos( $url, $dir['baseurl'] . '/' ) === false ) {
411
			return 0;
412
		}
413
414
		$query_args = array(
415
			'post_type'   => 'attachment',
416
			'post_status' => 'inherit',
417
			'fields'      => 'ids',
418
			'meta_query'  => array(
1 ignored issue
show
introduced by
Detected usage of meta_query, possible slow query.
Loading history...
419
				array(
420
					'value'   => $filename,
421
					'compare' => 'LIKE',
422
					'key'     => '_wp_attachment_metadata',
423
				),
424
			)
425
		);
426
		$query = new WP_Query( $query_args );
427
428
		if ( $query->have_posts() ) {
429
			foreach ( $query->posts as $post_id ) {
430
				$meta = wp_get_attachment_metadata( $post_id );
431
				$original_file = basename( $meta['file'] );
432
				$cropped_image_files = wp_list_pluck( $meta['sizes'], 'file' );
433
434
				if ( $original_file === $filename || in_array( $filename, $cropped_image_files ) ) {
435
					return intval( $post_id );
436
				}
437
			}
438
		}
439
440
		return 0;
441
	}
442
443
	/**
444
	 * Returns attachment metadata from an ID.
445
	 *
446
	 * @param  string  $id
447
	 * @param  string  $type Value Type. Can be either id or url
448
	 * @return boolean
449
	 */
450
	public static function get_attachment_metadata( $id, $type ) {
451
		$attachment_meta = array(
452
			'thumb_url'         => '',
453
			'default_thumb_url' => '',
454
			'file_ext'          => '',
455
			'file_type'         => '',
456
			'file_name'         => '',
457
			'file_url'          => '',
458
			'edit_nonce'        => '',
459
			'title'             => '',
460
			'caption'           => '',
461
			'description'       => '',
462
			'alt'               => '',
463
			'date'              => '',
464
			'filesize'          => '',
465
			'width'             => '',
466
			'height'            => '',
467
		);
468
469
		// when value_type is set to "url" the $id will hold the url, not the id
470
		if ( $type === 'url' ) {
471
			$attachment_id = static::get_attachment_id( $id );
472
473
			if ( $attachment_id === 0 ) {
474
				$attachment_meta['thumb_url'] = $id;
475
				$attachment_meta['default_thumb_url'] = $id;
476
				$attachment_meta['file_url'] = $id;
477
				return $attachment_meta;
478
			}
479
480
			$id = $attachment_id;
481
		}
482
483
		$attachment = get_post( $id );
484
485
		if ( ! $attachment ) {
486
			return $attachment_meta;
487
		}
488
489
		$attached_file                = get_attached_file( $attachment->ID );
490
		$meta                         = wp_get_attachment_metadata( $attachment->ID );
491
		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...
492
493
		$attachment_meta['edit_nonce']  = wp_create_nonce( 'update-post_' . $id );
494
		$attachment_meta['title']       = get_the_title( $id );
495
		$attachment_meta['caption']     = get_post_field( 'post_excerpt', $id );
496
		$attachment_meta['description'] = get_post_field( 'post_content', $id );
497
		$attachment_meta['alt']         = get_post_meta( $id, '_wp_attachment_image_alt', true );
498
		$attachment_meta['date']        = mysql2date( __( 'F j, Y' ), $attachment->post_date );
499
		$attachment_meta['filesize']    = size_format( filesize( $attached_file ) );
500
		$attachment_meta['width']       = $width;
501
		$attachment_meta['height']      = $height;
502
503
		$attachment_meta['file_url']  = is_numeric( $id ) ? wp_get_attachment_url( $id ) : $id;
504
		$attachment_meta['file_name'] = basename( $attachment_meta['file_url'] );
505
		$attachment_meta['filetype']  = wp_check_filetype( $attachment_meta['file_url'] );
506
507
		$attachment_meta['file_ext']  = $attachment_meta['filetype']['ext']; // png, mp3, etc..
508
		$attachment_meta['file_type'] = preg_replace( '~\/.+$~', '', $attachment_meta['filetype']['type'] ); // image, video, etc..
509
510
		if ( $attachment_meta['file_type'] === 'audio' ) {
511
			$attachment_meta['artist'] = $meta['artist'];
512
			$attachment_meta['album']  = $meta['album'];
513
			$attachment_meta['length'] = $meta['length_formatted'];
514
		}
515
516
		$attachment_meta['default_thumb_url'] = wp_mime_type_icon( $id );
517
518
		if ( $attachment_meta['file_type'] == 'image' ) {
519
			$attachment_meta['thumb_url'] = $attachment_meta['file_url'];
520
521
			if ( $type == 'id' ) {
522
				$thumb_src = wp_get_attachment_image_src( $id, 'thumbnail' );
523
				$attachment_meta['thumb_url'] = $thumb_src[0];
524
			}
525
		} else {
526
			$attachment_meta['thumb_url'] = $attachment_meta['default_thumb_url'];
527
		}
528
529
		return $attachment_meta;
530
	}
531
}
532