1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Carbon_Fields\Helper; |
4
|
|
|
|
5
|
|
|
use Carbon_Fields\Datastore\Datastore; |
6
|
|
|
use Carbon_Fields\Container\Container; |
7
|
|
|
use Carbon_Fields\Templater\Templater; |
8
|
|
|
use Carbon_Fields\Manager\Sidebar_Manager; |
9
|
|
|
use Carbon_Fields\Exception\Incorrect_Syntax_Exception; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Helper functions and main initialization class. |
13
|
|
|
*/ |
14
|
|
|
class Helper { |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Create a new helper. |
18
|
|
|
* Hook the main Carbon Fields initialization functionality. |
19
|
|
|
*/ |
20
|
|
|
public function __construct() { |
21
|
|
|
add_action( 'wp_loaded', array( $this, 'trigger_fields_register' ) ); |
22
|
|
|
add_action( 'carbon_after_register_fields', array( $this, 'init_containers' ) ); |
23
|
|
|
add_action( 'admin_footer', array( $this, 'init_scripts' ), 0 ); |
24
|
|
|
add_action( 'admin_print_footer_scripts', array( $this, 'print_json_data_script' ), 9 ); |
25
|
|
|
add_action( 'crb_field_activated', array( $this, 'add_templates' ) ); |
26
|
|
|
add_action( 'crb_container_activated', array( $this, 'add_templates' ) ); |
27
|
|
|
add_action( 'after_setup_theme', array( $this, 'load_textdomain' ), 9999 ); |
28
|
|
|
|
29
|
|
|
# Initialize templater |
30
|
|
|
new Templater(); |
31
|
|
|
|
32
|
|
|
# Initialize sidebar manager |
33
|
|
|
Sidebar_Manager::instance(); |
34
|
|
|
} |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* Load the plugin textdomain. |
38
|
|
|
*/ |
39
|
|
|
public function load_textdomain() { |
40
|
|
|
$dir = dirname( dirname( __DIR__ ) ) . '/languages/'; |
41
|
|
|
$domain = 'carbon-fields'; |
42
|
|
|
$locale = get_locale(); |
43
|
|
|
$path = $dir . $domain . '-' . $locale . '.mo'; |
44
|
|
|
load_textdomain( $domain, $path ); |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Register containers and fields. |
49
|
|
|
*/ |
50
|
|
|
public function trigger_fields_register() { |
51
|
|
|
try { |
52
|
|
|
do_action( 'carbon_register_fields' ); |
53
|
|
|
do_action( 'carbon_after_register_fields' ); |
54
|
|
|
} catch ( Incorrect_Syntax_Exception $e ) { |
55
|
|
|
$callback = ''; |
56
|
|
|
foreach ( $e->getTrace() as $trace ) { |
57
|
|
|
$callback .= '<br/>' . ( isset( $trace['file'] ) ? $trace['file'] . ':' . $trace['line'] : $trace['function'] . '()' ); |
58
|
|
|
} |
59
|
|
|
wp_die( '<h3>' . $e->getMessage() . '</h3><small>' . $callback . '</small>' ); |
60
|
|
|
} |
61
|
|
|
} |
62
|
|
|
|
63
|
|
|
/** |
64
|
|
|
* Initialize containers. |
65
|
|
|
*/ |
66
|
|
|
public function init_containers() { |
67
|
|
|
Container::init_containers(); |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
/** |
71
|
|
|
* Initialize main scripts |
72
|
|
|
*/ |
73
|
|
|
public function init_scripts() { |
74
|
|
|
wp_enqueue_script( 'carbon-app', \Carbon_Fields\URL . '/assets/js/app.js', array( 'jquery', 'backbone', 'underscore', 'jquery-touch-punch', 'jquery-ui-sortable' ) ); |
75
|
|
|
wp_enqueue_script( 'carbon-ext', \Carbon_Fields\URL . '/assets/js/ext.js', array( 'carbon-app' ) ); |
76
|
|
|
|
77
|
|
|
$active_fields = Container::get_active_fields(); |
78
|
|
|
$active_field_types = array(); |
79
|
|
|
|
80
|
|
|
foreach ( $active_fields as $field ) { |
81
|
|
|
if ( in_array( $field->type, $active_field_types ) ) { |
82
|
|
|
continue; |
83
|
|
|
} |
84
|
|
|
|
85
|
|
|
$active_field_types[] = $field->type; |
86
|
|
|
|
87
|
|
|
$field->admin_enqueue_scripts(); |
88
|
|
|
} |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Print the carbon JSON data script. |
93
|
|
|
*/ |
94
|
|
|
public function print_json_data_script() { |
95
|
|
|
?> |
96
|
|
|
<script type="text/javascript"> |
97
|
|
|
<!--//--><![CDATA[//><!-- |
98
|
|
|
var carbon_json = <?php echo wp_json_encode( $this->get_json_data() ); ?>; |
99
|
|
|
//--><!]]> |
100
|
|
|
</script> |
101
|
|
|
<?php |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* Retrieve containers and sidebars for use in the JS. |
106
|
|
|
* |
107
|
|
|
* @return array $carbon_data |
108
|
|
|
*/ |
109
|
|
|
public function get_json_data() { |
110
|
|
|
global $wp_registered_sidebars; |
111
|
|
|
|
112
|
|
|
$carbon_data = array( |
113
|
|
|
'containers' => array(), |
114
|
|
|
'sidebars' => array(), |
115
|
|
|
); |
116
|
|
|
|
117
|
|
|
$containers = Container::get_active_containers(); |
118
|
|
|
|
119
|
|
|
foreach ( $containers as $container ) { |
120
|
|
|
$container_data = $container->to_json( true ); |
121
|
|
|
|
122
|
|
|
$carbon_data['containers'][] = $container_data; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
foreach ( $wp_registered_sidebars as $sidebar ) { |
126
|
|
|
// Check if we have inactive sidebars |
127
|
|
|
if ( isset( $sidebar['class'] ) && strpos( $sidebar['class'], 'inactive-sidebar' ) !== false ) { |
128
|
|
|
continue; |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
$carbon_data['sidebars'][] = array( |
132
|
|
|
'name' => $sidebar['name'], |
133
|
|
|
'id' => $sidebar['id'], |
134
|
|
|
); |
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
return $carbon_data; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/** |
141
|
|
|
* Retrieve post meta field for a post. |
142
|
|
|
* |
143
|
|
|
* @param int $id Post ID. |
144
|
|
|
* @param string $name Custom field name. |
145
|
|
|
* @param string $type Custom field type (optional). |
146
|
|
|
* @return mixed Meta value. |
147
|
|
|
*/ |
148
|
|
|
public static function get_post_meta( $id, $name, $type = null ) { |
149
|
|
|
$name = $name[0] == '_' ? $name : '_' . $name; |
150
|
|
|
|
151
|
|
|
return self::get_field_value( 'post_meta', $name, $type, $id ); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Shorthand for get_post_meta(). |
156
|
|
|
* Uses the ID of the current post in the loop. |
157
|
|
|
* |
158
|
|
|
* @param string $name Custom field name. |
159
|
|
|
* @param string $type Custom field type (optional). |
160
|
|
|
* @return mixed Meta value. |
161
|
|
|
*/ |
162
|
|
|
public static function get_the_post_meta( $name, $type = null ) { |
163
|
|
|
return self::get_post_meta( get_the_ID(), $name, $type ); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Retrieve theme option field value. |
168
|
|
|
* |
169
|
|
|
* @param string $name Custom field name. |
170
|
|
|
* @param string $type Custom field type (optional). |
171
|
|
|
* @return mixed Option value. |
172
|
|
|
*/ |
173
|
|
|
public static function get_theme_option( $name, $type = null ) { |
174
|
|
|
return self::get_field_value( 'theme_options', $name, $type ); |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Retrieve term meta field for a term. |
179
|
|
|
* |
180
|
|
|
* @param int $id Term ID. |
181
|
|
|
* @param string $name Custom field name. |
182
|
|
|
* @param string $type Custom field type (optional). |
183
|
|
|
* @return mixed Meta value. |
184
|
|
|
*/ |
185
|
|
|
public static function get_term_meta( $id, $name, $type = null ) { |
186
|
|
|
$name = $name[0] == '_' ? $name: '_' . $name; |
187
|
|
|
|
188
|
|
|
return self::get_field_value( 'term_meta', $name, $type, $id ); |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
/** |
192
|
|
|
* Retrieve user meta field for a user. |
193
|
|
|
* |
194
|
|
|
* @param int $id User ID. |
195
|
|
|
* @param string $name Custom field name. |
196
|
|
|
* @param string $type Custom field type (optional). |
197
|
|
|
* @return mixed Meta value. |
198
|
|
|
*/ |
199
|
|
|
public static function get_user_meta( $id, $name, $type = null ) { |
200
|
|
|
$name = $name[0] == '_' ? $name: '_' . $name; |
201
|
|
|
|
202
|
|
|
return self::get_field_value( 'user_meta', $name, $type, $id ); |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Retrieve comment meta field for a comment. |
207
|
|
|
* |
208
|
|
|
* @param int $id Comment ID. |
209
|
|
|
* @param string $name Custom field name. |
210
|
|
|
* @param string $type Custom field type (optional). |
211
|
|
|
* @return mixed Meta value. |
212
|
|
|
*/ |
213
|
|
|
public static function get_comment_meta( $id, $name, $type = null ) { |
214
|
|
|
$name = $name[0] == '_' ? $name: '_' . $name; |
215
|
|
|
|
216
|
|
|
return self::get_field_value( 'comment_meta', $name, $type, $id ); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Retrieve a certain field value from the database. |
221
|
|
|
* Handles the logic for different field types. |
222
|
|
|
* |
223
|
|
|
* @param string $data_type Data type. |
224
|
|
|
* @param string $name Custom field name. |
225
|
|
|
* @param string $type Custom field type (optional). |
226
|
|
|
* @param int $id ID (optional). |
227
|
|
|
* @return mixed Meta value. |
228
|
|
|
*/ |
229
|
|
|
public static function get_field_value( $data_type, $name, $type = null, $id = null ) { |
230
|
|
|
$datastore_name = str_replace( ' ', '_', ucwords( str_replace( '_', ' ', $data_type ) ) ); |
231
|
|
|
|
232
|
|
|
switch ( $type ) { |
233
|
|
|
case 'complex': |
234
|
|
|
$value = self::get_complex_fields( $datastore_name, $name, $id ); |
235
|
|
|
break; |
236
|
|
|
|
237
|
|
|
case 'map': |
238
|
|
|
case 'map_with_address': |
239
|
|
|
$value = array( |
240
|
|
|
'lat' => (float) self::get_field_value_by_store( $data_type, $name . '-lat', $id ), |
241
|
|
|
'lng' => (float) self::get_field_value_by_store( $data_type, $name . '-lng', $id ), |
242
|
|
|
'address' => self::get_field_value_by_store( $data_type, $name . '-address', $id ), |
243
|
|
|
'zoom' => (int) self::get_field_value_by_store( $data_type, $name . '-zoom', $id ), |
244
|
|
|
); |
245
|
|
|
|
246
|
|
|
if ( ! array_filter( $value ) ) { |
247
|
|
|
$value = array(); |
248
|
|
|
} |
249
|
|
|
break; |
250
|
|
|
|
251
|
|
|
case 'association': |
252
|
|
|
$raw_value = self::get_field_value_by_store( $data_type, $name, $id ); |
253
|
|
|
$value = self::parse_relationship_field( $raw_value, $type ); |
254
|
|
|
break; |
255
|
|
|
|
256
|
|
|
default: |
257
|
|
|
$value = self::get_field_value_by_store( $data_type, $name, $id ); |
258
|
|
|
|
259
|
|
|
// backward compatibility for the old Relationship field |
260
|
|
|
$value = self::maybe_old_relationship_field( $value ); |
261
|
|
|
} |
262
|
|
|
|
263
|
|
|
return $value; |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Retrieve a certain field value from the database. |
268
|
|
|
* Handles the logic for different data stores (containers). |
269
|
|
|
* |
270
|
|
|
* @param string $store_type Data store type. |
271
|
|
|
* @param string $name Custom field name. |
272
|
|
|
* @param int $id ID (optional). |
273
|
|
|
* @return mixed Meta value. |
274
|
|
|
*/ |
275
|
|
|
public static function get_field_value_by_store( $store_type, $name, $id = null ) { |
276
|
|
|
$args = array( $id, $name, true ); |
277
|
|
|
$function = ''; |
278
|
|
|
|
279
|
|
|
switch ( $store_type ) { |
280
|
|
|
case 'post_meta': |
281
|
|
|
$function = 'get_post_meta'; |
282
|
|
|
break; |
283
|
|
|
|
284
|
|
|
case 'user_meta': |
285
|
|
|
$function = 'get_user_meta'; |
286
|
|
|
break; |
287
|
|
|
|
288
|
|
|
case 'comment_meta': |
289
|
|
|
$function = 'get_comment_meta'; |
290
|
|
|
break; |
291
|
|
|
|
292
|
|
|
case 'term_meta': |
293
|
|
|
$function = 'get_metadata'; |
294
|
|
|
$args = array( 'term', $id, $name, true ); |
295
|
|
|
break; |
296
|
|
|
|
297
|
|
|
case 'theme_options': |
298
|
|
|
$function = 'get_option'; |
299
|
|
|
$args = array( $name ); |
300
|
|
|
break; |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
if ( ! empty( $function ) && function_exists( $function ) ) { |
304
|
|
|
return call_user_func_array( $function, $args ); |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
return false; |
308
|
|
|
} |
309
|
|
|
|
310
|
|
|
/** |
311
|
|
|
* Adds the field/container template(s) to the templates stack. |
312
|
|
|
* |
313
|
|
|
* @param object $object field or container object |
314
|
|
|
**/ |
315
|
|
|
public function add_templates( $object ) { |
316
|
|
|
$templates = $object->get_templates(); |
317
|
|
|
|
318
|
|
|
if ( ! $templates ) { |
319
|
|
|
return false; |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
foreach ( $templates as $name => $callback ) { |
323
|
|
|
ob_start(); |
324
|
|
|
|
325
|
|
|
call_user_func( $callback ); |
326
|
|
|
|
327
|
|
|
$html = ob_get_clean(); |
328
|
|
|
|
329
|
|
|
// Add the template to the stack |
330
|
|
|
Templater::add_template( $name, $html ); |
331
|
|
|
} |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
/** |
335
|
|
|
* Build a string of concatenated pieces for an OR regex. |
336
|
|
|
* |
337
|
|
|
* @param array $pieces Pieces |
338
|
|
|
* @param string $glue Glue between the pieces |
339
|
|
|
* @return string Result string |
340
|
|
|
*/ |
341
|
|
|
public static function preg_quote_array( $pieces, $glue = '|' ) { |
342
|
|
|
$pieces = array_map( 'preg_quote', $pieces, array( '~' ) ); |
343
|
|
|
|
344
|
|
|
return implode( $glue, $pieces ); |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* Build the regex for parsing a certain complex field. |
349
|
|
|
* |
350
|
|
|
* @param string $field_name Name of the complex field. |
351
|
|
|
* @param array $group_names Array of group names. |
352
|
|
|
* @param array $field_names Array of subfield names. |
353
|
|
|
* @return string Regex |
354
|
|
|
*/ |
355
|
|
|
public static function get_complex_field_regex( $field_name, $group_names = array(), $field_names = array() ) { |
356
|
|
|
if ( ! empty( $group_names ) ) { |
357
|
|
|
$group_regex = self::preg_quote_array( $group_names ); |
358
|
|
|
} else { |
359
|
|
|
$group_regex = '\w*'; |
360
|
|
|
} |
361
|
|
|
|
362
|
|
|
if ( ! empty( $field_names ) ) { |
363
|
|
|
$field_regex = self::preg_quote_array( $field_names ); |
364
|
|
|
} else { |
365
|
|
|
$field_regex = '.*?'; |
366
|
|
|
} |
367
|
|
|
|
368
|
|
|
return '~^' . preg_quote( $field_name, '~' ) . '(?P<group>' . $group_regex . ')-_?(?P<key>' . $field_regex . ')_(?P<index>\d+)_?(?P<sub>\w+)?(-(?P<trailing>.*))?$~'; |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
/** |
372
|
|
|
* Retrieve the complex field data for a certain field. |
373
|
|
|
* |
374
|
|
|
* @param string $type Datastore type. |
375
|
|
|
* @param string $name Name of the field. |
376
|
|
|
* @param int $id ID of the entry (optional). |
377
|
|
|
* @return array Complex data entries. |
378
|
|
|
*/ |
379
|
|
|
public static function get_complex_fields( $type, $name, $id = null ) { |
380
|
|
|
$datastore = Datastore::factory( $type ); |
381
|
|
|
|
382
|
|
|
if ( $id !== null ) { |
383
|
|
|
$datastore->set_id( $id ); |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
$group_rows = $datastore->load_values( $name ); |
387
|
|
|
$input_groups = array(); |
388
|
|
|
|
389
|
|
|
foreach ( $group_rows as $row ) { |
390
|
|
|
if ( ! preg_match( self::get_complex_field_regex( $name ), $row['field_key'], $field_name ) ) { |
391
|
|
|
continue; |
392
|
|
|
} |
393
|
|
|
|
394
|
|
|
$row['field_value'] = maybe_unserialize( $row['field_value'] ); |
395
|
|
|
|
396
|
|
|
// backward compatibility for Relationship field |
397
|
|
|
$row['field_value'] = self::parse_relationship_field( $row['field_value'] ); |
398
|
|
|
|
399
|
|
|
$input_groups[ $field_name['index'] ]['_type'] = $field_name['group']; |
400
|
|
|
if ( ! empty( $field_name['trailing'] ) ) { |
401
|
|
|
$input_groups = self::expand_nested_field( $input_groups, $row, $field_name ); |
402
|
|
View Code Duplication |
} else if ( ! empty( $field_name['sub'] ) ) { |
|
|
|
|
403
|
|
|
$input_groups[ $field_name['index'] ][ $field_name['key'] ][ $field_name['sub'] ] = $row['field_value']; |
404
|
|
|
} else { |
405
|
|
|
$input_groups[ $field_name['index'] ][ $field_name['key'] ] = $row['field_value']; |
406
|
|
|
} |
407
|
|
|
} |
408
|
|
|
|
409
|
|
|
// create groups list with loaded fields |
410
|
|
|
self::ksort_recursive( $input_groups ); |
411
|
|
|
|
412
|
|
|
return $input_groups; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
/** |
416
|
|
|
* Recursively expand the subfields of a complex field. |
417
|
|
|
* |
418
|
|
|
* @param array $input_groups Input groups. |
419
|
|
|
* @param array $row Data row (key and value). |
420
|
|
|
* @param array $field_name Field name pieces. |
421
|
|
|
* @return array Expanded data. |
422
|
|
|
*/ |
423
|
|
|
public static function expand_nested_field( $input_groups, $row, $field_name ) { |
424
|
|
|
$subfield_key_token = $field_name['key'] . '_' . $field_name['sub'] . '-' . $field_name['trailing']; |
425
|
|
|
if ( ! preg_match( self::get_complex_field_regex( $field_name['key'] ), $subfield_key_token, $subfield_name ) ) { |
426
|
|
|
return $input_groups; |
427
|
|
|
} |
428
|
|
|
|
429
|
|
|
$input_groups[ $field_name['index'] ][ $field_name['key'] ][ $subfield_name['index'] ]['_type'] = $subfield_name['group']; |
430
|
|
|
|
431
|
|
|
if ( ! empty( $subfield_name['trailing'] ) ) { |
432
|
|
|
$input_groups[ $field_name['index'] ][ $field_name['key'] ] = self::expand_nested_field( $input_groups[ $field_name['index'] ][ $field_name['key'] ], $row, $subfield_name ); |
433
|
|
View Code Duplication |
} else if ( ! empty( $subfield_name['sub'] ) ) { |
|
|
|
|
434
|
|
|
$input_groups[ $field_name['index'] ][ $field_name['key'] ][ $subfield_name['index'] ][ $subfield_name['key'] ][ $subfield_name['sub'] ] = $row['field_value']; |
435
|
|
|
} else { |
436
|
|
|
$input_groups[ $field_name['index'] ][ $field_name['key'] ][ $subfield_name['index'] ][ $subfield_name['key'] ] = $row['field_value']; |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
return $input_groups; |
440
|
|
|
} |
441
|
|
|
|
442
|
|
|
/** |
443
|
|
|
* Parse the raw value of the relationship and association fields. |
444
|
|
|
* |
445
|
|
|
* @param string $raw_value Raw relationship value. |
446
|
|
|
* @param string $type Field type. |
447
|
|
|
* @return array Array of parsed data. |
448
|
|
|
*/ |
449
|
|
|
public static function parse_relationship_field( $raw_value = '', $type = '' ) { |
450
|
|
|
if ( $raw_value && is_array( $raw_value ) ) { |
451
|
|
|
$value = array(); |
452
|
|
|
foreach ( $raw_value as $raw_value_item ) { |
453
|
|
|
if ( is_string( $raw_value_item ) && strpos( $raw_value_item, ':' ) !== false ) { |
454
|
|
|
$item_data = explode( ':', $raw_value_item ); |
455
|
|
|
$item = array( |
456
|
|
|
'id' => $item_data[2], |
457
|
|
|
'type' => $item_data[0], |
458
|
|
|
); |
459
|
|
|
|
460
|
|
|
if ( $item_data[0] === 'post' ) { |
461
|
|
|
$item['post_type'] = $item_data[1]; |
462
|
|
|
} elseif ( $item_data[0] === 'term' ) { |
463
|
|
|
$item['taxonomy'] = $item_data[1]; |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
$value[] = $item; |
467
|
|
|
} elseif ( $type === 'association' ) { |
468
|
|
|
$value[] = array( |
469
|
|
|
'id' => $raw_value_item, |
470
|
|
|
'type' => 'post', |
471
|
|
|
'post_type' => get_post_type( $raw_value_item ), |
472
|
|
|
); |
473
|
|
|
} else { |
474
|
|
|
$value[] = $raw_value_item; |
475
|
|
|
} |
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
$raw_value = $value; |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
return $raw_value; |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
/** |
485
|
|
|
* Detect if using the old way of storing the relationship field values. |
486
|
|
|
* If so, parse them to the new way of storing the data. |
487
|
|
|
* |
488
|
|
|
* @param mixed $value Old field value. |
489
|
|
|
* @return mixed New field value. |
490
|
|
|
*/ |
491
|
|
|
public static function maybe_old_relationship_field( $value ) { |
492
|
|
|
if ( is_array( $value ) && ! empty( $value ) ) { |
493
|
|
|
if ( preg_match( '~^\w+:\w+:\d+$~', $value[0] ) ) { |
494
|
|
|
$new_value = array(); |
495
|
|
|
foreach ( $value as $value_entry ) { |
496
|
|
|
$pieces = explode( ':', $value_entry ); |
497
|
|
|
$new_value[] = $pieces[2]; |
498
|
|
|
} |
499
|
|
|
$value = $new_value; |
500
|
|
|
} |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
return $value; |
504
|
|
|
} |
505
|
|
|
|
506
|
|
|
/** |
507
|
|
|
* Recursive sorting function by array key. |
508
|
|
|
* @param array &$array The input array. |
509
|
|
|
* @param int $sort_flags Flags for controlling sorting behavior. |
510
|
|
|
* @return array Sorted array. |
511
|
|
|
*/ |
512
|
|
|
public static function ksort_recursive( &$array, $sort_flags = SORT_REGULAR ) { |
513
|
|
|
if ( ! is_array( $array ) ) { |
514
|
|
|
return false; |
515
|
|
|
} |
516
|
|
|
|
517
|
|
|
ksort( $array, $sort_flags ); |
518
|
|
|
foreach ( $array as $key => $value ) { |
519
|
|
|
self::ksort_recursive( $array[ $key ], $sort_flags ); |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
return true; |
523
|
|
|
} |
524
|
|
|
} |
525
|
|
|
|
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.