1 | <?php |
||||||
2 | |||||||
3 | declare(strict_types=1); |
||||||
4 | |||||||
5 | namespace Facile\MongoDbBundle\Capsule; |
||||||
6 | |||||||
7 | use Facile\MongoDbBundle\Event\QueryEvent; |
||||||
8 | use Facile\MongoDbBundle\Models\Query; |
||||||
9 | use MongoDB\Collection as MongoCollection; |
||||||
10 | use MongoDB\Driver\Manager; |
||||||
11 | use MongoDB\Driver\ReadPreference; |
||||||
12 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
||||||
13 | use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy; |
||||||
14 | |||||||
15 | /** |
||||||
16 | * Class Collection. |
||||||
17 | * |
||||||
18 | * @internal |
||||||
19 | */ |
||||||
20 | final class Collection extends MongoCollection |
||||||
21 | { |
||||||
22 | /** @var EventDispatcherInterface */ |
||||||
23 | private $eventDispatcher; |
||||||
24 | |||||||
25 | /** @var string */ |
||||||
26 | private $clientName; |
||||||
27 | |||||||
28 | /** @var string */ |
||||||
29 | private $databaseName; |
||||||
30 | |||||||
31 | /** |
||||||
32 | * Collection constructor. |
||||||
33 | * |
||||||
34 | * @param Manager $manager |
||||||
35 | * @param string $clientName |
||||||
36 | * @param string $databaseName |
||||||
37 | 15 | * @param string $collectionName |
|||||
38 | * @param array $options |
||||||
39 | * @param EventDispatcherInterface $eventDispatcher |
||||||
40 | * |
||||||
41 | * @internal param DataCollectorLoggerInterface $logger |
||||||
42 | */ |
||||||
43 | public function __construct( |
||||||
44 | Manager $manager, |
||||||
45 | 15 | string $clientName, |
|||||
46 | 15 | string $databaseName, |
|||||
47 | 15 | string $collectionName, |
|||||
48 | 15 | array $options = [], |
|||||
49 | 15 | EventDispatcherInterface $eventDispatcher |
|||||
50 | ) { |
||||||
51 | parent::__construct($manager, $databaseName, $collectionName, $options); |
||||||
52 | $this->eventDispatcher = $eventDispatcher; |
||||||
53 | $this->clientName = $clientName; |
||||||
54 | 1 | $this->databaseName = $databaseName; |
|||||
55 | } |
||||||
56 | 1 | ||||||
57 | 1 | /** |
|||||
58 | 1 | * {@inheritdoc} |
|||||
59 | */ |
||||||
60 | 1 | public function aggregate(array $pipeline, array $options = []) |
|||||
61 | { |
||||||
62 | $query = $this->prepareQuery(__FUNCTION__, null, $pipeline, $options); |
||||||
63 | $result = parent::aggregate($query->getData(), $query->getOptions()); |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
64 | $this->notifyQueryExecution($query); |
||||||
65 | |||||||
66 | 1 | return $result; |
|||||
67 | } |
||||||
68 | 1 | ||||||
69 | 1 | /** |
|||||
70 | 1 | * {@inheritdoc} |
|||||
71 | */ |
||||||
72 | 1 | public function count($filter = [], array $options = []) |
|||||
73 | { |
||||||
74 | $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options); |
||||||
75 | $result = parent::count($query->getFilters(), $query->getOptions()); |
||||||
0 ignored issues
–
show
The function
MongoDB\Collection::count() has been deprecated: 1.4
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This function has been deprecated. The supplier of the function has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead. ![]() |
|||||||
76 | $this->notifyQueryExecution($query); |
||||||
77 | |||||||
78 | 1 | return $result; |
|||||
79 | } |
||||||
80 | 1 | ||||||
81 | 1 | /** |
|||||
82 | 1 | * {@inheritdoc} |
|||||
83 | */ |
||||||
84 | 1 | public function find($filter = [], array $options = []) |
|||||
85 | { |
||||||
86 | $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options); |
||||||
87 | $result = parent::find($query->getFilters(), $query->getOptions()); |
||||||
88 | $this->notifyQueryExecution($query); |
||||||
89 | |||||||
90 | 1 | return $result; |
|||||
91 | } |
||||||
92 | 1 | ||||||
93 | 1 | /** |
|||||
94 | 1 | * {@inheritdoc} |
|||||
95 | */ |
||||||
96 | 1 | public function findOne($filter = [], array $options = []) |
|||||
97 | { |
||||||
98 | $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options); |
||||||
99 | $result = parent::findOne($query->getFilters(), $query->getOptions()); |
||||||
100 | $this->notifyQueryExecution($query); |
||||||
101 | |||||||
102 | 1 | return $result; |
|||||
103 | } |
||||||
104 | 1 | ||||||
105 | 1 | /** |
|||||
106 | 1 | * {@inheritdoc} |
|||||
107 | */ |
||||||
108 | 1 | public function findOneAndUpdate($filter, $update, array $options = []) |
|||||
109 | { |
||||||
110 | $query = $this->prepareQuery(__FUNCTION__, $filter, $update, $options); |
||||||
111 | $result = parent::findOneAndUpdate($query->getFilters(), $query->getData(), $query->getOptions()); |
||||||
112 | $this->notifyQueryExecution($query); |
||||||
113 | |||||||
114 | 1 | return $result; |
|||||
115 | } |
||||||
116 | 1 | ||||||
117 | 1 | /** |
|||||
118 | 1 | * {@inheritdoc} |
|||||
119 | */ |
||||||
120 | 1 | public function findOneAndDelete($filter, array $options = []) |
|||||
121 | { |
||||||
122 | $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options); |
||||||
123 | $result = parent::findOneAndDelete($query->getFilters(), $query->getOptions()); |
||||||
124 | $this->notifyQueryExecution($query); |
||||||
125 | |||||||
126 | 2 | return $result; |
|||||
127 | } |
||||||
128 | 2 | ||||||
129 | 2 | /** |
|||||
130 | 2 | * {@inheritdoc} |
|||||
131 | */ |
||||||
132 | 2 | public function deleteMany($filter, array $options = []) |
|||||
133 | { |
||||||
134 | $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options); |
||||||
135 | $result = parent::deleteMany($query->getFilters(), $query->getOptions()); |
||||||
136 | $this->notifyQueryExecution($query); |
||||||
137 | |||||||
138 | 1 | return $result; |
|||||
139 | } |
||||||
140 | 1 | ||||||
141 | 1 | /** |
|||||
142 | 1 | * {@inheritdoc} |
|||||
143 | */ |
||||||
144 | 1 | public function deleteOne($filter, array $options = []) |
|||||
145 | { |
||||||
146 | $query = $this->prepareQuery(__FUNCTION__, $filter, null, $options); |
||||||
147 | $result = parent::deleteOne($query->getFilters(), $query->getOptions()); |
||||||
148 | $this->notifyQueryExecution($query); |
||||||
149 | |||||||
150 | 1 | return $result; |
|||||
151 | } |
||||||
152 | 1 | ||||||
153 | 1 | /** |
|||||
154 | 1 | * {@inheritdoc} |
|||||
155 | */ |
||||||
156 | 1 | public function replaceOne($filter, $replacement, array $options = []) |
|||||
157 | { |
||||||
158 | $query = $this->prepareQuery(__FUNCTION__, $filter, $replacement, $options); |
||||||
159 | $result = parent::replaceOne($query->getFilters(), $query->getData(), $query->getOptions()); |
||||||
160 | $this->notifyQueryExecution($query); |
||||||
161 | |||||||
162 | 2 | return $result; |
|||||
163 | } |
||||||
164 | 2 | ||||||
165 | 2 | /** |
|||||
166 | 2 | * {@inheritdoc} |
|||||
167 | */ |
||||||
168 | 2 | public function insertOne($document, array $options = []) |
|||||
169 | { |
||||||
170 | $query = $this->prepareQuery(__FUNCTION__, [], $document, $options); |
||||||
171 | $result = parent::insertOne($query->getData(), $query->getOptions()); |
||||||
172 | $this->notifyQueryExecution($query); |
||||||
173 | |||||||
174 | 1 | return $result; |
|||||
175 | } |
||||||
176 | 1 | ||||||
177 | 1 | /** |
|||||
178 | 1 | * {@inheritdoc} |
|||||
179 | */ |
||||||
180 | 1 | public function updateOne($filter, $update, array $options = []) |
|||||
181 | { |
||||||
182 | $query = $this->prepareQuery(__FUNCTION__, $filter, $update, $options); |
||||||
183 | $result = parent::updateOne($query->getFilters(), $query->getData(), $query->getOptions()); |
||||||
184 | $this->notifyQueryExecution($query); |
||||||
185 | |||||||
186 | 1 | return $result; |
|||||
187 | } |
||||||
188 | 1 | ||||||
189 | 1 | /** |
|||||
190 | 1 | * {@inheritdoc} |
|||||
191 | */ |
||||||
192 | 1 | public function distinct($fieldName, $filter = [], array $options = []) |
|||||
193 | { |
||||||
194 | $query = $this->prepareQuery(__FUNCTION__, $filter, ['fieldName' => $fieldName], $options); |
||||||
195 | $result = parent::distinct($fieldName, $query->getFilters(), $query->getOptions()); |
||||||
196 | $this->notifyQueryExecution($query); |
||||||
197 | |||||||
198 | return $result; |
||||||
199 | } |
||||||
200 | |||||||
201 | /** |
||||||
202 | * @param string $method |
||||||
203 | 12 | * @param array|object $filters |
|||||
204 | * @param array|object $data |
||||||
205 | 12 | * @param array $options |
|||||
206 | 12 | * |
|||||
207 | 12 | * @return Query |
|||||
208 | 12 | */ |
|||||
209 | 12 | private function prepareQuery(string $method, $filters = null, $data = null, array $options): Query |
|||||
210 | 12 | { |
|||||
211 | 12 | $query = new Query(); |
|||||
212 | 12 | $query->setFilters($filters ?? []); |
|||||
213 | 12 | $query->setData($data ?? []); |
|||||
214 | 12 | $query->setOptions($options); |
|||||
215 | $query->setMethod($method); |
||||||
216 | $query->setClient($this->getClientName()); |
||||||
217 | 12 | $query->setDatabase($this->getDatabaseName()); |
|||||
218 | $query->setCollection($this->getCollectionName()); |
||||||
219 | 12 | $query->setReadPreference( |
|||||
220 | $this->translateReadPreference($options['readPreference'] ?? $this->__debugInfo()['readPreference']) |
||||||
221 | ); |
||||||
222 | |||||||
223 | $event = new QueryEvent($query); |
||||||
224 | if (class_exists(LegacyEventDispatcherProxy::class)) { |
||||||
225 | $this->eventDispatcher->dispatch($event, QueryEvent::QUERY_PREPARED); |
||||||
0 ignored issues
–
show
The call to
Symfony\Contracts\EventD...erInterface::dispatch() has too many arguments starting with Facile\MongoDbBundle\Eve...ryEvent::QUERY_PREPARED .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
226 | } else { |
||||||
227 | 12 | $this->eventDispatcher->dispatch(QueryEvent::QUERY_PREPARED, $event); |
|||||
0 ignored issues
–
show
Facile\MongoDbBundle\Eve...ryEvent::QUERY_PREPARED of type string is incompatible with the type object expected by parameter $event of Symfony\Contracts\EventD...erInterface::dispatch() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
228 | } |
||||||
229 | 12 | ||||||
230 | 12 | return $query; |
|||||
231 | } |
||||||
232 | 12 | ||||||
233 | 12 | /** |
|||||
234 | * @param ReadPreference $readPreference |
||||||
235 | * |
||||||
236 | * @return string |
||||||
237 | */ |
||||||
238 | private function translateReadPreference(ReadPreference $readPreference): string |
||||||
239 | { |
||||||
240 | switch ($readPreference->getMode()) { |
||||||
241 | case ReadPreference::RP_PRIMARY: |
||||||
242 | return 'primary'; |
||||||
243 | case ReadPreference::RP_PRIMARY_PREFERRED: |
||||||
244 | return 'primaryPreferred'; |
||||||
245 | case ReadPreference::RP_SECONDARY: |
||||||
246 | return 'secondary'; |
||||||
247 | case ReadPreference::RP_SECONDARY_PREFERRED: |
||||||
248 | 12 | return 'secondaryPreferred'; |
|||||
249 | case ReadPreference::RP_NEAREST: |
||||||
250 | 12 | return 'nearest'; |
|||||
251 | default: |
||||||
252 | 12 | return 'undefined'; |
|||||
253 | 12 | } |
|||||
254 | } |
||||||
255 | |||||||
256 | /** |
||||||
257 | * @param Query $queryLog |
||||||
258 | 12 | */ |
|||||
259 | private function notifyQueryExecution(Query $queryLog) |
||||||
260 | 12 | { |
|||||
261 | $queryLog->setExecutionTime(microtime(true) - $queryLog->getStart()); |
||||||
262 | |||||||
263 | $event = new QueryEvent($queryLog); |
||||||
264 | if (class_exists(LegacyEventDispatcherProxy::class)) { |
||||||
265 | $this->eventDispatcher->dispatch($event, QueryEvent::QUERY_EXECUTED); |
||||||
0 ignored issues
–
show
The call to
Symfony\Contracts\EventD...erInterface::dispatch() has too many arguments starting with Facile\MongoDbBundle\Eve...ryEvent::QUERY_EXECUTED .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue. If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above. ![]() |
|||||||
266 | 12 | } else { |
|||||
267 | $this->eventDispatcher->dispatch(QueryEvent::QUERY_EXECUTED, $event); |
||||||
0 ignored issues
–
show
Facile\MongoDbBundle\Eve...ryEvent::QUERY_EXECUTED of type string is incompatible with the type object expected by parameter $event of Symfony\Contracts\EventD...erInterface::dispatch() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
268 | 12 | } |
|||||
269 | } |
||||||
270 | |||||||
271 | /** |
||||||
272 | * @return string |
||||||
273 | */ |
||||||
274 | public function getClientName(): string |
||||||
275 | { |
||||||
276 | return $this->clientName; |
||||||
277 | } |
||||||
278 | |||||||
279 | /** |
||||||
280 | * @return string |
||||||
281 | */ |
||||||
282 | public function getDatabaseName(): string |
||||||
283 | { |
||||||
284 | return $this->databaseName; |
||||||
285 | } |
||||||
286 | } |
||||||
287 |