Spaces:
No application file
No application file
| namespace Mautic\CoreBundle\Model; | |
| use Mautic\CoreBundle\Entity\TranslationEntityInterface; | |
| use Mautic\CoreBundle\Entity\VariantEntityInterface; | |
| trait VariantModelTrait | |
| { | |
| /** | |
| * @var bool | |
| */ | |
| protected $inConversion = false; | |
| /** | |
| * Converts a variant to the main item and the original main item a variant. | |
| */ | |
| public function convertVariant(VariantEntityInterface $entity): void | |
| { | |
| // let saveEntities() know it does not need to set variant start dates | |
| $this->inConversion = true; | |
| [$parent, $children] = $entity->getVariants(); | |
| $save = []; | |
| // set this email as the parent for the original parent and children | |
| if ($parent) { | |
| if ($parent->getId() != $entity->getId()) { | |
| if (method_exists($parent, 'setIsPublished')) { | |
| $parent->setIsPublished(false); | |
| } | |
| $entity->addVariantChild($parent); | |
| $parent->setVariantParent($entity); | |
| } | |
| $parent->setVariantStartDate(null); | |
| $parent->setVariantSentCount(0); | |
| foreach ($children as $child) { | |
| // capture child before it's removed from collection | |
| $save[] = $child; | |
| $parent->removeVariantChild($child); | |
| } | |
| } | |
| if (count($save)) { | |
| foreach ($save as $child) { | |
| if ($child->getId() != $entity->getId()) { | |
| if (method_exists($child, 'setIsPublished')) { | |
| $child->setIsPublished(false); | |
| } | |
| $entity->addVariantChild($child); | |
| $child->setVariantParent($entity); | |
| } else { | |
| $child->removeVariantParent(); | |
| } | |
| $child->setVariantSentCount(0); | |
| $child->setVariantStartDate(null); | |
| } | |
| } | |
| $save[] = $parent; | |
| $save[] = $entity; | |
| // save the entities | |
| $this->saveEntities($save, false); | |
| } | |
| /** | |
| * Prepare a variant for saving. | |
| * | |
| * @param array $resetVariantCounterMethods ['setVariantHits', 'setVariantSends', ...] | |
| */ | |
| protected function preVariantSaveEntity(VariantEntityInterface $entity, array $resetVariantCounterMethods = [], \DateTime $variantStartDate = null): bool | |
| { | |
| $isVariant = $entity->isVariant(); | |
| if (!$isVariant && $entity instanceof TranslationEntityInterface) { | |
| // Translations could be assigned to a variant and thus applicable to be reset | |
| if ($translationParent = $entity->getTranslationParent()) { | |
| $isVariant = $translationParent->isVariant(); /** @phpstan-ignore-line @todo for M6, extend the TranslationEntityInterface from The VariantEntityInterface */ | |
| } | |
| } | |
| if ($isVariant) { | |
| // Reset the variant hit and start date if there are any changes and if this is an A/B test | |
| // Do it here in addition to postVariantSave() so that it's available to the event listeners | |
| $changes = $entity->getChanges(); | |
| // If unpublished and wasn't changed from published - don't reset | |
| if (!$entity->isPublished(false) && (!isset($changes['isPublished']))) { | |
| return false; | |
| } | |
| // Reset the variant | |
| if (!empty($changes) && empty($this->inConversion)) { | |
| if (method_exists($entity, 'setVariantStartDate')) { | |
| $entity->setVariantStartDate($variantStartDate); | |
| } | |
| // Reset counters | |
| foreach ($resetVariantCounterMethods as $method) { | |
| if (method_exists($entity, $method)) { | |
| $entity->$method(0); | |
| } | |
| } | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| /** | |
| * Run post saving a variant aware entity. | |
| * | |
| * @param bool $resetVariants | |
| * @param array $relatedIds | |
| */ | |
| protected function postVariantSaveEntity(VariantEntityInterface $entity, $resetVariants = false, $relatedIds = [], \DateTime $variantStartDate = null) | |
| { | |
| // If parent, add this entity as a child of the parent so that it populates the list in the tab (due to Doctrine hanging on to entities in memory) | |
| if ($parent = $entity->getVariantParent()) { | |
| $parent->addVariantChild($entity); | |
| } | |
| // Reset associated variants if applicable due to changes | |
| if ($resetVariants && empty($this->inConversion)) { | |
| $this->resetVariants($entity, $relatedIds, $variantStartDate); | |
| } | |
| } | |
| protected function resetVariants($entity, $relatedIds = null, \DateTime $variantStartDate = null) | |
| { | |
| $repo = $this->getRepository(); | |
| if (method_exists($repo, 'resetVariants')) { | |
| if (null == $relatedIds) { | |
| $relatedIds = $entity->getRelatedEntityIds(); | |
| } | |
| if (!in_array($entity->getId(), $relatedIds)) { | |
| $relatedIds[] = $entity->getId(); | |
| } | |
| if (null === $variantStartDate) { | |
| $variantStartDate = new \DateTime(); | |
| } | |
| // Ensure UTC since we're saving directly to the DB | |
| $variantStartDate->setTimezone(new \DateTimeZone('UTC')); | |
| $repo->resetVariants($relatedIds, $variantStartDate->format('Y-m-d H:i:s')); | |
| } | |
| } | |
| } | |