Completed
Pull Request — 2.x (#4856)
by Scott Kingsley
12:48
created

PodsConfig::load_configs()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 37
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 13
nc 5
nop 0
dl 0
loc 37
rs 8.439
c 0
b 0
f 0
1
<?php
2
/**
3
 * Class to handle registration of Pods configs and loading/saving of config files.
4
 *
5
 * @package Pods
6
 */
7
class PodsConfig {
8
9
	/**
10
	 * @var array List of registered config types.
11
	 */
12
	protected $registered_config_types = array(
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $registered_config_types exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
13
		'json' => 'json',
14
		'yml'  => 'yml',
15
	);
16
17
	/**
18
	 * @var array List of registered config item types.
19
	 */
20
	protected $registered_config_item_types = array(
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $registered_config_item_types exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
21
		'pods'      => 'pods',
22
		'templates' => 'templates',
23
		'pages'     => 'pages',
24
		'helpers'   => 'helpers',
25
	);
26
27
	/**
28
	 * @var array List of registered paths.
29
	 */
30
	protected $registered_paths = array();
31
32
	/**
33
	 * @var array List of registered Pods configs.
34
	 */
35
	protected $pods = array();
36
37
	/**
38
	 * @var array List of registered Pods Template configs.
39
	 */
40
	protected $templates = array();
41
42
	/**
43
	 * @var array List of registered Pods Page configs.
44
	 */
45
	protected $pages = array();
46
47
	/**
48
	 * @var array List of registered Pods Helper configs.
49
	 */
50
	protected $helpers = array();
51
52
	/**
53
	 * @var array Associative array list of other registered configs.
54
	 */
55
	protected $custom_configs = array();
56
57
	/**
58
	 * @var array List of config names for each file path.
59
	 */
60
	protected $file_path_configs = array();
61
62
	/**
63
	 * PodsConfig constructor.
64
	 */
65
	public function __construct() {
66
		// Nothing to see here.
67
	}
68
69
	/**
70
	 * Setup initial registered paths and load configs.
71
	 */
72
	public function setup() {
73
74
		// Register theme.
75
		$this->register_path( get_template_directory() );
76
77
		if ( get_template_directory() !== get_stylesheet_directory() ) {
78
			// Register child theme.
79
			$this->register_path( get_stylesheet_directory() );
80
		}
81
82
		$this->load_configs();
83
84
	}
85
86
	/**
87
	 * Register a config type.
88
	 *
89
	 * @param string $config_type Config type.
90
	 */
91
	public function register_config_type( string $config_type ) {
92
93
		$config_type = sanitize_title( $config_type );
94
		$config_type = str_replace( array( '/', DIRECTORY_SEPARATOR ), '-', $config_type );
95
96
		$this->registered_config_types[ $config_type ] = $config_type;
97
98
	}
99
100
	/**
101
	 * Unregister a config type.
102
	 *
103
	 * @param string $config_type Config type.
104
	 */
105
	public function unregister_config_type( string $config_type ) {
106
107
		$config_type = sanitize_title( $config_type );
108
		$config_type = str_replace( array( '/', DIRECTORY_SEPARATOR ), '-', $config_type );
109
110
		if ( isset( $this->registered_config_types[ $config_type ] ) ) {
111
			unset( $this->registered_config_types[ $config_type ] );
112
		}
113
114
	}
115
116
	/**
117
	 * Register a config item type.
118
	 *
119
	 * @param string $item_type Config item type.
120
	 */
121
	public function register_config_item_type( string $item_type ) {
122
123
		$item_type = sanitize_title( $item_type );
124
		$item_type = str_replace( array( '/', DIRECTORY_SEPARATOR ), '-', $item_type );
125
126
		$this->registered_config_item_types[ $item_type ] = $item_type;
127
128
	}
129
130
	/**
131
	 * Unregister a config item type.
132
	 *
133
	 * @param string $item_type Config item type.
134
	 */
135
	public function unregister_config_item_type( string $item_type ) {
136
137
		$item_type = sanitize_title( $item_type );
138
		$item_type = str_replace( array( '/', DIRECTORY_SEPARATOR ), '-', $item_type );
139
140
		if ( isset( $this->registered_config_item_types[ $item_type ] ) ) {
141
			unset( $this->registered_config_item_types[ $item_type ] );
142
		}
143
144
	}
145
146
	/**
147
	 * Register a config file path.
148
	 *
149
	 * @param string $path File path.
150
	 */
151
	public function register_path( string $path ) {
152
153
		$path = trailingslashit( $path );
154
155
		if ( 0 !== strpos( $path, ABSPATH ) ) {
156
			$path = ABSPATH . $path;
157
		}
158
159
		$this->registered_paths[ $path ] = $path;
160
161
	}
162
163
	/**
164
	 * Unregister a config file path.
165
	 *
166
	 * @param string $path File path.
167
	 */
168
	public function unregister_path( string $path ) {
169
170
		$path = trailingslashit( $path );
171
172
		if ( 0 !== strpos( $path, ABSPATH ) ) {
173
			$path = ABSPATH . $path;
174
		}
175
176
		if ( isset( $this->registered_paths[ $path ] ) ) {
177
			unset( $this->registered_paths[ $path ] );
178
		}
179
180
	}
181
182
	/**
183
	 * Get file configs based on registered config types and config item types.
184
	 *
185
	 * @return array File configs.
186
	 */
187
	public function get_file_configs() {
188
189
		$file_configs = array();
190
191
		// Flesh out the config types.
192
		foreach ( $this->registered_config_types as $config_type ) {
193
			$path = sprintf(
194
				'pods.%s',
195
				$config_type
196
			);
197
198
			$file_configs[] = array(
199
				'type' => $config_type,
200
				'file' => $path,
201
			);
202
203
			foreach ( $this->registered_config_item_types as $config_item_types ) {
204
				$path = sprintf(
205
					'pods%s%s.%s',
206
					DIRECTORY_SEPARATOR,
207
					$config_item_types,
208
					$config_type
209
				);
210
211
				$file_configs[] = array(
212
					'type' => $config_type,
213
					'file' => $path,
214
				);
215
			}//end foreach
216
		}//end foreach
217
218
		return $file_configs;
219
220
	}
221
222
	/**
223
	 * Load configs from registered file paths.
224
	 */
225
	public function load_configs() {
226
227
		/**
228
		 * @var $wp_filesystem WP_Filesystem_Base
229
		 */
230
		global $wp_filesystem;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
231
232
		/**
233
		 * Allow plugins/themes to hook into config loading.
234
		 *
235
		 * @param PodsConfig $pods_config Pods config object.
236
		 *
237
		 * @since 2.7.2
238
		 */
239
		do_action( 'pods_config_pre_load_configs', $this );
240
241
		$file_configs = $this->get_file_configs();
242
243
		foreach ( $this->registered_paths as $config_path ) {
244
			foreach ( $file_configs as $file_config ) {
245
				$file_path = $config_path . $file_config['file'];
246
247
				if ( ! $wp_filesystem->exists( $file_path ) || ! $wp_filesystem->is_readable( $file_path ) ) {
248
					continue;
249
				}
250
251
				$raw_config = $wp_filesystem->get_contents( $file_path );
252
253
				if ( empty( $raw_config ) ) {
254
					continue;
255
				}
256
257
				$this->load_config( $file_config['type'], $raw_config, $file_path );
258
			}//end foreach
259
		}//end foreach
260
261
	}
262
263
	/**
264
	 * Load config from registered file path.
265
	 *
266
	 * @param string $config_type Config type.
267
	 * @param string $raw_config  Raw config content.
268
	 * @param string $file_path   File path.
269
	 */
270
	public function load_config( string $config_type, string $raw_config, string $file_path ) {
271
272
		$config = null;
273
274
		if ( 'yml' === $config_type ) {
275
			require_once PODS_DIR . 'vendor/mustangostang/spyc/spyc.php';
276
277
			$config = Spyc::YAMLLoadString( $raw_config );
278
		} elseif ( 'json' === $config_type ) {
279
			$config = json_decode( $raw_config, true );
280
		} else {
281
			/**
282
			 * Parse Pods config from a custom config type.
283
			 *
284
			 * @param array  $config      Config data.
285
			 * @param string $raw_config  Raw config content.
286
			 * @param string $config_type Config type.
287
			 *
288
			 * @since 2.7.2
289
			 */
290
			$config = apply_filters( 'pods_config_parse', [], $raw_config, $config_type );
291
		}
292
293
		if ( $config && is_array( $config ) ) {
294
			$this->register_config( $config, $file_path );
295
		}
296
297
	}
298
299
	/**
300
	 * Register config for different item types.
301
	 *
302
	 * @param array  $config    Config data.
303
	 * @param string $file_path Config file path.
304
	 */
305
	public function register_config( array $config, string $file_path = '' ) {
306
307
		if ( ! isset( $this->file_path_configs[ $file_path ] ) ) {
308
			$this->file_path_configs[ $file_path ] = array();
309
		}
310
311
		foreach ( $config as $item_type => $items ) {
312
			if ( empty( $items ) || ! is_array( $items ) ) {
313
				continue;
314
			}
315
316
			if ( ! isset( $this->file_path_configs[ $file_path ][ $item_type ] ) ) {
317
				$this->file_path_configs[ $file_path ][ $item_type ] = array();
318
			}
319
320
			if ( 'pods' === $item_type ) {
321
				$this->register_config_pods( $items, $file_path );
322
			} elseif ( 'templates' === $item_type ) {
323
				$this->register_config_templates( $items, $file_path );
324
			} elseif ( 'pages' === $item_type ) {
325
				$this->register_config_pages( $items, $file_path );
326
			} elseif ( 'helpers' === $item_type ) {
327
				$this->register_config_helpers( $items, $file_path );
328
			} else {
329
				$this->register_config_custom_item_type( $item_type, $items, $file_path );
330
			}
331
		}//end foreach
332
333
	}
334
335
	/**
336
	 * Register pod configs.
337
	 *
338
	 * @param array  $items     Config items.
339
	 * @param string $file_path Config file path.
340
	 */
341
	public function register_config_pods( array $items, string $file_path = '' ) {
342
343
		foreach ( $items as $item ) {
344
			// Check if the item type and name exists.
345
			if ( empty( $item['type'] ) || empty( $item['name'] ) ) {
346
				continue;
347
			}
348
349
			if ( ! isset( $this->pods[ $item['type'] ] ) ) {
350
				$this->pods[ $item['type'] ] = array();
351
			}
352
353
			if ( isset( $item['id'] ) ) {
354
				unset( $item['id'] );
355
			}
356
357
			$this->pods[ $item['type'] ][ $item['name'] ] = $item;
358
359
			$this->file_path_configs[ $file_path ]['pods'] = $item['type'] . ':' . $item['name'];
360
		}//end foreach
361
362
	}
363
364
	/**
365
	 * Register template configs.
366
	 *
367
	 * @param array  $items     Config items.
368
	 * @param string $file_path Config file path.
369
	 */
370
	public function register_config_templates( array $items, string $file_path = '' ) {
371
372
		foreach ( $items as $item ) {
373
			// Check if the item name exists.
374
			if ( empty( $item['name'] ) ) {
375
				continue;
376
			}
377
378
			if ( isset( $item['id'] ) ) {
379
				unset( $item['id'] );
380
			}
381
382
			$this->templates[ $item['name'] ] = $item;
383
384
			$this->file_path_configs[ $file_path ]['templates'] = $item['name'];
385
		}//end foreach
386
387
	}
388
389
	/**
390
	 * Register page configs.
391
	 *
392
	 * @param array  $items     Config items.
393
	 * @param string $file_path Config file path.
394
	 */
395
	public function register_config_pages( array $items, string $file_path = '' ) {
396
397
		foreach ( $items as $item ) {
398
			// Check if the item name exists.
399
			if ( empty( $item['name'] ) ) {
400
				continue;
401
			}
402
403
			if ( isset( $item['id'] ) ) {
404
				unset( $item['id'] );
405
			}
406
407
			$this->pages[ $item['name'] ] = $item;
408
409
			$this->file_path_configs[ $file_path ]['pages'] = $item['name'];
410
		}//end foreach
411
412
	}
413
414
	/**
415
	 * Register helper configs.
416
	 *
417
	 * @param array  $items     Config items.
418
	 * @param string $file_path Config file path.
419
	 */
420
	public function register_config_helpers( array $items, string $file_path = '' ) {
421
422
		foreach ( $items as $item ) {
423
			// Check if the item name exists.
424
			if ( empty( $item['name'] ) ) {
425
				continue;
426
			}
427
428
			if ( isset( $item['id'] ) ) {
429
				unset( $item['id'] );
430
			}
431
432
			$this->helpers[ $item['name'] ] = $item;
433
434
			$this->file_path_configs[ $file_path ]['helpers'] = $item['name'];
435
		}//end foreach
436
437
	}
438
439
	/**
440
	 * Register config items for custom config item type.
441
	 *
442
	 * @param string $item_type Config Item type.
443
	 * @param array  $items     Config items.
444
	 * @param string $file_path Config file path.
445
	 */
446
	public function register_config_custom_item_type( string $item_type, array $items, string $file_path = '' ) {
447
448
		if ( ! isset( $this->custom_configs[ $item_type ] ) ) {
449
			$this->custom_configs[ $item_type ] = array();
450
		}
451
452
		foreach ( $items as $item ) {
453
			/**
454
			 * Pre-process the item to be saved for a custom item type.
455
			 *
456
			 * @param array  $item      Item to pre-process.
457
			 * @param string $item_type Item type.
458
			 * @param string $file_path File path of config.
459
			 *
460
			 * @since 2.7.2
461
			 */
462
			$item = apply_filters( 'pods_config_register_custom_item', $item, $item_type, $file_path );
463
464
			// Check if the item name exists.
465
			if ( empty( $item['name'] ) ) {
466
				continue;
467
			}
468
469
			if ( isset( $item['id'] ) ) {
470
				unset( $item['id'] );
471
			}
472
473
			$this->custom_configs[ $item_type ][ $item['name'] ] = $item;
474
475
			$this->file_path_configs[ $file_path ][ $item_type ] = $item['name'];
476
		}//end foreach
477
478
	}
479
480
}
481