These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | abstract class FluentDOM { |
||
4 | |||
5 | /** |
||
6 | * @var bool |
||
7 | */ |
||
8 | public static $isHHVM = FALSE; |
||
9 | |||
10 | /** |
||
11 | * @var FluentDOM\Loadable |
||
12 | */ |
||
13 | private static $_loader = NULL; |
||
14 | |||
15 | /** |
||
16 | * @var array |
||
17 | */ |
||
18 | private static $_xpathTransformers = []; |
||
19 | |||
20 | /** |
||
21 | * @var FluentDOM\Loadable |
||
22 | */ |
||
23 | private static $_defaultLoaders = []; |
||
24 | |||
25 | /** |
||
26 | * @var FluentDOM\Serializer\Factory\Group |
||
27 | */ |
||
28 | private static $_serializerFactories = NULL; |
||
29 | |||
30 | /** |
||
31 | * Load a data source into a FluentDOM\Document |
||
32 | * |
||
33 | * @param mixed $source |
||
34 | * @param string $contentType |
||
35 | * @param array $options |
||
36 | * @return \FluentDOM\Document |
||
37 | */ |
||
38 | 5 | public static function load($source, $contentType = 'text/xml', array $options = []) { |
|
39 | 5 | if (!isset(self::$_loader)) { |
|
40 | 4 | self::$_loader = self::getDefaultLoaders(); |
|
41 | 4 | } |
|
42 | 5 | $result = self::$_loader->load($source, $contentType, $options); |
|
43 | 5 | return $result instanceof \DOMDocument ? $result : $result->getDocument(); |
|
44 | } |
||
45 | |||
46 | /** |
||
47 | * Return a FluentDOM Creator instance, allow to create a DOM using nested function calls |
||
48 | * |
||
49 | * @param string $version |
||
50 | * @param string $encoding |
||
51 | * @return \FluentDOM\Nodes\Creator |
||
52 | */ |
||
53 | 2 | public static function create($version = '1.0', $encoding = 'UTF-8') { |
|
54 | 2 | return new \FluentDOM\Nodes\Creator($version, $encoding); |
|
55 | } |
||
56 | |||
57 | /** |
||
58 | * Create an FluentDOM::Query instance and load the source into it. |
||
59 | * |
||
60 | * @param mixed $source |
||
61 | * @param string $contentType |
||
62 | * @param array $options |
||
63 | * @return \FluentDOM\Query |
||
64 | */ |
||
65 | 4 | public static function Query($source = NULL, $contentType = 'text/xml', array $options = []) { |
|
66 | 4 | $query = new FluentDOM\Query(); |
|
67 | 4 | if (isset($source)) { |
|
68 | 3 | $query->load($source, $contentType, $options); |
|
69 | 3 | } |
|
70 | 4 | return $query; |
|
71 | } |
||
72 | |||
73 | /** |
||
74 | * Create an FluentDOM::Query instance with a modified selector callback. |
||
75 | * This allows to use CSS selectors instead of Xpath expression. |
||
76 | * |
||
77 | * @param mixed $source |
||
78 | * @param string $contentType |
||
79 | * @param array $options |
||
80 | * @throws \LogicException |
||
81 | * @return \FluentDOM\Query |
||
82 | * @codeCoverageIgnore |
||
83 | */ |
||
84 | public static function QueryCss($source = NULL, $contentType = 'text/xml', array $options = []) { |
||
85 | $builder = self::getXPathTransformer(); |
||
86 | $query = self::Query($source, $contentType, $options); |
||
87 | $isHtml = ($query->contentType === 'text/html'); |
||
88 | $query->onPrepareSelector = function($selector, $contextMode) use ($builder, $isHtml) { |
||
89 | return $builder->toXpath($selector, $contextMode, $isHtml); |
||
90 | }; |
||
91 | return $query; |
||
92 | } |
||
93 | |||
94 | /** |
||
95 | * Set a loader used in FluentDOM::load(), NULL will reset the loader. |
||
96 | * If no loader is provided an FluentDOM\Loader\Standard() will be created. |
||
97 | * |
||
98 | * @param FluentDOM\Loadable|NULL $loader |
||
99 | */ |
||
100 | 3 | public static function setLoader($loader) { |
|
101 | 3 | if ($loader instanceof \FluentDOM\Loadable) { |
|
102 | 1 | self::$_loader = $loader; |
|
103 | 3 | } elseif (NULL === $loader) { |
|
104 | 1 | self::$_loader = NULL; |
|
105 | 1 | } else { |
|
106 | 1 | throw new \FluentDOM\Exceptions\InvalidArgument( |
|
107 | 1 | 'loader', ['FluentDOM\Loadable'] |
|
108 | 1 | ); |
|
109 | } |
||
110 | 2 | } |
|
111 | |||
112 | /** |
||
113 | * Register an additional default loader |
||
114 | * |
||
115 | * @param \FluentDOM\Loadable|callable $loader |
||
116 | * @param [string] ...$contentTypes |
||
117 | * @return \FluentDOM\Loaders |
||
118 | */ |
||
119 | 3 | public static function registerLoader($loader, ...$contentTypes) { |
|
120 | 3 | $loaders = self::getDefaultLoaders(); |
|
121 | 3 | if (count($contentTypes) > 0) { |
|
122 | 1 | $lazyLoader = new \FluentDOM\Loader\Lazy(); |
|
123 | 1 | foreach ($contentTypes as $contentType) { |
|
124 | 1 | $lazyLoader->add($contentType, $loader); |
|
0 ignored issues
–
show
|
|||
125 | 1 | } |
|
126 | 1 | $loaders->add($lazyLoader); |
|
127 | 3 | } else if (is_callable($loader)) { |
|
128 | 1 | $loaders->add($loader()); |
|
129 | 1 | } else { |
|
130 | 1 | $loaders->add($loader); |
|
131 | } |
||
132 | 3 | self::$_loader = NULL; |
|
133 | 3 | return $loaders; |
|
134 | } |
||
135 | |||
136 | /** |
||
137 | * Standard loader + any registered loader. |
||
138 | * |
||
139 | * @return \FluentDOM\Loaders |
||
140 | * @codeCoverageIgnore |
||
141 | */ |
||
142 | public static function getDefaultLoaders() { |
||
143 | if (!(self::$_defaultLoaders instanceof FluentDOM\Loaders)) { |
||
144 | self::$_defaultLoaders = new FluentDOM\Loaders(new FluentDOM\Loader\Standard()); |
||
145 | } |
||
146 | return self::$_defaultLoaders; |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * Register a serializer factory for a specified content type(s). This can be |
||
151 | * a callable returning the create serializer. |
||
152 | * |
||
153 | * @param \FluentDOM\Serializer\Factory|callable $factory |
||
154 | * @param [string] ...$contentTypes |
||
155 | */ |
||
156 | 1 | public static function registerSerializerFactory($factory, ...$contentTypes) { |
|
157 | 1 | foreach ($contentTypes as $contentType) { |
|
158 | 1 | self::getSerializerFactories()[$contentType] = $factory; |
|
159 | 1 | } |
|
160 | 1 | } |
|
161 | |||
162 | /** |
||
163 | * Return registered serializer factories |
||
164 | * |
||
165 | * @return \FluentDOM\Serializer\Factory\Group |
||
166 | */ |
||
167 | 4 | public static function getSerializerFactories() { |
|
168 | 4 | if (!(self::$_serializerFactories instanceof FluentDOM\Serializer\Factory)) { |
|
169 | $xml = function($contentType, \DOMNode $node) { |
||
170 | 3 | return new FluentDOM\Serializer\Xml($node); |
|
171 | 1 | }; |
|
172 | $html = function($contentType, \DOMNode $node) { |
||
173 | 1 | return new FluentDOM\Serializer\Html($node); |
|
174 | 1 | }; |
|
175 | 1 | $json = function($contentType, \DOMNode $node) { |
|
176 | 1 | return new FluentDOM\Serializer\Json($node); |
|
177 | 1 | }; |
|
178 | 1 | self::$_serializerFactories = new FluentDOM\Serializer\Factory\Group( |
|
179 | [ |
||
180 | 1 | 'text/html' => $html, |
|
181 | 1 | 'html' => $html, |
|
182 | 1 | 'text/xml' => $xml, |
|
183 | 1 | 'xml' => $xml, |
|
184 | 1 | 'text/json' => $json, |
|
185 | 'json' => $json |
||
186 | 1 | ] |
|
187 | 1 | ); |
|
188 | 1 | } |
|
189 | 4 | return self::$_serializerFactories; |
|
190 | } |
||
191 | |||
192 | /** |
||
193 | * Get a xpath expression builder to convert css selectors to xpath |
||
194 | * |
||
195 | * @param string $errorMessage |
||
196 | * @return \FluentDOM\Xpath\Transformer |
||
197 | */ |
||
198 | 6 | public static function getXPathTransformer($errorMessage = 'No CSS selector support installed') { |
|
199 | 6 | foreach (FluentDOM::$_xpathTransformers as $index => $transformer) { |
|
200 | 6 | if (is_string($transformer) && class_exists($transformer)) { |
|
201 | 1 | FluentDOM::$_xpathTransformers[$index] = new $transformer(); |
|
202 | 6 | } elseif (is_callable($transformer)) { |
|
203 | 1 | FluentDOM::$_xpathTransformers[$index] = $transformer(); |
|
204 | 1 | } |
|
205 | 6 | if (FluentDOM::$_xpathTransformers[$index] instanceof \FluentDOM\Xpath\Transformer) { |
|
206 | 5 | return FluentDOM::$_xpathTransformers[$index]; |
|
207 | } else { |
||
208 | 1 | unset(FluentDOM::$_xpathTransformers[$index]); |
|
209 | } |
||
210 | 1 | } |
|
211 | 1 | throw new \LogicException($errorMessage); |
|
212 | } |
||
213 | |||
214 | /** |
||
215 | * @param string|callable|FluentDOM\Xpath\Transformer $transformer |
||
216 | */ |
||
217 | 6 | public static function registerXpathTransformer($transformer, $reset = FALSE) { |
|
218 | 6 | if ($reset) { |
|
219 | 6 | self::$_xpathTransformers = []; |
|
220 | 6 | } |
|
221 | 6 | array_unshift(self::$_xpathTransformers, $transformer); |
|
222 | 6 | } |
|
223 | } |
||
224 | FluentDOM::$isHHVM = defined('HHVM_VERSION'); |
||
225 | |||
226 | |||
227 | /** |
||
228 | * FluentDOM function, is an Alias for the \FluentDOM\FluentDOM::Query() |
||
229 | * factory class function. |
||
230 | * |
||
231 | * @param mixed $source |
||
232 | * @param string $contentType |
||
233 | * @param array $options |
||
234 | * @return \FluentDOM\Query |
||
235 | * @codeCoverageIgnore |
||
236 | */ |
||
237 | function FluentDOM($source = NULL, $contentType = 'text/xml', array $options = []) { |
||
238 | return FluentDOM::Query($source, $contentType, $options); |
||
239 | } |
||
240 |
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.