Passed
Push — master ( 00a0be...a32cdb )
by Atanas
01:46
created

ConditionFactory::parseNegatedCondition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace WPEmerge\Routing\Conditions;
4
5
use Closure;
6
use Exception;
7
use WPEmerge\Facades\Framework;
8
use WPEmerge\Routing\Conditions\CustomCondition;
9
use WPEmerge\Routing\Conditions\MultipleCondition;
10
use WPEmerge\Routing\Conditions\UrlCondition;
11
use ReflectionClass;
12
13
/**
14
 * Check against the current url
15
 */
16
class ConditionFactory {
17
	const NEGATE_CONDITION_PREFIX = '!';
18
19
	/**
20
	 * Create a new condition.
21
	 *
22
	 * @throws InvalidRouteConditionException
23
	 * @param  string|array|Closure           $options
24
	 * @return ConditionInterface
25
	 */
26 13
	public static function make( $options ) {
27 13
		if ( is_string( $options ) ) {
28 2
			return static::makeFromUrl( $options );
29
		}
30
31 11
		if ( is_array( $options ) ) {
32 9
			return static::makeFromArray( $options );
33
		}
34
35 2
		if ( $options instanceof Closure ) {
36 1
			return static::makeFromClosure( $options );
37
		}
38
39 1
		throw new InvalidRouteConditionException( 'Invalid condition options supplied.' );
40
	}
41
42
	/**
43
	 * Check if the passed argument is a registered condition type.
44
	 *
45
	 * @param  mixed   $condition_type
46
	 * @return boolean
47
	 */
48 6
	protected static function conditionTypeRegistered( $condition_type ) {
49 6
		if ( ! is_string( $condition_type ) ) {
50 1
			return false;
51
		}
52
53 5
		$condition_class = Framework::resolve( WPEMERGE_ROUTING_CONDITIONS_KEY . $condition_type );
54 5
		return ( $condition_class !== null );
55
	}
56
57
	/**
58
	 * Check if a condition is negated.
59
	 *
60
	 * @param  mixed   $condition
61
	 * @return boolean
62
	 */
63 1
	protected static function isNegatedCondition( $condition ) {
64
		return (
65 1
			is_string( $condition )
66
			&&
67 1
			substr( $condition, 0, strlen( static::NEGATE_CONDITION_PREFIX ) ) === static::NEGATE_CONDITION_PREFIX
68
		);
69
	}
70
71
	/**
72
	 * Parse a negated condition and its arguments.
73
	 *
74
	 * @param  string $type
75
	 * @param  array  $arguments
76
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string|array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
77
	 */
78 1
	protected static function parseNegatedCondition( $type, $arguments ) {
79 1
		$negated_type = substr( $type, strlen( static::NEGATE_CONDITION_PREFIX ) );
80 1
		$arguments = array_merge( [ $negated_type ], $arguments );
81 1
		$type = 'negate';
82
83 1
		return ['type' => $type, 'arguments' => $arguments];
84
	}
85
86
	/**
87
	 * Parse the condition type and its arguments from an options array.
88
	 *
89
	 * @throws Exception
90
	 * @param  array $options
91
	 * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string|array>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
92
	 */
93 7
	protected static function parseConditionOptions( $options ) {
94 7
		$type = $options[0];
95 7
		$arguments = array_values( array_slice( $options, 1 ) );
96
97 7
		if ( static::isNegatedCondition( $type ) ) {
98 1
			return static::parseNegatedCondition( $type, $arguments );
99
		}
100
101 7
		if ( ! static::conditionTypeRegistered( $type ) ) {
102 3
			if ( is_callable( $type ) ) {
103 2
				return ['type' => 'custom', 'arguments' => $options];
104
			}
105
106 1
			throw new Exception( 'Unknown condition type specified: ' . $type );
107
		}
108
109 4
		return ['type' => $type, 'arguments' => $arguments ];
110
	}
111
112
	/**
113
	 * Create a new condition from a url.
114
	 *
115
	 * @param  string             $url
116
	 * @return ConditionInterface
117
	 */
118 1
	protected static function makeFromUrl( $url ) {
119 1
		return new UrlCondition( $url );
120
	}
121
122
	/**
123
	 * Create a new condition from an array.
124
	 *
125
	 * @throws Exception
126
	 * @param  array               $options
127
	 * @return ConditionInterface
128
	 */
129 9
	protected static function makeFromArray( $options ) {
130 9
		if ( count( $options ) === 0 ) {
131 1
			throw new Exception( 'No condition type specified.' );
132
		}
133
134 8
		if ( is_array( $options[0] ) ) {
135 1
			return static::makeFromArrayOfConditions( $options );
136
		}
137
138 8
		$condition_options = static::parseConditionOptions( $options );
139 7
		$condition_class = Framework::resolve( WPEMERGE_ROUTING_CONDITIONS_KEY . $condition_options['type'] );
140
141 7
		$reflection = new ReflectionClass( $condition_class );
142 7
		$condition = $reflection->newInstanceArgs( $condition_options['arguments'] );
143 7
		return $condition;
144
	}
145
146
	/**
147
	 * Create a new condition from an array of conditions.
148
	 *
149
	 * @param  array               $options
150
	 * @return ConditionInterface
151
	 */
152 1
	protected static function makeFromArrayOfConditions( $options ) {
153 1
		return new MultipleCondition( $options );
154
	}
155
156
	/**
157
	 * Create a new condition from a closure.
158
	 *
159
	 * @param  Closure            $closure
160
	 * @return ConditionInterface
161
	 */
162 1
	protected static function makeFromClosure( Closure $closure ) {
163 1
		return new CustomCondition( $closure );
164
	}
165
}
166