Completed
Push — development ( 2fadcd...18958b )
by
unknown
03:13
created

Predefined_Options_Field   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 136
Duplicated Lines 13.24 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 26.67%

Importance

Changes 0
Metric Value
dl 18
loc 136
ccs 12
cts 45
cp 0.2667
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 3

8 Methods

Rating   Name   Duplication   Size   Complexity  
A is_indexed_array() 0 3 1
A set_options() 9 9 3
A add_options() 9 9 3
B load_options() 0 21 6
A get_options() 0 3 1
A get_options_values() 0 4 1
A parse_options() 0 16 4
A get_values_from_options() 0 5 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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