Completed
Push — milestone/2.0 ( e9623f...cbfdca )
by
unknown
06:39
created

Value_Set::keepalive()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Carbon_Fields\Value_Set;
4
5
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
6
7
/**
8
 * Class representing a field's value
9
 *
10
 * (raw) value set schema:
11
 * array(
12
 *     array(
13
 *         'value'=>'',
14
 *         [property2]=>'',
15
 *         ...
16
 *     ),
17
 *     ...
18
 * )
19
 */
20
class Value_Set {
21
22
	/**
23
	 * Value type which saves a single value
24
	 */
25
	const TYPE_SINGLE_VALUE = 1;
26
27
	/**
28
	 * Value type which saves multiple values with a single property
29
	 */
30
	const TYPE_MULTIPLE_VALUES = 2;
31
32
	/**
33
	 * Value type which saves a single value with multiple proerties
34
	 */
35
	const TYPE_MULTIPLE_PROPERTIES = 3;
36
37
	/**
38
	 * Value type which saves multiple values with multiple propertys
39
	 */
40
	const TYPE_VALUE_SET = 4;
41
42
	/**
43
	 * Default value property required for every value set
44
	 */
45
	const VALUE_PROPERTY = 'value';
46
47
	/**
48
	 * Value set type
49
	 * 
50
	 * @var integer static::TYPE_* constant
51
	 */
52
	protected $type = self::TYPE_SINGLE_VALUE;
53
54
	/**
55
	 * Array of valid value set types
56
	 *
57
	 * @var array
58
	 */
59
	protected $valid_types = array( self::TYPE_SINGLE_VALUE, self::TYPE_MULTIPLE_VALUES, self::TYPE_MULTIPLE_PROPERTIES, self::TYPE_VALUE_SET );
60
61
	/**
62
	 * Registered value set properties (properties) with their default value (when the property is missing in the passed raw_value_set)
63
	 *
64
	 * @var array
65
	 */
66
	protected $properties = array( self::VALUE_PROPERTY=>'' );
0 ignored issues
show
introduced by
Expected 1 space between double arrow and "''"; 0 found
Loading history...
introduced by
Expected 1 space before "=>"; 0 found
Loading history...
introduced by
Expected 1 space after "=>"; 0 found
Loading history...
introduced by
Expected 1 space between "VALUE_PROPERTY" and double arrow; 0 found
Loading history...
67
68
	/**
69
	 * Data the value set represents
70
	 *
71
	 * @var array Nullable array
72
	 */
73
	protected $value_set = null;
74
75
	/**
76
	 * Value set constructor
77
	 *
78
	 * @param integer $type static::TYPE_* constant
79
	 * @param array $additional_properties
80
	 */
81 2
	public function __construct( $type = self::TYPE_SINGLE_VALUE, $additional_properties = array() ) {
82 2
		if ( ! in_array( $type, $this->valid_types ) ) {
83 1
			Incorrect_Syntax_Exception::raise( "Invalid type specified for Value_Set: $type" );
84
		}
85
86 1
		$this->type = $type;
87 1
		$this->properties = array_merge( $this->properties, $additional_properties );
88 1
	}
89
90
	/**
91
	 * Format a raw value set into one which guarantees that only (and all) registered properties are present
92
	 *
93
	 * @param array $raw_value_set
94
	 * @return array
95
	 */
96
	protected function get_formatted_value_set( $raw_value_set ) {
97
		$formatted_value_set = array();
98
		foreach ( $raw_value_set as $raw_value ) {
99
			$formatted_value = array();
100
			foreach ( $this->properties as $property => $default_value ) {
101
				$formatted_value[ $property ] = isset( $raw_value[ $property ] ) ? $raw_value[ $property ] : $default_value;
102
			}
103
			$formatted_value_set[] = $formatted_value;
104
		}
105
		return $formatted_value_set;
106
	}
107
108
	/**
109
	 * Return value set type
110
	 *
111
	 * @return int static::TYPE_* constant
112
	 */
113 1
	public function get_type() {
114 1
		return $this->type;
115
	}
116
117
	/**
118
	 * Return whether this value type requires a keepalive key
119
	 *
120
	 * @return boolean
121
	 */
122 2
	public function keepalive() {
123 2
		return ( $this->type !== static::TYPE_SINGLE_VALUE );
124
	}
125
126
	/**
127
	 * Return whether the data is empty
128
	 *
129
	 * @return boolean
130
	 */
131 5
	public function is_empty() {
132 5
		return empty( $this->value_set );
133
	}
134
135
	/**
136
	 * Return data formatted according to the value set $type
137
	 *
138
	 * @return mixed
139
	 */
140 4
	public function get() {
141 4
		if ( $this->value_set === null ) {
142
			return null;
143
		}
144 4
		$value = '';
145 4
		$value_property = static::VALUE_PROPERTY;
146
147 4
		switch ( $this->type ) {
148 4
			case static::TYPE_MULTIPLE_VALUES:
149 1
				$value = array_map( function( $set ) use ( $value_property ) {
150 1
					return $set[ $value_property ];
151 1
				}, $this->value_set );
152 1
				break;
153 3 View Code Duplication
			case static::TYPE_MULTIPLE_PROPERTIES:
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
154 1
				$value = array();
155 1
				if ( ! empty( $this->value_set ) ) {
156 1
					$value = $this->value_set[0];
157 1
				}
158 1
				break;
159 2
			case static::TYPE_VALUE_SET:
160 1
				$value = $this->value_set;
161 1
				break;
162
163 1
			case static::TYPE_SINGLE_VALUE:
164 1 View Code Duplication
			default:
165 1
				if ( ! empty( $this->value_set ) ) {
166 1
					$value = $this->value_set[0][ static::VALUE_PROPERTY ];
167 1
				}
168 1
				break;
169 4
		}
170
171 4
		return $value;
172
	}
173
174
	/**
175
	 * Return the full value set data regardless of type
176
	 * 
177
	 * @return array
178
	 */
179 1
	public function get_set() {
180 1
		return $this->value_set;
181
	}
182
183
	/**
184
	 * Check if an array is flat
185
	 *
186
	 * @param arrat $array
187
	 * @return boolean
188
	 */
189
	protected function is_flat_array( $array ) {
190
		$flat = true;
191
		foreach ( $array as $value ) {
192
			if ( is_array( $value ) ) {
193
				$flat = false;
194
				break;
195
			}
196
		}
197
		return $flat;
198
	}
199
200
	/**
201
	 * Convert a flat array to a raw value set
202
	 *
203
	 * @param array $value_array
204
	 * @return array
205
	 */
206
	protected function flat_array_to_raw_value_set( $value_array ) {
207
		$raw_value_set = array();
208
209
		$keyed = false;
210
		$keys = array_keys( $value_array );
211
		foreach ( $keys as $key ) {
212
			if ( is_string( $key ) ) {
213
				$keyed = true;
214
				break;
215
			}
216
		}
217
218
		if ( $keyed ) {
219
			$raw_value_set[] = $value_array;
220
		} else {
221
			foreach ( $value_array as $key => $value ) {
222
				if ( is_array( $value ) && isset( $value[ static::VALUE_PROPERTY ] ) ) {
223
					$raw_value_set[] = $value;
224
				} else {
225
					$raw_value_set[] = array(
226
						static::VALUE_PROPERTY=>$value,
0 ignored issues
show
introduced by
Expected 1 space before "=>"; 0 found
Loading history...
introduced by
Expected 1 space after "=>"; 0 found
Loading history...
227
					);
228
				}
229
			}
230
		}
231
232
		return $raw_value_set;
233
	}
234
235
	/**
236
	 * Set the value set data
237
	 * Accepts: single value, array of values, array of key-values, array of arrays of key-values
238
	 *
239
	 * @param mixed $raw_value_set
240
	 */
241 12
	public function set( $raw_value_set ) {
242 12
		if ( $raw_value_set === null ) {
243 1
			$this->value_set = null;
0 ignored issues
show
Documentation Bug introduced by
It seems like null of type null is incompatible with the declared type array of property $value_set.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
244 1
			return;
245
		}
246
247 11
		if ( ! is_array( $raw_value_set ) ) {
248 1
			$raw_value_set = array( $raw_value_set );
249 1
		}
250
251 11
		if ( $this->is_flat_array( $raw_value_set ) ) {
0 ignored issues
show
Documentation introduced by
$raw_value_set is of type array, but the function expects a object<Carbon_Fields\Value_Set\arrat>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
252 3
			$raw_value_set = $this->flat_array_to_raw_value_set( $raw_value_set );
253 3
		}
254
255 11
		$this->value_set = $this->get_formatted_value_set( $raw_value_set );
256
	}
257
}