Completed
Push — development ( 6b3261...c8c20d )
by
unknown
03:24
created

Predefined_Options_Field::set_options()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 6

Duplication

Lines 9
Ratio 100 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

Changes 0
Metric Value
cc 3
eloc 6
nc 2
nop 1
dl 9
loc 9
ccs 5
cts 6
cp 0.8333
crap 3.0416
rs 9.6666
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
	 * @return Field          $this
36
	 */
37 9 View Code Duplication
	public function set_options( $options ) {
38 9
		if ( ! is_callable( $options ) && ! is_array( $options ) ) {
39 4
			Incorrect_Syntax_Exception::raise( 'Only arrays and callbacks are allowed in the <code>set_options()</code> method.' );
40
			return $this;
41
		}
42
43 5
		$this->option_collections = array();
44 5
		return $this->add_options( $options );
45
	}
46
47
	/**
48
	 * Add new options to this field.
49
	 * Accepts either array of data or a callback that returns the data.
50
	 *
51
	 * @param  array|callable $options
52
	 * @return Field          $this
53
	 */
54 13 View Code Duplication
	public function add_options( $options ) {
55 13
		if ( ! is_callable( $options ) && ! is_array( $options ) ) {
56 4
			Incorrect_Syntax_Exception::raise( 'Only arrays and callbacks are allowed in the <code>add_options()</code> method.' );
57
			return $this;
58
		}
59
60 9
		$this->option_collections[] = $options;
61 9
		return $this;
62
	}
63
64
	/**
65
	 * Get a populated array of options executing any callbacks in the process
66
	 *
67
	 * @return array
68
	 */
69
	protected function load_options() {
70
		$options = array();
71
		foreach ( $this->option_collections as $collection ) {
72
			$collection_items = array();
73
			if ( is_callable( $collection ) ) {
74
				$collection_items = call_user_func( $collection );
75
				if ( ! is_array( $collection_items ) ) {
76
					continue;
77
				}
78
			} else {
79
				foreach ( $collection as $key => $value ) {
80
					if ( is_array( $value ) ) {
81
						$collection_items = $collection_items + $value;
82
					} else {
83
						$collection_items[ $key ] = $value;
84
					}
85
				}
86
			}
87
			if ( $this->is_indexed_array( $options ) && $this->is_indexed_array( $collection_items ) ) {
88
				$options = array_merge( $options, $collection_items );
89
			} else {
90
				$options = array_replace( $options, $collection_items );
91
			}
92
		}
93
94
		return $options;
95
	}
96
97
	/**
98
	 * Retrieve the current options.
99
	 *
100
	 * @return array|callable $options
101
	 */
102 13
	public function get_options() {
103 13
		return $this->load_options();
104
	}
105
106
	/**
107
	 * Changes the options array structure. This is needed to keep the array items order when it is JSON encoded.
108
	 * Will also work with a callable that returns an array.
109
	 *
110
	 * @param array|callable $options
111
	 * @return array
112
	 */
113
	protected function parse_options( $options ) {
114
		$parsed = array();
115
116
		if ( is_callable( $options ) ) {
117
			$options = call_user_func( $options );
118
		}
119
120
		foreach ( $options as $key => $value ) {
121
			$parsed[] = array(
122
				'name' => $value,
123
				'value' => $key,
124
			);
125
		}
126
127
		return $parsed;
128
	}
129
}
130