Completed
Push — milestone/2_0/react-ui ( c9a76c...950db8 )
by
unknown
02:58
created

Predefined_Options_Field::load_options()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 27
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 0
Metric Value
cc 8
eloc 19
nc 6
nop 0
dl 0
loc 27
ccs 0
cts 21
cp 0
crap 72
rs 5.3846
c 0
b 0
f 0
1
<?php
2
3
namespace Carbon_Fields\Field;
4
5
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
6
7
/**
8
 * Base class for fields with predefined options.
9
 * Mainly used to reduce the bloat on the base Field class.
10
 */
11
abstract class Predefined_Options_Field extends Field {
12
	
13
	/**
14
	 * Stores the raw, unprocessed field options
15
	 *
16
	 * @var array(array|callable)
17
	 */
18
	protected $option_collections = array();
19
20
	/**
21
	 * Check if an array is indexed
22
	 * 
23
	 * @param  array   $array
24
	 * @return boolean
25
	 */
26
	protected function is_indexed_array( $array ) {
27
		return array_keys( $array ) === range( 0, count( $array ) - 1 );
28
	}
29
30
	/**
31
	 * Set the options of this field.
32
	 * Accepts either array of data or a callback that returns the data.
33
	 *
34
	 * @param array|callable $options
35
	 */
36 9 View Code Duplication
	public function set_options( $options ) {
37 9
		if ( ! is_callable( $options ) && ! is_array( $options ) ) {
38 4
			Incorrect_Syntax_Exception::raise( 'Only arrays and callbacks are allowed in the <code>set_options()</code> method.' );
39
			return $this;
40
		}
41
42 5
		$this->option_collections = array();
43 5
		return $this->add_options( $options );
44
	}
45
46
	/**
47
	 * Add new options to this field.
48
	 * Accepts either array of data or a callback that returns the data.
49
	 *
50
	 * @param array|callable $options
51
	 */
52 13 View Code Duplication
	public function add_options( $options ) {
53 13
		if ( ! is_callable( $options ) && ! is_array( $options ) ) {
54 4
			Incorrect_Syntax_Exception::raise( 'Only arrays and callbacks are allowed in the <code>add_options()</code> method.' );
55
			return $this;
56
		}
57
58 9
		$this->option_collections[] = $options;
59 9
		return $this;
60
	}
61
62
	/**
63
	 * Get a populated array of options executing any callbacks in the process
64
	 *
65
	 * @return array
66
	 */
67
	protected function load_options() {
68
		$options = array();
69
		foreach ( $this->option_collections as $collection ) {
70
			$collection_items = array();
71
			if ( is_callable( $collection ) ) {
72
				$collection_items = call_user_func( $collection );
73
				if ( ! is_array( $collection_items ) ) {
74
					continue;
75
				}
76
			} else {
77
				foreach ( $collection as $key => $value ) {
78
					if ( is_array( $value ) ) {
79
						$collection_items = $collection_items + $value;
80
					} else {
81
						$collection_items[ $key ] = $value;
82
					}
83
				}
84
			}
85
			if ( $this->is_indexed_array( $options ) && $this->is_indexed_array( $collection_items ) ) {
86
				$options = array_merge( $options, $collection_items );
87
			} else {
88
				$options = array_replace( $options, $collection_items );
89
			}
90
		}
91
92
		return $options;
93
	}
94
95
	/**
96
	 * Retrieve the current options.
97
	 *
98
	 * @return array|callable $options
99
	 */
100 13
	public function get_options() {
101 13
		return $this->load_options();
102
	}
103
104
	/**
105
	 * Changes the options array structure. This is needed to keep the array items order when it is JSON encoded.
106
	 * Will also work with a callable that returns an array.
107
	 *
108
	 * @param array|callable $options
109
	 * @return array
110
	 */
111
	protected function parse_options( $options ) {
112
		$parsed = array();
113
114
		if ( is_callable( $options ) ) {
115
			$options = call_user_func( $options );
116
		}
117
118
		foreach ( $options as $key => $value ) {
119
			$parsed[] = array(
120
				'name' => $value,
121
				'value' => $key,
122
			);
123
		}
124
125
		return $parsed;
126
	}
127
}
128