1 | <?php |
||
2 | |||
3 | /* |
||
4 | * @copyright 2016 Mautic Contributors. All rights reserved |
||
5 | * @author Mautic |
||
6 | * |
||
7 | * @link http://mautic.org |
||
8 | * |
||
9 | * @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html |
||
10 | */ |
||
11 | |||
12 | namespace Mautic\DynamicContentBundle\Entity; |
||
13 | |||
14 | use Doctrine\Common\Collections\ArrayCollection; |
||
15 | use Doctrine\DBAL\Types\Type; |
||
16 | use Doctrine\ORM\Events; |
||
17 | use Doctrine\ORM\Mapping as ORM; |
||
18 | use Mautic\ApiBundle\Serializer\Driver\ApiMetadataDriver; |
||
19 | use Mautic\CoreBundle\Doctrine\Mapping\ClassMetadataBuilder; |
||
20 | use Mautic\CoreBundle\Entity\FiltersEntityTrait; |
||
21 | use Mautic\CoreBundle\Entity\FormEntity; |
||
22 | use Mautic\CoreBundle\Entity\TranslationEntityInterface; |
||
23 | use Mautic\CoreBundle\Entity\TranslationEntityTrait; |
||
24 | use Mautic\CoreBundle\Entity\VariantEntityInterface; |
||
25 | use Mautic\CoreBundle\Entity\VariantEntityTrait; |
||
26 | use Symfony\Component\Validator\Constraints\Callback; |
||
27 | use Symfony\Component\Validator\Constraints\Count; |
||
28 | use Symfony\Component\Validator\Constraints\NotBlank; |
||
29 | use Symfony\Component\Validator\Context\ExecutionContextInterface; |
||
30 | use Symfony\Component\Validator\Mapping\ClassMetadata; |
||
31 | |||
32 | class DynamicContent extends FormEntity implements VariantEntityInterface, TranslationEntityInterface |
||
33 | { |
||
34 | use TranslationEntityTrait; |
||
35 | use VariantEntityTrait; |
||
36 | use FiltersEntityTrait; |
||
37 | |||
38 | /** |
||
39 | * @var int |
||
40 | */ |
||
41 | private $id; |
||
42 | |||
43 | /** |
||
44 | * @var string |
||
45 | */ |
||
46 | private $name; |
||
47 | |||
48 | /** |
||
49 | * @var string |
||
50 | */ |
||
51 | private $description; |
||
52 | |||
53 | /** |
||
54 | * @var \Mautic\CategoryBundle\Entity\Category |
||
55 | **/ |
||
56 | private $category; |
||
57 | |||
58 | /** |
||
59 | * @var \DateTime |
||
60 | */ |
||
61 | private $publishUp; |
||
62 | |||
63 | /** |
||
64 | * @var \DateTime |
||
65 | */ |
||
66 | private $publishDown; |
||
67 | |||
68 | /** |
||
69 | * @var string |
||
70 | */ |
||
71 | private $content; |
||
72 | |||
73 | /** |
||
74 | * @var array |
||
75 | */ |
||
76 | private $utmTags = []; |
||
77 | |||
78 | /** |
||
79 | * @var int |
||
80 | */ |
||
81 | private $sentCount = 0; |
||
82 | |||
83 | /** |
||
84 | * @var ArrayCollection |
||
85 | */ |
||
86 | private $stats; |
||
87 | |||
88 | /** |
||
89 | * @var bool |
||
90 | */ |
||
91 | private $isCampaignBased = true; |
||
92 | |||
93 | /** |
||
94 | * @var string |
||
95 | */ |
||
96 | private $slotName; |
||
97 | |||
98 | /** |
||
99 | * DynamicContent constructor. |
||
100 | */ |
||
101 | public function __construct() |
||
102 | { |
||
103 | $this->stats = new ArrayCollection(); |
||
104 | $this->translationChildren = new ArrayCollection(); |
||
105 | $this->variantChildren = new ArrayCollection(); |
||
106 | } |
||
107 | |||
108 | /** |
||
109 | * Clone method. |
||
110 | */ |
||
111 | public function __clone() |
||
112 | { |
||
113 | $this->id = null; |
||
114 | $this->sentCount = 0; |
||
115 | $this->stats = new ArrayCollection(); |
||
116 | $this->translationChildren = new ArrayCollection(); |
||
117 | $this->variantChildren = new ArrayCollection(); |
||
118 | |||
119 | parent::__clone(); |
||
120 | } |
||
121 | |||
122 | /** |
||
123 | * Clear stats. |
||
124 | */ |
||
125 | public function clearStats() |
||
126 | { |
||
127 | $this->stats = new ArrayCollection(); |
||
128 | } |
||
129 | |||
130 | public static function loadMetadata(ORM\ClassMetadata $metadata) |
||
131 | { |
||
132 | $builder = new ClassMetadataBuilder($metadata); |
||
133 | |||
134 | $builder->setTable('dynamic_content') |
||
135 | ->addIndex(['is_campaign_based'], 'is_campaign_based_index') |
||
136 | ->addIndex(['slot_name'], 'slot_name_index') |
||
137 | ->setCustomRepositoryClass('Mautic\DynamicContentBundle\Entity\DynamicContentRepository') |
||
138 | ->addLifecycleEvent('cleanSlotName', Events::prePersist) |
||
139 | ->addLifecycleEvent('cleanSlotName', Events::preUpdate); |
||
140 | |||
141 | $builder->addIdColumns(); |
||
142 | |||
143 | $builder->addCategory(); |
||
144 | |||
145 | $builder->addPublishDates(); |
||
146 | |||
147 | $builder->createField('sentCount', 'integer') |
||
148 | ->columnName('sent_count') |
||
149 | ->build(); |
||
150 | |||
151 | $builder->createField('content', 'text') |
||
152 | ->columnName('content') |
||
153 | ->nullable() |
||
154 | ->build(); |
||
155 | |||
156 | $builder->createField('utmTags', Type::JSON_ARRAY) |
||
0 ignored issues
–
show
|
|||
157 | ->columnName('utm_tags') |
||
158 | ->nullable() |
||
159 | ->build(); |
||
160 | |||
161 | $builder->createOneToMany('stats', 'Stat') |
||
162 | ->setIndexBy('id') |
||
163 | ->mappedBy('dynamicContent') |
||
164 | ->cascadePersist() |
||
165 | ->fetchExtraLazy() |
||
166 | ->build(); |
||
167 | |||
168 | self::addTranslationMetadata($builder, self::class); |
||
169 | self::addVariantMetadata($builder, self::class); |
||
170 | self::addFiltersMetadata($builder); |
||
171 | |||
172 | $builder->createField('isCampaignBased', 'boolean') |
||
173 | ->columnName('is_campaign_based') |
||
174 | ->option('default', 1) |
||
175 | ->build(); |
||
176 | |||
177 | $builder->createField('slotName', 'string') |
||
178 | ->columnName('slot_name') |
||
179 | ->nullable() |
||
180 | ->build(); |
||
181 | } |
||
182 | |||
183 | /** |
||
184 | * @throws \Symfony\Component\Validator\Exception\ConstraintDefinitionException |
||
185 | * @throws \Symfony\Component\Validator\Exception\InvalidOptionsException |
||
186 | * @throws \Symfony\Component\Validator\Exception\MissingOptionsException |
||
187 | */ |
||
188 | public static function loadValidatorMetaData(ClassMetadata $metadata) |
||
189 | { |
||
190 | $metadata->addPropertyConstraint('name', new NotBlank(['message' => 'mautic.core.name.required'])); |
||
191 | |||
192 | $metadata->addConstraint(new Callback([ |
||
193 | 'callback' => function (self $dwc, ExecutionContextInterface $context) { |
||
194 | if (!$dwc->getIsCampaignBased()) { |
||
195 | $validator = $context->getValidator(); |
||
196 | $violations = $validator->validate( |
||
197 | $dwc->getSlotName(), |
||
198 | [ |
||
199 | new NotBlank( |
||
200 | [ |
||
201 | 'message' => 'mautic.dynamicContent.slot_name.notblank', |
||
202 | ] |
||
203 | ), |
||
204 | ] |
||
205 | ); |
||
206 | if (count($violations) > 0) { |
||
207 | foreach ($violations as $violation) { |
||
208 | $context->buildViolation($violation->getMessage()) |
||
209 | ->atPath('slotName') |
||
210 | ->addViolation(); |
||
211 | } |
||
212 | } |
||
213 | $violations = $validator->validate( |
||
214 | $dwc->getFilters(), |
||
215 | [ |
||
216 | new Count( |
||
217 | [ |
||
218 | 'minMessage' => 'mautic.dynamicContent.filter.options.empty', |
||
219 | 'min' => 1, |
||
220 | ] |
||
221 | ), |
||
222 | ] |
||
223 | ); |
||
224 | if (count($violations) > 0) { |
||
225 | foreach ($violations as $violation) { |
||
226 | $context->buildViolation($violation->getMessage()) |
||
227 | ->atPath('filters') |
||
228 | ->addViolation(); |
||
229 | } |
||
230 | } |
||
231 | } |
||
232 | }, |
||
233 | ])); |
||
234 | } |
||
235 | |||
236 | public static function loadApiMetadata(ApiMetadataDriver $metadata) |
||
237 | { |
||
238 | $metadata->setGroupPrefix('dwc') |
||
239 | ->addListProperties([ |
||
240 | 'id', |
||
241 | 'name', |
||
242 | 'category', |
||
243 | ]) |
||
244 | ->addProperties([ |
||
245 | 'publishUp', |
||
246 | 'publishDown', |
||
247 | 'sentCount', |
||
248 | 'variantParent', |
||
249 | 'variantChildren', |
||
250 | 'content', |
||
251 | 'utmTags', |
||
252 | 'filters', |
||
253 | 'isCampaignBased', |
||
254 | 'slotName', |
||
255 | ]) |
||
256 | ->setMaxDepth(1, 'variantParent') |
||
257 | ->setMaxDepth(1, 'variantChildren') |
||
258 | ->build(); |
||
259 | } |
||
260 | |||
261 | /** |
||
262 | * @param $prop |
||
263 | * @param $val |
||
264 | */ |
||
265 | protected function isChanged($prop, $val) |
||
266 | { |
||
267 | $getter = 'get'.ucfirst($prop); |
||
268 | $current = $this->$getter(); |
||
269 | |||
270 | if ('variantParent' == $prop || 'translationParent' == $prop || 'category' == $prop) { |
||
271 | $currentId = ($current) ? $current->getId() : ''; |
||
272 | $newId = ($val) ? $val->getId() : null; |
||
273 | if ($currentId != $newId) { |
||
274 | $this->changes[$prop] = [$currentId, $newId]; |
||
275 | } |
||
276 | } else { |
||
277 | parent::isChanged($prop, $val); |
||
278 | } |
||
279 | } |
||
280 | |||
281 | /** |
||
282 | * @return int |
||
283 | */ |
||
284 | public function getId() |
||
285 | { |
||
286 | return $this->id; |
||
287 | } |
||
288 | |||
289 | /** |
||
290 | * @return string |
||
291 | */ |
||
292 | public function getName() |
||
293 | { |
||
294 | return $this->name; |
||
295 | } |
||
296 | |||
297 | /** |
||
298 | * @param string $name |
||
299 | * |
||
300 | * @return $this |
||
301 | */ |
||
302 | public function setName($name) |
||
303 | { |
||
304 | $this->isChanged('name', $name); |
||
305 | $this->name = $name; |
||
306 | |||
307 | return $this; |
||
308 | } |
||
309 | |||
310 | /** |
||
311 | * @return string |
||
312 | */ |
||
313 | public function getDescription() |
||
314 | { |
||
315 | return $this->description; |
||
316 | } |
||
317 | |||
318 | /** |
||
319 | * @param string $description |
||
320 | * |
||
321 | * @return $this |
||
322 | */ |
||
323 | public function setDescription($description) |
||
324 | { |
||
325 | $this->description = $description; |
||
326 | |||
327 | return $this; |
||
328 | } |
||
329 | |||
330 | /** |
||
331 | * @return \Mautic\CategoryBundle\Entity\Category |
||
332 | */ |
||
333 | public function getCategory() |
||
334 | { |
||
335 | return $this->category; |
||
336 | } |
||
337 | |||
338 | /** |
||
339 | * @param \Mautic\CategoryBundle\Entity\Category $category |
||
340 | * |
||
341 | * @return $this |
||
342 | */ |
||
343 | public function setCategory($category) |
||
344 | { |
||
345 | $this->isChanged('category', $category); |
||
346 | $this->category = $category; |
||
347 | |||
348 | return $this; |
||
349 | } |
||
350 | |||
351 | /** |
||
352 | * @return \DateTime |
||
353 | */ |
||
354 | public function getPublishUp() |
||
355 | { |
||
356 | return $this->publishUp; |
||
357 | } |
||
358 | |||
359 | /** |
||
360 | * @param \DateTime $publishUp |
||
361 | * |
||
362 | * @return $this |
||
363 | */ |
||
364 | public function setPublishUp($publishUp) |
||
365 | { |
||
366 | $this->isChanged('publishUp', $publishUp); |
||
367 | $this->publishUp = $publishUp; |
||
368 | |||
369 | return $this; |
||
370 | } |
||
371 | |||
372 | /** |
||
373 | * @return \DateTime |
||
374 | */ |
||
375 | public function getPublishDown() |
||
376 | { |
||
377 | return $this->publishDown; |
||
378 | } |
||
379 | |||
380 | /** |
||
381 | * @param \DateTime $publishDown |
||
382 | * |
||
383 | * @return $this |
||
384 | */ |
||
385 | public function setPublishDown($publishDown) |
||
386 | { |
||
387 | $this->isChanged('publishDown', $publishDown); |
||
388 | $this->publishDown = $publishDown; |
||
389 | |||
390 | return $this; |
||
391 | } |
||
392 | |||
393 | /** |
||
394 | * @return string |
||
395 | */ |
||
396 | public function getContent() |
||
397 | { |
||
398 | return $this->content; |
||
399 | } |
||
400 | |||
401 | /** |
||
402 | * @param string $content |
||
403 | * |
||
404 | * @return $this |
||
405 | */ |
||
406 | public function setContent($content) |
||
407 | { |
||
408 | $this->isChanged('content', $content); |
||
409 | $this->content = $content; |
||
410 | |||
411 | return $this; |
||
412 | } |
||
413 | |||
414 | /** |
||
415 | * @param bool $includeVariants |
||
416 | * |
||
417 | * @return mixed |
||
418 | */ |
||
419 | public function getSentCount($includeVariants = false) |
||
420 | { |
||
421 | return $includeVariants ? $this->getAccumulativeTranslationCount('getSentCount') : $this->sentCount; |
||
422 | } |
||
423 | |||
424 | /** |
||
425 | * @param $sentCount |
||
426 | * |
||
427 | * @return $this |
||
428 | */ |
||
429 | public function setSentCount($sentCount) |
||
430 | { |
||
431 | $this->sentCount = $sentCount; |
||
432 | |||
433 | return $this; |
||
434 | } |
||
435 | |||
436 | /** |
||
437 | * @return ArrayCollection |
||
438 | */ |
||
439 | public function getStats() |
||
440 | { |
||
441 | return $this->stats; |
||
442 | } |
||
443 | |||
444 | /** |
||
445 | * @return bool |
||
446 | */ |
||
447 | public function getIsCampaignBased() |
||
448 | { |
||
449 | return $this->isCampaignBased; |
||
450 | } |
||
451 | |||
452 | /** |
||
453 | * @param bool $isCampaignBased |
||
454 | * |
||
455 | * @return $this |
||
456 | */ |
||
457 | public function setIsCampaignBased($isCampaignBased) |
||
458 | { |
||
459 | $this->isChanged('isCampaignBased', $isCampaignBased); |
||
460 | $this->isCampaignBased = $isCampaignBased; |
||
461 | |||
462 | return $this; |
||
463 | } |
||
464 | |||
465 | /** |
||
466 | * @return string |
||
467 | */ |
||
468 | public function getSlotName() |
||
469 | { |
||
470 | return $this->slotName; |
||
471 | } |
||
472 | |||
473 | /** |
||
474 | * @param string $slotName |
||
475 | * |
||
476 | * @return $this |
||
477 | */ |
||
478 | public function setSlotName($slotName) |
||
479 | { |
||
480 | $this->isChanged('slotName', $slotName); |
||
481 | $this->slotName = $slotName; |
||
482 | |||
483 | return $this; |
||
484 | } |
||
485 | |||
486 | /** |
||
487 | * Lifecycle callback to clear the slot name if is_campaign is true. |
||
488 | */ |
||
489 | public function cleanSlotName() |
||
490 | { |
||
491 | if ($this->getIsCampaignBased()) { |
||
492 | $this->setSlotName(''); |
||
493 | } |
||
494 | } |
||
495 | |||
496 | /** |
||
497 | * @return DynamicContent |
||
498 | */ |
||
499 | public function setUtmTags(array $utmTags) |
||
500 | { |
||
501 | $this->isChanged('utmTags', $utmTags); |
||
502 | $this->utmTags = $utmTags; |
||
503 | |||
504 | return $this; |
||
505 | } |
||
506 | |||
507 | /** |
||
508 | * @return array |
||
509 | */ |
||
510 | public function getUtmTags() |
||
511 | { |
||
512 | return $this->utmTags; |
||
513 | } |
||
514 | } |
||
515 |
This class constant has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the constant will be removed from the class and what other constant to use instead.