This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * @author Donii Sergii <[email protected]> |
||
4 | */ |
||
5 | |||
6 | namespace sonrac\Arango; |
||
7 | |||
8 | use ArangoDBClient\CollectionHandler as ArangoDBCollectionHandler; |
||
9 | use ArangoDBClient\Connection as ArangoDBConnection; |
||
10 | use ArangoDBClient\ConnectionOptions as ArangoDBConnectionOptions; |
||
11 | use ArangoDBClient\Document; |
||
12 | use ArangoDBClient\Exception as ArangoException; |
||
13 | use ArangoDBClient\Statement; |
||
14 | use ArangoDBClient\UpdatePolicy as ArangoDBUpdatePolicy; |
||
15 | use Illuminate\Database\Connection as IlluminateConnection; |
||
16 | use sonrac\Arango\Query\Grammars\Grammar; |
||
17 | use sonrac\Arango\Query\Processors\Processor; |
||
18 | use sonrac\Arango\Query\QueryBuilder; |
||
19 | |||
20 | /** |
||
21 | * Class Connection. |
||
22 | * Arango connection. |
||
23 | * |
||
24 | * @author Donii Sergii <[email protected]> |
||
25 | */ |
||
26 | class Connection extends IlluminateConnection |
||
27 | { |
||
28 | /** |
||
29 | * Arango.DB Query Builder |
||
30 | * |
||
31 | * @var |
||
32 | * |
||
33 | * @author Donii Sergii <[email protected]> |
||
34 | */ |
||
35 | protected $db; |
||
36 | |||
37 | protected $database = '_system'; |
||
38 | |||
39 | /** |
||
40 | * Arango.DB connection |
||
41 | * |
||
42 | * @var \ArangoDBClient\Connection |
||
43 | * |
||
44 | * @author Donii Sergii <[email protected]> |
||
45 | */ |
||
46 | protected $arangoConnection; |
||
47 | |||
48 | /** |
||
49 | * Connection constructor. |
||
50 | 11 | * |
|
51 | * @param array $config Connection options |
||
52 | 11 | * |
|
53 | * @throws ArangoException |
||
54 | 11 | * |
|
55 | * @author Donii Sergii <[email protected]> |
||
56 | 11 | */ |
|
57 | 11 | public function __construct(array $config = []) |
|
58 | { |
||
59 | $this->config = $config; |
||
60 | |||
61 | $this->arangoConnection = $this->createConnection(); |
||
62 | |||
63 | $this->db = new ArangoDBCollectionHandler($this->arangoConnection); |
||
64 | |||
65 | // We need to initialize a query grammar and the query post processors |
||
66 | 1 | // which are both very important parts of the database abstractions |
|
67 | // so we initialize these to their default values while starting. |
||
68 | 1 | $this->useDefaultQueryGrammar(); |
|
69 | |||
70 | $this->useDefaultPostProcessor(); |
||
71 | } |
||
72 | |||
73 | /** |
||
74 | * Send AQL request to ArangoDB and return response with flat array |
||
75 | * |
||
76 | * @param string $query |
||
77 | * @param array $bindings |
||
78 | 1 | * @param bool $useReadPdo |
|
79 | * @return mixed |
||
80 | 1 | */ |
|
81 | public function select($query, $bindings = [], $useReadPdo = true) |
||
82 | { |
||
83 | return $this->run($query, $bindings, function ($query, $bindings) use ($useReadPdo) { |
||
84 | if ($this->pretending()) { |
||
85 | return []; |
||
86 | } |
||
87 | |||
88 | $query = $this->prepareBindingsInQuery($query); |
||
89 | $options = [ |
||
90 | 'query' => $query, |
||
91 | 'count' => true, |
||
92 | 11 | 'batchSize' => 1000, |
|
93 | 'sanitize' => true, |
||
94 | 11 | ]; |
|
95 | |||
96 | 11 | if (count($bindings) > 0) { |
|
97 | $options['bindVars'] = $this->prepareBindings($bindings); |
||
98 | 11 | var_dump($options['bindVars']); |
|
0 ignored issues
–
show
Security
Debugging Code
introduced
by
![]() |
|||
99 | } |
||
100 | |||
101 | $statement = new Statement($this->getArangoClient(), $options); |
||
102 | |||
103 | $cursor = $statement->execute(); |
||
104 | |||
105 | $resultingDocuments = []; |
||
106 | |||
107 | foreach ($cursor as $key => $document) { |
||
0 ignored issues
–
show
The expression
$cursor of type object<ArangoDBClient\Cursor>|null is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
108 | 11 | /* @var Document $document */ |
|
109 | $resultingDocuments[$key] = $document->getAll(); |
||
110 | 11 | } |
|
111 | |||
112 | 11 | return $resultingDocuments; |
|
113 | }); |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * {@inheritdoc} |
||
118 | */ |
||
119 | public function query() |
||
120 | { |
||
121 | return new QueryBuilder( |
||
122 | 11 | $this, $this->getQueryGrammar(), $this->getPostProcessor() |
|
123 | ); |
||
124 | 11 | } |
|
125 | |||
126 | /** |
||
127 | * {@inheritdoc} |
||
128 | */ |
||
129 | View Code Duplication | public function statement($query, $bindings = []) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
130 | { |
||
131 | return $this->run($query, $bindings, function ($query, $bindings) { |
||
132 | if ($this->pretending()) { |
||
133 | return true; |
||
134 | 11 | } |
|
135 | |||
136 | 11 | $query = $this->prepareBindingsInQuery($query); |
|
137 | $options = [ |
||
138 | 'query' => $query, |
||
139 | 'count' => true, |
||
140 | 'batchSize' => 1000, |
||
141 | 'sanitize' => true, |
||
142 | ]; |
||
143 | |||
144 | if (count($bindings) > 0) { |
||
145 | $options['bindVars'] = $this->prepareBindings($bindings); |
||
146 | 11 | } |
|
147 | |||
148 | 11 | $statement = new Statement($this->getArangoClient(), $options); |
|
149 | |||
150 | return $statement->execute(); |
||
151 | }); |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * {@inheritdoc} |
||
156 | */ |
||
157 | View Code Duplication | public function affectingStatement($query, $bindings = []) |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
158 | 11 | { |
|
159 | return $this->run($query, $bindings, function ($query, $bindings) { |
||
160 | 11 | $query = $this->prepareBindingsInQuery($query); |
|
161 | |||
162 | $options = [ |
||
163 | 'query' => $query, |
||
164 | 'count' => true, |
||
165 | 'batchSize' => 1000, |
||
166 | 'sanitize' => true, |
||
167 | ]; |
||
168 | |||
169 | if (count($bindings) > 0) { |
||
170 | 11 | $options['bindVars'] = $this->prepareBindings($bindings); |
|
171 | } |
||
172 | 11 | ||
173 | $statement = new Statement($this->getArangoClient(), $options); |
||
174 | |||
175 | return $statement->execute(); |
||
176 | }); |
||
177 | } |
||
178 | |||
179 | /** |
||
180 | * Get Arango.DB |
||
181 | * |
||
182 | 11 | * @return mixed |
|
183 | * |
||
184 | 11 | * @author Donii Sergii <[email protected]> |
|
185 | */ |
||
186 | public function getArangoDB() |
||
187 | { |
||
188 | return $this->db; |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * Get Arango.DB client |
||
193 | * |
||
194 | 11 | * @return \ArangoDBClient\Connection |
|
195 | * |
||
196 | 11 | * @author Donii Sergii <[email protected]> |
|
197 | */ |
||
198 | public function getArangoClient() |
||
199 | { |
||
200 | return $this->arangoConnection; |
||
201 | } |
||
202 | |||
203 | /** |
||
204 | * Create new arango.db connection. |
||
205 | * |
||
206 | 11 | * @param array $config Config |
|
207 | * |
||
208 | 11 | * @return ArangoDBConnection |
|
209 | * |
||
210 | * @throws \ArangoDBClient\Exception |
||
211 | * |
||
212 | * @author Donii Sergii <[email protected]> |
||
213 | */ |
||
214 | public function createConnection(array $config = []) |
||
215 | { |
||
216 | $config = $this->config + $config; |
||
217 | |||
218 | 11 | ArangoException::enableLogging(); |
|
219 | |||
220 | 11 | return new ArangoDBConnection($this->getMainConnectionOption() + $config); |
|
221 | } |
||
222 | |||
223 | /** |
||
224 | * Get database name. |
||
225 | * |
||
226 | * @return string |
||
227 | * |
||
228 | * @author Donii Sergii <[email protected]> |
||
229 | */ |
||
230 | public function getDatabaseName() |
||
231 | { |
||
232 | $this->database = $this->getOption(ArangoDBConnectionOptions::OPTION_DATABASE, $this->database); |
||
233 | 11 | ||
234 | return parent::getDatabaseName(); |
||
235 | 11 | } |
|
236 | 11 | ||
237 | /** |
||
238 | * Get arango.db endpoint. |
||
239 | 11 | * |
|
240 | * @return string |
||
241 | * |
||
242 | * @author Donii Sergii <[email protected]> |
||
243 | */ |
||
244 | public function getEndPoint() |
||
245 | { |
||
246 | return $this->getOption(ArangoDBConnectionOptions::OPTION_ENDPOINT, 'tcp://127.0.0.1:8529'); |
||
247 | } |
||
248 | |||
249 | 11 | /** |
|
250 | * Get auth type |
||
251 | * |
||
252 | * @return string |
||
253 | 11 | * |
|
254 | * @author Donii Sergii <[email protected]> |
||
255 | 11 | */ |
|
256 | public function getAuthType() |
||
257 | 11 | { |
|
258 | return $this->getOption(ArangoDBConnectionOptions::OPTION_AUTH_TYPE, 'Basic'); |
||
259 | 11 | } |
|
260 | |||
261 | 11 | /** |
|
262 | * Get auth type |
||
263 | 11 | * |
|
264 | * @return string |
||
265 | 11 | * |
|
266 | * @author Donii Sergii <[email protected]> |
||
267 | 11 | */ |
|
268 | public function getAuthUser() |
||
269 | 11 | { |
|
270 | return $this->getOption(ArangoDBConnectionOptions::OPTION_AUTH_USER, 'root'); |
||
271 | 11 | } |
|
272 | |||
273 | /** |
||
274 | * Get auth type |
||
275 | * |
||
276 | * @return string |
||
277 | * |
||
278 | * @author Donii Sergii <[email protected]> |
||
279 | */ |
||
280 | public function getAuthPassword() |
||
281 | { |
||
282 | return $this->getOption(ArangoDBConnectionOptions::OPTION_AUTH_PASSWD, ''); |
||
283 | } |
||
284 | |||
285 | /** |
||
286 | * Get connection option |
||
287 | * |
||
288 | * @return string |
||
289 | * |
||
290 | * @author Donii Sergii <[email protected]> |
||
291 | */ |
||
292 | public function getConnectionOption() |
||
293 | { |
||
294 | return $this->getOption(ArangoDBConnectionOptions::OPTION_CONNECTION, 'Keep-Alive'); |
||
295 | } |
||
296 | |||
297 | /** |
||
298 | * Get timeout option |
||
299 | * |
||
300 | * @return int |
||
301 | * |
||
302 | * @author Donii Sergii <[email protected]> |
||
303 | */ |
||
304 | public function getTimeout() |
||
305 | { |
||
306 | return $this->getOption(ArangoDBConnectionOptions::OPTION_TIMEOUT, 3); |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * Get reconnect option |
||
311 | * |
||
312 | * @return bool |
||
313 | * |
||
314 | * @author Donii Sergii <[email protected]> |
||
315 | */ |
||
316 | public function getReconnect() |
||
317 | { |
||
318 | return $this->getOption(ArangoDBConnectionOptions::OPTION_RECONNECT, true); |
||
319 | } |
||
320 | |||
321 | /** |
||
322 | * Get create option |
||
323 | * |
||
324 | * @return mixed |
||
325 | * |
||
326 | * @author Donii Sergii <[email protected]> |
||
327 | */ |
||
328 | public function getCreate() |
||
329 | { |
||
330 | return $this->getOption(ArangoDBConnectionOptions::OPTION_CREATE, true); |
||
331 | } |
||
332 | |||
333 | /** |
||
334 | * Get update policy option |
||
335 | * |
||
336 | * @return string |
||
337 | * |
||
338 | * @author Donii Sergii <[email protected]> |
||
339 | */ |
||
340 | public function getUpdatePolicy() |
||
341 | { |
||
342 | return $this->getOption(ArangoDBConnectionOptions::OPTION_UPDATE_POLICY, ArangoDBUpdatePolicy::LAST); |
||
343 | } |
||
344 | |||
345 | public function getDefaultQueryGrammar() |
||
346 | { |
||
347 | return new Grammar(); |
||
348 | } |
||
349 | |||
350 | public function getDefaultPostProcessor() |
||
351 | { |
||
352 | return new Processor(); |
||
353 | } |
||
354 | |||
355 | protected function prepareBindingsInQuery($query) |
||
356 | { |
||
357 | $query = explode('?', $query); |
||
358 | $result = ''; |
||
359 | foreach ($query as $index => $part) { |
||
360 | if ($index === count($query) - 1) { |
||
361 | $result .= $part; |
||
362 | continue; |
||
363 | } |
||
364 | $result .= $part.'@B'.($index + 1); |
||
365 | } |
||
366 | return $result; |
||
367 | } |
||
368 | |||
369 | /** |
||
370 | * Reconnect to the database if a PDO connection is missing. |
||
371 | * |
||
372 | * @throws \ArangoDBClient\Exception |
||
373 | * @return void |
||
374 | */ |
||
375 | protected function reconnectIfMissingConnection() |
||
376 | { |
||
377 | if (is_null($this->arangoConnection)) { |
||
378 | $this->arangoConnection = $this->createConnection(); |
||
379 | } |
||
380 | } |
||
381 | |||
382 | /** |
||
383 | * Get option value |
||
384 | * |
||
385 | * @param string $optionName |
||
386 | * @param mixed $default |
||
387 | * |
||
388 | * @return mixed |
||
389 | * |
||
390 | * @author Donii Sergii <[email protected]> |
||
391 | */ |
||
392 | private function getOption($optionName, $default) |
||
393 | { |
||
394 | if (!isset($this->config[$optionName])) { |
||
395 | $this->config[$optionName] = $default; |
||
396 | } |
||
397 | |||
398 | return $this->config[$optionName]; |
||
399 | } |
||
400 | |||
401 | /** |
||
402 | * Get main connection option |
||
403 | * |
||
404 | * @return array |
||
405 | * |
||
406 | * @author Donii Sergii <[email protected]> |
||
407 | */ |
||
408 | private function getMainConnectionOption() |
||
409 | { |
||
410 | return [ |
||
411 | // database name |
||
412 | ArangoDBConnectionOptions::OPTION_DATABASE => $this->getDatabaseName(), |
||
413 | // server endpoint to connect to |
||
414 | ArangoDBConnectionOptions::OPTION_ENDPOINT => $this->getEndPoint(), |
||
415 | // authorization type to use (currently supported: 'Basic') |
||
416 | ArangoDBConnectionOptions::OPTION_AUTH_TYPE => $this->getAuthType(), |
||
417 | // user for basic authorization |
||
418 | ArangoDBConnectionOptions::OPTION_AUTH_USER => $this->getAuthUser(), |
||
419 | // password for basic authorization |
||
420 | ArangoDBConnectionOptions::OPTION_AUTH_PASSWD => $this->getAuthPassword(), |
||
421 | // connection persistence on server. can use either 'Close' (one-time connections) or 'Keep-Alive' (re-used connections) |
||
422 | ArangoDBConnectionOptions::OPTION_CONNECTION => $this->getConnectionOption(), |
||
423 | // connect timeout in seconds |
||
424 | ArangoDBConnectionOptions::OPTION_TIMEOUT => $this->getTimeout(), |
||
425 | // whether or not to reconnect when a keep-alive connection has timed out on server |
||
426 | ArangoDBConnectionOptions::OPTION_RECONNECT => $this->getReconnect(), |
||
427 | // optionally create new collections when inserting documents |
||
428 | ArangoDBConnectionOptions::OPTION_CREATE => $this->getCreate(), |
||
429 | // optionally create new collections when inserting documents |
||
430 | ArangoDBConnectionOptions::OPTION_UPDATE_POLICY => $this->getUpdatePolicy(), |
||
431 | ]; |
||
432 | } |
||
433 | } |
||
434 |