These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the ONGR package. |
||
5 | * |
||
6 | * (c) NFQ Technologies UAB <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace ONGR\TranslationsBundle\Translation; |
||
13 | |||
14 | use Elasticsearch\Common\Exceptions\Missing404Exception; |
||
15 | use ONGR\ElasticsearchBundle\Result\Result; |
||
16 | use ONGR\ElasticsearchDSL\Query\ExistsQuery; |
||
17 | use ONGR\ElasticsearchDSL\Query\TermsQuery; |
||
18 | use ONGR\ElasticsearchBundle\Service\Repository; |
||
19 | use ONGR\TranslationsBundle\Event\Events; |
||
20 | use ONGR\TranslationsBundle\Event\TranslationEditMessageEvent; |
||
21 | use Symfony\Component\EventDispatcher\EventDispatcherInterface; |
||
22 | use Symfony\Component\HttpFoundation\Request; |
||
23 | use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; |
||
24 | use Symfony\Component\PropertyAccess\PropertyAccess; |
||
25 | use Symfony\Component\PropertyAccess\PropertyAccessorInterface; |
||
26 | |||
27 | /** |
||
28 | * Handles translation objects by http requests. |
||
29 | */ |
||
30 | class TranslationManager |
||
31 | { |
||
32 | /** |
||
33 | * @var Repository |
||
34 | */ |
||
35 | private $repository; |
||
36 | |||
37 | /** |
||
38 | * @var PropertyAccessorInterface |
||
39 | */ |
||
40 | private $accessor; |
||
41 | |||
42 | /** |
||
43 | * @var EventDispatcherInterface |
||
44 | */ |
||
45 | private $dispatcher; |
||
46 | |||
47 | /** |
||
48 | * @param Repository $repository |
||
49 | * @param EventDispatcherInterface $dispatcher |
||
50 | */ |
||
51 | public function __construct(Repository $repository, EventDispatcherInterface $dispatcher) |
||
52 | { |
||
53 | $this->repository = $repository; |
||
54 | $this->dispatcher = $dispatcher; |
||
55 | } |
||
56 | |||
57 | /** |
||
58 | * Adds object to translations. |
||
59 | * |
||
60 | * @param Request $request |
||
61 | */ |
||
62 | View Code Duplication | public function add(Request $request) |
|
0 ignored issues
–
show
|
|||
63 | { |
||
64 | $content = $this->parseJsonContent($request); |
||
65 | $document = $this->getTranslation($content['id']); |
||
66 | $this->addObject($document, $content); |
||
67 | $this->commitTranslation($document); |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * Edits object from translation. |
||
72 | * |
||
73 | * @param Request $request Http request object. |
||
74 | */ |
||
75 | public function edit(Request $request) |
||
76 | { |
||
77 | $content = $this->parseJsonContent($request); |
||
78 | $document = $this->getTranslation($content['id']); |
||
79 | |||
80 | if ($content['name'] == 'messages') { |
||
81 | $this->dispatcher->dispatch(Events::ADD_HISTORY, new TranslationEditMessageEvent($request, $document)); |
||
82 | } |
||
83 | $this->editObject($document, $content); |
||
84 | $this->commitTranslation($document); |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * Removes object from translations. |
||
89 | * |
||
90 | * @param Request $request Http request object. |
||
91 | */ |
||
92 | View Code Duplication | public function delete(Request $request) |
|
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.
Loading history...
|
|||
93 | { |
||
94 | $content = $this->parseJsonContent($request); |
||
95 | $document = $this->getTranslation($content['id']); |
||
96 | $this->deleteObject($document, $content); |
||
97 | $this->commitTranslation($document); |
||
98 | } |
||
99 | |||
100 | /** |
||
101 | * Returns specific values from objects. |
||
102 | * |
||
103 | * @param Request $request Http request object. |
||
104 | * |
||
105 | * @return array |
||
106 | */ |
||
107 | public function get(Request $request) |
||
108 | { |
||
109 | $content = $this->parseJsonContent($request); |
||
110 | |||
111 | $search = $this |
||
112 | ->repository |
||
113 | ->createSearch() |
||
114 | ->addFilter(new ExistsQuery($content['name'])); |
||
115 | |||
116 | if (array_key_exists('properties', $content)) { |
||
117 | foreach ($content['properties'] as $property) { |
||
118 | $search->setSource($content['name'] . '.' . $property); |
||
119 | } |
||
120 | } |
||
121 | |||
122 | if (array_key_exists('findBy', $content)) { |
||
123 | foreach ($content['findBy'] as $field => $value) { |
||
124 | $search->addQuery( |
||
125 | new TermsQuery($content['name'] . '.' . $field, is_array($value) ? $value : [$value]), |
||
126 | 'must' |
||
127 | ); |
||
128 | } |
||
129 | } |
||
130 | |||
131 | return $this->repository->execute($search, Result::RESULTS_ARRAY); |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * Adds object to translation. |
||
136 | * |
||
137 | * @param object $document |
||
138 | * @param array $options |
||
139 | */ |
||
140 | private function addObject($document, $options) |
||
141 | { |
||
142 | $meta = $this->repository->getManager()->getMetadataCollector() |
||
143 | ->getBundleMapping('ONGRTranslationsBundle:Translation'); |
||
144 | $objectClass = reset($meta)['aliases'][$options['name']]['namespace']; |
||
145 | |||
146 | $object = new $objectClass(); |
||
147 | $this->setObjectProperties($object, $options['properties']); |
||
148 | |||
149 | $this->updateTimestamp($object); |
||
150 | $this->updateTimestamp($document); |
||
151 | } |
||
152 | |||
153 | /** |
||
154 | * Removes message from document based on options. |
||
155 | * |
||
156 | * @param object $document |
||
157 | * @param array $options |
||
158 | */ |
||
159 | private function deleteObject($document, $options) |
||
160 | { |
||
161 | $accessor = $this->getAccessor(); |
||
162 | $objects = $accessor->getValue($document, $options['name']); |
||
163 | |||
164 | $key = $this->findObject($objects, $options['findBy']); |
||
165 | |||
166 | if ($key >= 0) { |
||
167 | unset($objects[$key]); |
||
168 | $accessor->setValue($document, $options['name'], $objects); |
||
169 | } |
||
170 | } |
||
171 | |||
172 | /** |
||
173 | * Edits message from document based on options. |
||
174 | * |
||
175 | * @param object $document |
||
176 | * @param array $options |
||
177 | */ |
||
178 | private function editObject($document, $options) |
||
179 | { |
||
180 | $accessor = $this->getAccessor(); |
||
181 | $objects = $accessor->getValue($document, $options['name']); |
||
182 | |||
183 | if ($objects === null) { |
||
184 | $this->addObject($document, $options); |
||
185 | } else { |
||
186 | $key = $this->findObject($objects, $options['findBy']); |
||
187 | |||
188 | if ($key < 0) { |
||
189 | $this->addObject($document, $options); |
||
190 | } else { |
||
191 | $this->setObjectProperties($objects[$key], $options['properties']); |
||
192 | $this->updateTimestamp($objects[$key]); |
||
193 | $this->updateTimestamp($document); |
||
194 | $accessor->setValue($document, $options['name'], $objects); |
||
195 | } |
||
196 | } |
||
197 | } |
||
198 | |||
199 | /** |
||
200 | * Finds object by property and its value from iterator and returns key. |
||
201 | * |
||
202 | * @param \Iterator $objects |
||
203 | * @param array $options |
||
204 | * |
||
205 | * @return int |
||
206 | */ |
||
207 | private function findObject($objects, $options) |
||
208 | { |
||
209 | foreach ($objects as $key => $object) { |
||
210 | $fit = true; |
||
211 | |||
212 | foreach ($options as $property => $value) { |
||
213 | if ($this->getAccessor()->getValue($object, $property) !== $value) { |
||
214 | $fit = false; |
||
215 | break; |
||
216 | } |
||
217 | } |
||
218 | |||
219 | if ($fit) { |
||
220 | return $key; |
||
221 | } |
||
222 | } |
||
223 | |||
224 | return -1; |
||
225 | } |
||
226 | |||
227 | /** |
||
228 | * Parses http request content from json to array. |
||
229 | * |
||
230 | * @param Request $request Http request object. |
||
231 | * |
||
232 | * @return array |
||
233 | * |
||
234 | * @throws BadRequestHttpException |
||
235 | */ |
||
236 | View Code Duplication | private function parseJsonContent(Request $request) |
|
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.
Loading history...
|
|||
237 | { |
||
238 | $content = json_decode($request->getContent(), true); |
||
239 | |||
240 | if (empty($content)) { |
||
241 | throw new BadRequestHttpException('No content found.'); |
||
242 | } |
||
243 | |||
244 | return $content; |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * Commits document into elasticsearch client. |
||
249 | * |
||
250 | * @param object $document |
||
251 | */ |
||
252 | private function commitTranslation($document) |
||
253 | { |
||
254 | $this->repository->getManager()->persist($document); |
||
255 | $this->repository->getManager()->commit(); |
||
256 | } |
||
257 | |||
258 | /** |
||
259 | * Returns translation from elasticsearch. |
||
260 | * |
||
261 | * @param string $id |
||
262 | * |
||
263 | * @return object |
||
264 | * |
||
265 | * @throws BadRequestHttpException |
||
266 | */ |
||
267 | private function getTranslation($id) |
||
268 | { |
||
269 | try { |
||
270 | $document = $this->repository->find($id); |
||
271 | } catch (Missing404Exception $e) { |
||
272 | $document = null; |
||
273 | } |
||
274 | |||
275 | if ($document === null) { |
||
276 | throw new BadRequestHttpException('Invalid translation Id.'); |
||
277 | } |
||
278 | |||
279 | return $document; |
||
280 | } |
||
281 | |||
282 | /** |
||
283 | * Returns property accessor instance. |
||
284 | * |
||
285 | * @return PropertyAccessorInterface |
||
286 | */ |
||
287 | private function getAccessor() |
||
288 | { |
||
289 | if (!$this->accessor) { |
||
290 | $this->accessor = PropertyAccess::createPropertyAccessorBuilder() |
||
291 | ->enableExceptionOnInvalidIndex() |
||
292 | ->enableMagicCall() |
||
293 | ->getPropertyAccessor(); |
||
294 | } |
||
295 | |||
296 | return $this->accessor; |
||
297 | } |
||
298 | |||
299 | /** |
||
300 | * Sets `updated_at` property. |
||
301 | * |
||
302 | * @param object $object |
||
303 | */ |
||
304 | private function updateTimestamp($object) |
||
305 | { |
||
306 | $accessor = $this->getAccessor(); |
||
307 | |||
308 | if ($accessor->isWritable($object, 'updated_at')) { |
||
309 | $accessor->setValue($object, 'updated_at', new \DateTime()); |
||
310 | } |
||
311 | } |
||
312 | |||
313 | /** |
||
314 | * Sets object properties into provided object. |
||
315 | * |
||
316 | * @param object $object Object to set properties into. |
||
317 | * @param array $properties Array of properties to set. |
||
318 | */ |
||
319 | private function setObjectProperties($object, $properties) |
||
320 | { |
||
321 | foreach ($properties as $property => $value) { |
||
322 | $this->getAccessor()->setValue($object, $property, $value); |
||
323 | } |
||
324 | } |
||
325 | } |
||
326 |
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.