These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Provide options for a loader |
||
4 | * |
||
5 | * @license http://www.opensource.org/licenses/mit-license.php The MIT License |
||
6 | * @copyright Copyright (c) 2016 Bastian Feder, Thomas Weinert |
||
7 | */ |
||
8 | |||
9 | namespace FluentDOM\Loader { |
||
10 | |||
11 | use FluentDOM\Exceptions\InvalidArgument; |
||
12 | use FluentDOM\Exceptions\InvalidSource; |
||
13 | |||
14 | /** |
||
15 | * Generalized option handling for loaders |
||
16 | */ |
||
17 | class Options implements \IteratorAggregate, \ArrayAccess { |
||
18 | |||
19 | const IS_FILE = 'is_file'; |
||
20 | const IS_STRING = 'is_string'; |
||
21 | const ALLOW_FILE = 'allow_file'; |
||
22 | |||
23 | const LIBXML_OPTIONS = 'libxml'; |
||
24 | |||
25 | const CB_IDENTIFY_STRING_SOURCE = 'identifyStringSource'; |
||
26 | |||
27 | private $_options = []; |
||
28 | protected $_callbacks = [ |
||
29 | self::CB_IDENTIFY_STRING_SOURCE => false |
||
30 | ]; |
||
31 | |||
32 | /** |
||
33 | * @param array|\Traversable|Options $options |
||
34 | * @param array $callbacks |
||
35 | */ |
||
36 | 24 | public function __construct($options = [], $callbacks = []) { |
|
37 | 24 | if (is_array($options)) { |
|
38 | 22 | $this->_options = $options; |
|
39 | 24 | } else if ($options instanceof \Traversable) { |
|
40 | 1 | $this->_options = iterator_to_array($options); |
|
41 | 1 | } else { |
|
42 | 1 | throw new InvalidArgument('options', ['array', \Traversable::class]); |
|
43 | } |
||
44 | 23 | foreach ($callbacks as $name => $callback) { |
|
45 | 7 | $this->setCallback($name, $callback); |
|
46 | 22 | } |
|
47 | 22 | } |
|
48 | |||
49 | /** |
||
50 | * @param string $name |
||
51 | * @param callable $callback |
||
52 | */ |
||
53 | 7 | public function setCallback($name, callable $callback) { |
|
54 | 7 | if (!array_key_exists($name, $this->_callbacks)) { |
|
55 | 1 | throw new \InvalidArgumentException( |
|
56 | 1 | sprintf('Unknown callback specifier "%s".', $name) |
|
57 | 1 | ); |
|
58 | } |
||
59 | 6 | $this->_callbacks[$name] = $callback; |
|
60 | 6 | } |
|
61 | |||
62 | /** |
||
63 | * @param string $name |
||
64 | * @param mixed $default |
||
65 | * @param mixed ...$arguments |
||
66 | * @return mixed |
||
67 | */ |
||
68 | 5 | private function executeCallback($name, $default, ...$arguments) { |
|
69 | 5 | $callback = $this->_callbacks[$name]; |
|
70 | 5 | if (is_callable($callback)) { |
|
71 | 4 | return $callback(...$arguments); |
|
72 | } else { |
||
73 | 1 | return $default; |
|
74 | } |
||
75 | } |
||
76 | |||
77 | /** |
||
78 | * @return \Iterator |
||
79 | */ |
||
80 | 1 | public function getIterator() { |
|
81 | 1 | return new \ArrayIterator($this->_options); |
|
82 | } |
||
83 | |||
84 | /** |
||
85 | * @param mixed $offset |
||
86 | * @return bool |
||
87 | */ |
||
88 | 2 | public function offsetExists($offset) { |
|
89 | 2 | return array_key_exists($offset, $this->_options); |
|
90 | } |
||
91 | |||
92 | /** |
||
93 | * @param mixed $offset |
||
94 | * @return mixed|null |
||
95 | */ |
||
96 | 18 | public function offsetGet($offset) { |
|
97 | 18 | return array_key_exists($offset, $this->_options) ? $this->_options[$offset] : NULL; |
|
98 | } |
||
99 | |||
100 | /** |
||
101 | * @param mixed $offset |
||
102 | * @param mixed $value |
||
103 | */ |
||
104 | 4 | public function offsetSet($offset, $value) { |
|
105 | switch ($offset) { |
||
106 | 4 | View Code Duplication | case self::IS_STRING : |
1 ignored issue
–
show
|
|||
107 | 1 | if ($value) { |
|
108 | 1 | $this->_options[self::IS_FILE] = FALSE; |
|
109 | 1 | $this->_options[self::ALLOW_FILE] = FALSE; |
|
110 | 1 | } |
|
111 | 1 | break; |
|
112 | 3 | View Code Duplication | case self::IS_FILE : |
1 ignored issue
–
show
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...
|
|||
113 | 1 | if ($value) { |
|
114 | 1 | $this->_options[self::IS_STRING] = FALSE; |
|
115 | 1 | $this->_options[self::ALLOW_FILE] = TRUE; |
|
116 | 1 | } |
|
117 | 1 | break; |
|
118 | 2 | case self::ALLOW_FILE : |
|
119 | 1 | if (!$value) { |
|
120 | 1 | $this->_options[self::IS_FILE] = FALSE; |
|
121 | 1 | } |
|
122 | 1 | break; |
|
123 | } |
||
124 | 4 | $this->_options[$offset] = $value; |
|
125 | 4 | } |
|
126 | |||
127 | /** |
||
128 | * @param mixed $offset |
||
129 | */ |
||
130 | 1 | public function offsetUnset($offset) { |
|
131 | 1 | $this->_options[$offset] = NULL; |
|
132 | 1 | } |
|
133 | |||
134 | /** |
||
135 | * @param mixed $source |
||
136 | * @return string |
||
137 | */ |
||
138 | 7 | public function getSourceType($source) { |
|
139 | 7 | if ($this[self::IS_FILE]) { |
|
140 | 1 | return self::IS_FILE; |
|
141 | 6 | } elseif ($this[self::IS_STRING]) { |
|
142 | 1 | return self::IS_STRING; |
|
143 | } |
||
144 | 5 | $isStringSource = $this->executeCallback( |
|
145 | 5 | Options::CB_IDENTIFY_STRING_SOURCE, TRUE, $source |
|
146 | 5 | ); |
|
147 | 5 | return ($isStringSource) ? self::IS_STRING : self::IS_FILE; |
|
148 | } |
||
149 | |||
150 | /** |
||
151 | * @param string $sourceType |
||
152 | * @param bool $throwException |
||
153 | * @return bool |
||
154 | * @throws \Exception |
||
155 | */ |
||
156 | 6 | public function isAllowed($sourceType, $throwException = TRUE) { |
|
157 | try { |
||
158 | switch ($sourceType) { |
||
159 | 6 | case self::IS_FILE : |
|
160 | 3 | if (!($this[self::IS_FILE] || $this[self::ALLOW_FILE])) { |
|
161 | 2 | throw new InvalidSource\TypeFile('File source not allowed.'); |
|
162 | } |
||
163 | 1 | break; |
|
164 | 3 | case self::IS_STRING : |
|
165 | 3 | if ($this[self::IS_FILE]) { |
|
166 | 2 | throw new InvalidSource\TypeString('File source expected.'); |
|
167 | } |
||
168 | 1 | break; |
|
169 | } |
||
170 | 6 | } catch (InvalidSource $e) { |
|
171 | 4 | if ($throwException) { |
|
172 | 2 | throw $e; |
|
173 | } |
||
174 | 2 | return FALSE; |
|
175 | } |
||
176 | 2 | return TRUE; |
|
177 | } |
||
178 | } |
||
179 | } |
||
180 |
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.