Completed
Push — milestone/2.0 ( 9939d7...e0608a )
by
unknown
03:03
created

Predefined_Options_Field::set_options()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 8
Ratio 100 %

Code Coverage

Tests 5
CRAP Score 3.0416

Importance

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