Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/mautic.corals.io/app/bundles/CampaignBundle/Controller/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/mautic.corals.io/app/bundles/CampaignBundle/Controller/CampaignController.php
<?php

namespace Mautic\CampaignBundle\Controller;

use Doctrine\DBAL\Cache\CacheException;
use Doctrine\Persistence\ManagerRegistry;
use Mautic\CampaignBundle\Entity\Campaign;
use Mautic\CampaignBundle\Entity\Event;
use Mautic\CampaignBundle\Entity\LeadEventLog;
use Mautic\CampaignBundle\Entity\LeadEventLogRepository;
use Mautic\CampaignBundle\Entity\Summary;
use Mautic\CampaignBundle\Entity\SummaryRepository;
use Mautic\CampaignBundle\EventCollector\EventCollector;
use Mautic\CampaignBundle\EventListener\CampaignActionJumpToEventSubscriber;
use Mautic\CampaignBundle\Model\CampaignModel;
use Mautic\CampaignBundle\Model\EventModel;
use Mautic\CoreBundle\Controller\AbstractStandardFormController;
use Mautic\CoreBundle\Factory\MauticFactory;
use Mautic\CoreBundle\Factory\ModelFactory;
use Mautic\CoreBundle\Factory\PageHelperFactoryInterface;
use Mautic\CoreBundle\Form\Type\DateRangeType;
use Mautic\CoreBundle\Helper\CoreParametersHelper;
use Mautic\CoreBundle\Helper\UserHelper;
use Mautic\CoreBundle\Security\Permissions\CorePermissions;
use Mautic\CoreBundle\Service\FlashBag;
use Mautic\CoreBundle\Translation\Translator;
use Mautic\CoreBundle\Twig\Helper\DateHelper;
use Mautic\FormBundle\Helper\FormFieldHelper;
use Mautic\LeadBundle\Controller\EntityContactsTrait;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;

class CampaignController extends AbstractStandardFormController
{
    use EntityContactsTrait;

    /**
     * @var array
     */
    protected $addedSources = [];

    /**
     * @var array
     */
    protected $campaignEvents = [];

    /**
     * @var array
     */
    protected $campaignSources = [];

    /**
     * @var array
     */
    protected $connections = [];

    /**
     * @var array
     */
    protected $deletedEvents = [];

    /**
     * @var array
     */
    protected $deletedSources = [];

    /**
     * @var array
     */
    protected $listFilters = [];

    /**
     * @var array
     */
    protected $modifiedEvents = [];

    protected $sessionId;

    public function __construct(
        FormFactoryInterface $formFactory,
        FormFieldHelper $fieldHelper,
        private EventCollector $eventCollector,
        private DateHelper $dateHelper,
        ManagerRegistry $managerRegistry,
        MauticFactory $factory,
        ModelFactory $modelFactory,
        UserHelper $userHelper,
        CoreParametersHelper $coreParametersHelper,
        EventDispatcherInterface $dispatcher,
        Translator $translator,
        FlashBag $flashBag,
        private RequestStack $requestStack,
        CorePermissions $security
    ) {
        parent::__construct($formFactory, $fieldHelper, $managerRegistry, $factory, $modelFactory, $userHelper, $coreParametersHelper, $dispatcher, $translator, $flashBag, $requestStack, $security);
    }

    protected function getPermissions(): array
    {
        // set some permissions
        return (array) $this->security->isGranted(
            [
                'campaign:campaigns:viewown',
                'campaign:campaigns:viewother',
                'campaign:campaigns:create',
                'campaign:campaigns:editown',
                'campaign:campaigns:editother',
                'campaign:campaigns:cloneown',
                'campaign:campaigns:cloneother',
                'campaign:campaigns:deleteown',
                'campaign:campaigns:deleteother',
                'campaign:campaigns:publishown',
                'campaign:campaigns:publishother',
            ],
            'RETURN_ARRAY'
        );
    }

    /**
     * Deletes a group of entities.
     *
     * @return JsonResponse|RedirectResponse
     */
    public function batchDeleteAction(Request $request)
    {
        return $this->batchDeleteStandard($request);
    }

    /**
     * Clone an entity.
     *
     * @return JsonResponse|RedirectResponse|Response
     */
    public function cloneAction(Request $request, $objectId)
    {
        return $this->cloneStandard($request, $objectId);
    }

    /**
     * @param string|int $objectId
     * @param int        $page
     * @param int|null   $count
     *
     * @return JsonResponse|RedirectResponse|Response
     */
    public function contactsAction(
        Request $request,
        PageHelperFactoryInterface $pageHelperFactory,
        $objectId,
        $page = 1,
        $count = null,
        \DateTimeInterface $dateFrom = null,
        \DateTimeInterface $dateTo = null
    ) {
        $session = $request->getSession();
        $session->set('mautic.campaign.contact.page', $page);

        return $this->generateContactsGrid(
            $request,
            $pageHelperFactory,
            $objectId,
            $page,
            'campaign:campaigns:view',
            'campaign',
            'campaign_leads',
            null,
            'campaign_id',
            ['manually_removed' => 0],
            null,
            null,
            [],
            null,
            'entity.lead_id',
            'DESC',
            $count,
            $dateFrom,
            $dateTo
        );
    }

    /**
     * Deletes the entity.
     *
     * @return JsonResponse|RedirectResponse
     */
    public function deleteAction(Request $request, $objectId)
    {
        return $this->deleteStandard($request, $objectId);
    }

    /**
     * @param bool $ignorePost
     *
     * @return JsonResponse|RedirectResponse|Response
     */
    public function editAction(Request $request, $objectId, $ignorePost = false)
    {
        return $this->editStandard($request, $objectId, $ignorePost);
    }

    /**
     * @param int $page
     *
     * @return JsonResponse|Response
     */
    public function indexAction(Request $request, $page = null)
    {
        // set some permissions
        $permissions = $this->security->isGranted(
            [
                'campaign:campaigns:view',
                'campaign:campaigns:viewown',
                'campaign:campaigns:viewother',
                'campaign:campaigns:create',
                'campaign:campaigns:edit',
                'campaign:campaigns:editown',
                'campaign:campaigns:editother',
                'campaign:campaigns:delete',
                'campaign:campaigns:deleteown',
                'campaign:campaigns:deleteother',
                'campaign:campaigns:publish',
                'campaign:campaigns:publishown',
                'campaign:campaigns:publishother',
            ],
            'RETURN_ARRAY',
            null,
            true
        );

        if (!$permissions['campaign:campaigns:view']) {
            return $this->accessDenied();
        }

        $this->setListFilters();

        $session = $request->getSession();
        if (empty($page)) {
            $page = $session->get('mautic.campaign.page', 1);
        }

        $limit = $session->get('mautic.campaign.limit', $this->coreParametersHelper->get('default_pagelimit'));
        $start = (1 === $page) ? 0 : (($page - 1) * $limit);
        if ($start < 0) {
            $start = 0;
        }

        $search = $request->get('search', $session->get('mautic.campaign.filter', ''));
        $session->set('mautic.campaign.filter', $search);

        $filter = ['string' => $search, 'force' => []];

        $model = $this->getModel('campaign');

        if (!$permissions[$this->getPermissionBase().':viewother']) {
            $filter['force'][] = ['column' => 'c.createdBy', 'expr' => 'eq', 'value' => $this->user->getId()];
        }

        $orderBy    = $session->get('mautic.campaign.orderby', 'c.dateModified');
        $orderByDir = $session->get('mautic.campaign.orderbydir', $this->getDefaultOrderDirection());

        [$count, $items] = $this->getIndexItems($start, $limit, $filter, $orderBy, $orderByDir);

        if ($count && $count < ($start + 1)) {
            // the number of entities are now less then the current page so redirect to the last page
            $lastPage = (1 === $count) ? 1 : (((ceil($count / $limit)) ?: 1) ?: 1);

            $session->set('mautic.campaign.page', $lastPage);
            $returnUrl = $this->generateUrl('mautic_campaign_index', ['page' => $lastPage]);

            return $this->postActionRedirect(
                $this->getPostActionRedirectArguments(
                    [
                        'returnUrl'       => $returnUrl,
                        'viewParameters'  => ['page' => $lastPage],
                        'contentTemplate' => 'Mautic\CampaignBundle\Controller\CampaignController::indexAction',
                        'passthroughVars' => [
                            'mauticContent' => 'campaign',
                        ],
                    ],
                    'index'
                )
            );
        }

        // set what page currently on so that we can return here after form submission/cancellation
        $session->set('mautic.campaign.page', $page);

        $viewParameters = [
            'permissionBase'  => $this->getPermissionBase(),
            'mauticContent'   => $this->getJsLoadMethodPrefix(),
            'sessionVar'      => $this->getSessionBase(),
            'actionRoute'     => $this->getActionRoute(),
            'indexRoute'      => $this->getIndexRoute(),
            'tablePrefix'     => $model->getRepository()->getTableAlias(),
            'modelName'       => $this->getModelName(),
            'translationBase' => $this->getTranslationBase(),
            'searchValue'     => $search,
            'items'           => $items,
            'totalItems'      => $count,
            'page'            => $page,
            'limit'           => $limit,
            'permissions'     => $permissions,
            'tmpl'            => $request->get('tmpl', 'index'),
        ];

        return $this->delegateView(
            $this->getViewArguments(
                [
                    'viewParameters'  => $viewParameters,
                    'contentTemplate' => '@MauticCampaign/Campaign/list.html.twig',
                    'passthroughVars' => [
                        'mauticContent' => $this->getJsLoadMethodPrefix(),
                        'route'         => $this->generateUrl($this->getIndexRoute(), ['page' => $page]),
                    ],
                ],
                'index'
            )
        );
    }

    /**
     * Generates new form and processes post data.
     *
     * @return RedirectResponse|Response
     */
    public function newAction(Request $request)
    {
        /** @var CampaignModel $model */
        $model    = $this->getModel('campaign');
        $campaign = $model->getEntity();

        if (!$this->security->isGranted('campaign:campaigns:create')) {
            return $this->accessDenied();
        }

        // set the page we came from
        $page = $request->getSession()->get('mautic.campaign.page', 1);

        $options = $this->getEntityFormOptions();
        $action  = $this->generateUrl('mautic_campaign_action', ['objectAction' => 'new']);
        $form    = $model->createForm($campaign, $this->formFactory, $action, $options);

        // /Check for a submitted form and process it
        $isPost = 'POST' === $request->getMethod();
        $this->beforeFormProcessed($campaign, $form, 'new', $isPost);

        if ($isPost) {
            $valid = false;
            if (!$cancelled = $this->isFormCancelled($form)) {
                if ($valid = $this->isFormValid($form)) {
                    if ($valid = $this->beforeEntitySave($campaign, $form, 'new')) {
                        $campaign->setDateModified(new \DateTime());
                        $model->saveEntity($campaign);
                        $this->afterEntitySave($campaign, $form, 'new', $valid);

                        if (method_exists($this, 'viewAction')) {
                            $viewParameters = ['objectId' => $campaign->getId(), 'objectAction' => 'view'];
                            $returnUrl      = $this->generateUrl('mautic_campaign_action', $viewParameters);
                            $template       = 'Mautic\CampaignBundle\Controller\CampaignController::viewAction';
                        } else {
                            $viewParameters = ['page' => $page];
                            $returnUrl      = $this->generateUrl('mautic_campaign_index', $viewParameters);
                            $template       = 'Mautic\CampaignBundle\Controller\CampaignController::indexAction';
                        }
                    }
                }

                $this->afterFormProcessed($valid, $campaign, $form, 'new');
            } else {
                $viewParameters = ['page' => $page];
                $returnUrl      = $this->generateUrl($this->getIndexRoute(), $viewParameters);
                $template       = 'Mautic\CampaignBundle\Controller\CampaignController::indexAction';
            }

            $passthrough = [
                'mauticContent' => 'cammpaign',
            ];

            if ($isInPopup = isset($form['updateSelect'])) {
                $template    = false;
                $passthrough = array_merge(
                    $passthrough,
                    $this->getUpdateSelectParams($form['updateSelect']->getData(), $campaign)
                );
            }

            if ($cancelled || ($valid && !$this->isFormApplied($form))) {
                if ($isInPopup) {
                    $passthrough['closeModal'] = true;
                }

                return $this->postActionRedirect(
                    $this->getPostActionRedirectArguments(
                        [
                            'returnUrl'       => $returnUrl,
                            'viewParameters'  => $viewParameters,
                            'contentTemplate' => $template,
                            'passthroughVars' => $passthrough,
                            'entity'          => $campaign,
                        ],
                        'new'
                    )
                );
            } elseif ($valid && $this->isFormApplied($form)) {
                return $this->editAction($request, $campaign->getId(), true);
            }
        }

        $delegateArgs = [
            'viewParameters' => [
                'permissionBase'  => $model->getPermissionBase(),
                'mauticContent'   => 'campaign',
                'actionRoute'     => 'mautic_campaign_action',
                'indexRoute'      => 'mautic_campaign_index',
                'tablePrefix'     => 'c',
                'modelName'       => 'campaign',
                'translationBase' => $this->getTranslationBase(),
                'tmpl'            => $request->isXmlHttpRequest() ? $request->get('tmpl', 'index') : 'index',
                'entity'          => $campaign,
                'form'            => $this->getFormView($form, 'new'),
            ],
            'contentTemplate' => '@MauticCampaign/Campaign/form.html.twig',
            'passthroughVars' => [
                'mauticContent' => 'campaign',
                'route'         => $this->generateUrl(
                    'mautic_campaign_action',
                    [
                        'objectAction' => (!empty($valid) ? 'edit' : 'new'), // valid means a new form was applied
                        'objectId'     => ($campaign) ? $campaign->getId() : 0,
                    ]
                ),
                'validationError' => $this->getFormErrorForBuilder($form),
            ],
            'entity' => $campaign,
            'form'   => $form,
        ];

        return $this->delegateView(
            $this->getViewArguments($delegateArgs, 'new')
        );
    }

    /**
     * View a specific campaign.
     *
     * @return JsonResponse|Response
     */
    public function viewAction(Request $request, $objectId)
    {
        return $this->viewStandard($request, $objectId, $this->getModelName(), null, null, 'campaign');
    }

    /**
     * @param Campaign $campaign
     * @param Campaign $oldCampaign
     */
    protected function afterEntityClone($campaign, $oldCampaign)
    {
        $tempId   = 'mautic_'.sha1(uniqid(mt_rand(), true));
        $objectId = $oldCampaign->getId();

        // Get the events that need to be duplicated as well
        $events = $oldCampaign->getEvents()->toArray();

        $campaign->setIsPublished(false);

        // Clone the campaign's events
        /** @var Event $event */
        foreach ($events as $event) {
            $tempEventId = 'new'.$event->getId();

            $clone = clone $event;
            $clone->nullId();
            $clone->setCampaign($campaign);
            $clone->setTempId($tempEventId);

            // Just wipe out the parent as it'll be generated when the cloned entity is saved
            $clone->setParent(null);

            if (CampaignActionJumpToEventSubscriber::EVENT_NAME === $clone->getType()) {
                // Update properties to point to the new temp ID
                $properties                = $clone->getProperties();
                $properties['jumpToEvent'] = 'new'.$properties['jumpToEvent'];

                $clone->setProperties($properties);
            }

            $campaign->addEvent($tempEventId, $clone);
        }

        // Update canvas settings with new event ids
        $canvasSettings = $campaign->getCanvasSettings();
        if (isset($canvasSettings['nodes'])) {
            foreach ($canvasSettings['nodes'] as &$node) {
                // Only events and not lead sources
                if (is_numeric($node['id'])) {
                    $node['id'] = 'new'.$node['id'];
                }
            }
        }

        if (isset($canvasSettings['connections'])) {
            foreach ($canvasSettings['connections'] as &$c) {
                // Only events and not lead sources
                if (is_numeric($c['sourceId'])) {
                    $c['sourceId'] = 'new'.$c['sourceId'];
                }

                // Only events and not lead sources
                if (is_numeric($c['targetId'])) {
                    $c['targetId'] = 'new'.$c['targetId'];
                }
            }
        }

        // Simulate edit
        $campaign->setCanvasSettings($canvasSettings);
        $this->setSessionCanvasSettings($tempId, $canvasSettings);
        $tempId = $this->getCampaignSessionId($campaign, 'clone', $tempId);

        $campaignSources = $this->getCampaignModel()->getLeadSources($objectId);
        $this->prepareCampaignSourcesForEdit($tempId, $campaignSources);
    }

    /**
     * @param object    $entity
     * @param string    $action
     * @param bool|null $persistConnections
     */
    protected function afterEntitySave($entity, FormInterface $form, $action, $persistConnections = null)
    {
        if ($persistConnections) {
            // Update canvas settings with new event IDs then save
            $this->connections = $this->getCampaignModel()->setCanvasSettings($entity, $this->connections);
        } else {
            // Just update and add to entity
            $this->connections = $this->getCampaignModel()->setCanvasSettings($entity, $this->connections, false, $this->modifiedEvents);
        }
    }

    /**
     * @param bool $isClone
     */
    protected function afterFormProcessed($isValid, $entity, FormInterface $form, $action, $isClone = false)
    {
        if (!$isValid) {
            // Add the canvas settings to the entity to be able to rebuild it
            $this->afterEntitySave($entity, $form, $action, false);
        } else {
            $this->clearSessionComponents($this->sessionId);
            $this->sessionId = $entity->getId();
        }
    }

    /**
     * @param bool $isClone
     */
    protected function beforeFormProcessed($entity, FormInterface $form, $action, $isPost, $objectId = null, $isClone = false)
    {
        $sessionId = $this->getCampaignSessionId($entity, $action, $objectId);
        // set added/updated events
        [$this->modifiedEvents, $this->deletedEvents, $this->campaignEvents] = $this->getSessionEvents($sessionId);

        // set added/updated sources
        [$this->addedSources, $this->deletedSources, $campaignSources]     = $this->getSessionSources($sessionId, $isClone);
        $this->connections                                                 = $this->getSessionCanvasSettings($sessionId);

        if ($isPost) {
            $this->getCampaignModel()->setCanvasSettings($entity, $this->connections, false, $this->modifiedEvents);
            $this->prepareCampaignSourcesForEdit($sessionId, $campaignSources, true);
        } else {
            if (!$isClone) {
                // clear out existing fields in case the form was refreshed, browser closed, etc
                $this->clearSessionComponents($sessionId);
                $this->modifiedEvents = $this->campaignSources = [];

                if ($entity->getId()) {
                    $campaignSources = $this->getCampaignModel()->getLeadSources($entity->getId());
                    $this->prepareCampaignSourcesForEdit($sessionId, $campaignSources);

                    $this->setSessionCanvasSettings($sessionId, $entity->getCanvasSettings());
                }
            }

            $this->deletedEvents = [];

            $form->get('sessionId')->setData($sessionId);

            $this->prepareCampaignEventsForEdit($entity, $sessionId, $isClone);
        }
    }

    /**
     * @param Campaign $entity
     * @param bool     $isClone
     */
    protected function beforeEntitySave($entity, FormInterface $form, $action, $objectId = null, $isClone = false): bool
    {
        if (empty($this->campaignEvents)) {
            // set the error
            $form->addError(
                new FormError(
                    $this->translator->trans('mautic.campaign.form.events.notempty', [], 'validators')
                )
            );

            return false;
        }

        if (empty($this->campaignSources['lists']) && empty($this->campaignSources['forms'])) {
            // set the error
            $form->addError(
                new FormError(
                    $this->translator->trans('mautic.campaign.form.sources.notempty', [], 'validators')
                )
            );

            return false;
        }

        if ($isClone) {
            [$this->addedSources, $this->deletedSources, $campaignSources] = $this->getSessionSources($objectId, $isClone);
            $this->getCampaignModel()->setLeadSources($entity, $campaignSources, []);
            // If this is a clone, we need to save the entity first to properly build the events, sources and canvas settings
            $this->getCampaignModel()->getRepository()->saveEntity($entity);
            // Set as new so that timestamps are still hydrated
            $entity->setNew();
            $this->sessionId = $entity->getId();
        }

        // Set lead sources
        $this->getCampaignModel()->setLeadSources($entity, $this->addedSources, $this->deletedSources);

        // Build and set Event entities
        $this->getCampaignModel()->setEvents($entity, $this->campaignEvents, $this->connections, $this->deletedEvents);

        if ('edit' === $action && null !== $this->connections) {
            if (!empty($this->deletedEvents)) {
                /** @var EventModel $eventModel */
                $eventModel = $this->getModel('campaign.event');
                $eventModel->deleteEvents($entity->getEvents()->toArray(), $this->deletedEvents);
            }
        }

        return true;
    }

    /**
     * Clear field and events from the session.
     */
    protected function clearSessionComponents($id)
    {
        $session = $this->getCurrentRequest()->getSession();
        $session->remove('mautic.campaign.'.$id.'.events.modified');
        $session->remove('mautic.campaign.'.$id.'.events.deleted');
        $session->remove('mautic.campaign.'.$id.'.events.canvassettings');
        $session->remove('mautic.campaign.'.$id.'.leadsources.current');
        $session->remove('mautic.campaign.'.$id.'.leadsources.modified');
        $session->remove('mautic.campaign.'.$id.'.leadsources.deleted');
    }

    /**
     * @return CampaignModel
     */
    protected function getCampaignModel()
    {
        /** @var CampaignModel $model */
        $model = $this->getModel($this->getModelName());

        return $model;
    }

    /**
     * @return int|string|null
     */
    protected function getCampaignSessionId(Campaign $campaign, $action, $objectId = null)
    {
        if (isset($this->sessionId)) {
            return $this->sessionId;
        }

        if ($objectId) {
            $sessionId = $objectId;
        } elseif ('new' === $action && empty($sessionId)) {
            $sessionId = 'mautic_'.sha1(uniqid(mt_rand(), true));
            if ($this->requestStack->getCurrentRequest()->request->has('campaign')) {
                $campaign  = $this->requestStack->getCurrentRequest()->request->get('campaign') ?? [];
                $sessionId = $campaign['sessionId'] ?? $sessionId;
            }
        } elseif ('edit' === $action) {
            $sessionId = $campaign->getId();
        }

        $this->sessionId = $sessionId;

        return $sessionId;
    }

    protected function getTemplateBase(): string
    {
        return '@MauticCampaign/Campaign';
    }

    protected function getIndexItems($start, $limit, $filter, $orderBy, $orderByDir, array $args = [])
    {
        $session        = $this->getCurrentRequest()->getSession();
        $currentFilters = $session->get('mautic.campaign.list_filters', []);
        $updatedFilters = $this->requestStack->getCurrentRequest()->get('filters', false);

        $sourceLists = $this->getCampaignModel()->getSourceLists();
        $listFilters = [
            'filters' => [
                'placeholder' => $this->translator->trans('mautic.campaign.filter.placeholder'),
                'multiple'    => true,
                'groups'      => [
                    'mautic.campaign.leadsource.form' => [
                        'options' => $sourceLists['forms'],
                        'prefix'  => 'form',
                    ],
                    'mautic.campaign.leadsource.list' => [
                        'options' => $sourceLists['lists'],
                        'prefix'  => 'list',
                    ],
                ],
            ],
        ];

        if ($updatedFilters) {
            // Filters have been updated

            // Parse the selected values
            $newFilters     = [];
            $updatedFilters = json_decode($updatedFilters, true);

            if ($updatedFilters) {
                foreach ($updatedFilters as $updatedFilter) {
                    [$clmn, $fltr] = explode(':', $updatedFilter);

                    $newFilters[$clmn][] = $fltr;
                }

                $currentFilters = $newFilters;
            } else {
                $currentFilters = [];
            }
        }
        $session->set('mautic.campaign.list_filters', $currentFilters);

        $joinLists = $joinForms = false;
        if (!empty($currentFilters)) {
            $listIds = $catIds = [];
            foreach ($currentFilters as $type => $typeFilters) {
                $listFilters['filters']['groups']['mautic.campaign.leadsource.'.$type]['values'] = $typeFilters;

                foreach ($typeFilters as $fltr) {
                    if ('list' == $type) {
                        $listIds[] = (int) $fltr;
                    } else {
                        $formIds[] = (int) $fltr;
                    }
                }
            }

            if (!empty($listIds)) {
                $joinLists         = true;
                $filter['force'][] = ['column' => 'l.id', 'expr' => 'in', 'value' => $listIds];
            }

            if (!empty($formIds)) {
                $joinForms         = true;
                $filter['force'][] = ['column' => 'f.id', 'expr' => 'in', 'value' => $formIds];
            }
        }

        // Store for customizeViewArguments
        $this->listFilters = $listFilters;

        return parent::getIndexItems(
            $start,
            $limit,
            $filter,
            $orderBy,
            $orderByDir,
            [
                'joinLists' => $joinLists,
                'joinForms' => $joinForms,
            ]
        );
    }

    protected function getModelName(): string
    {
        return 'campaign';
    }

    /**
     * @return mixed[]
     */
    protected function getPostActionRedirectArguments(array $args, $action): array
    {
        switch ($action) {
            case 'new':
            case 'edit':
                if (!empty($args['entity'])) {
                    $sessionId = $this->getCampaignSessionId($args['entity'], $action);
                    $this->clearSessionComponents($sessionId);
                }
                break;
        }

        return $args;
    }

    /**
     * Get events from session.
     */
    protected function getSessionEvents($id): array
    {
        $session = $this->getCurrentRequest()->getSession();

        $modifiedEvents = $session->get('mautic.campaign.'.$id.'.events.modified', []);
        $deletedEvents  = $session->get('mautic.campaign.'.$id.'.events.deleted', []);

        $events = array_diff_key($modifiedEvents, array_flip($deletedEvents));

        return [$modifiedEvents, $deletedEvents, $events];
    }

    /**
     * Get events from session.
     */
    protected function getSessionSources($id, $isClone = false): array
    {
        $session = $this->getCurrentRequest()->getSession();

        $campaignSources = $session->get('mautic.campaign.'.$id.'.leadsources.current', []);
        $modifiedSources = $session->get('mautic.campaign.'.$id.'.leadsources.modified', []);

        if ($campaignSources === $modifiedSources) {
            if ($isClone) {
                // Clone hasn't saved the sources yet so return the current list as added
                return [$campaignSources, [], $campaignSources];
            } else {
                return [[], [], $campaignSources];
            }
        }

        // Deleted sources
        $deletedSources = [];
        foreach ($campaignSources as $type => $sources) {
            if (isset($modifiedSources[$type])) {
                $deletedSources[$type] = array_diff_key($sources, $modifiedSources[$type]);
            } else {
                $deletedSources[$type] = $sources;
            }
        }

        // Added sources
        $addedSources = [];
        foreach ($modifiedSources as $type => $sources) {
            if (isset($campaignSources[$type])) {
                $addedSources[$type] = array_diff_key($sources, $campaignSources[$type]);
            } else {
                $addedSources[$type] = $sources;
            }
        }

        return [$addedSources, $deletedSources, $modifiedSources];
    }

    /**
     * @param string $action
     *
     * @throws CacheException
     */
    protected function getViewArguments(array $args, $action): array
    {
        switch ($action) {
            case 'index':
                $args['viewParameters']['filters'] = $this->listFilters;
                break;
            case 'view':
                /** @var Campaign $entity */
                $entity   = $args['entity'];
                $objectId = $args['objectId'];
                // Init the date range filter form
                $dateRangeValues = $this->requestStack->getCurrentRequest()->get('daterange', []);
                $action          = $this->generateUrl('mautic_campaign_action', ['objectAction' => 'view', 'objectId' => $objectId]);
                $dateRangeForm   = $this->formFactory->create(DateRangeType::class, $dateRangeValues, ['action' => $action]);
                $events          = $this->getCampaignModel()->getEventRepository()->getCampaignEvents($entity->getId());
                $dateFrom        = null;
                $dateTo          = null;
                $dateToPlusOne   = null;

                if ($this->coreParametersHelper->get('campaign_by_range')) {
                    $dateFrom      = new \DateTimeImmutable($dateRangeForm->get('date_from')->getData());
                    $dateTo        = new \DateTimeImmutable($dateRangeForm->get('date_to')->getData());
                    $dateToPlusOne = $dateTo->modify('+1 day');
                }

                $leadCount = $this->getCampaignModel()->getRepository()->getCampaignLeadCount($entity->getId());
                $logCounts = $this->processCampaignLogCounts($entity->getId(), $dateFrom, $dateToPlusOne);

                $campaignLogCounts          = $logCounts['campaignLogCounts'] ?? [];
                $campaignLogCountsProcessed = $logCounts['campaignLogCountsProcessed'] ?? [];

                $this->processCampaignEvents($events, $leadCount, $campaignLogCounts, $campaignLogCountsProcessed);
                $sortedEvents = $this->processCampaignEventsFromParentCondition($events);

                $stats = $this->getCampaignModel()->getCampaignMetricsLineChartData(
                    null,
                    new \DateTime($dateRangeForm->get('date_from')->getData()),
                    new \DateTime($dateRangeForm->get('date_to')->getData()),
                    null,
                    ['campaign_id' => $objectId]
                );

                $sourcesList = $this->getCampaignModel()->getSourceLists();

                $this->prepareCampaignSourcesForEdit($objectId, $sourcesList, true);
                $this->prepareCampaignEventsForEdit($entity, $objectId, true);

                $args['viewParameters'] = array_merge(
                    $args['viewParameters'],
                    [
                        'campaign'        => $entity,
                        'stats'           => $stats,
                        'events'          => $sortedEvents,
                        'eventSettings'   => $this->eventCollector->getEventsArray(),
                        'sources'         => $this->getCampaignModel()->getLeadSources($entity),
                        'dateRangeForm'   => $dateRangeForm->createView(),
                        'campaignSources' => $this->campaignSources,
                        'campaignEvents'  => $events,
                    ]
                );
                break;
            case 'new':
            case 'edit':
                $session                = $this->getCurrentRequest()->getSession();
                $args['viewParameters'] = array_merge(
                    $args['viewParameters'],
                    [
                        'eventSettings'   => $this->eventCollector->getEventsArray(),
                        'campaignEvents'  => $this->campaignEvents,
                        'campaignSources' => $this->campaignSources,
                        'deletedEvents'   => $this->deletedEvents,
                        'hasEventClone'   => $session->has('mautic.campaign.events.clone.storage'),
                    ]
                );
                break;
        }

        return $args;
    }

    /**
     * @param bool $isClone
     *
     * @return array
     */
    protected function prepareCampaignEventsForEdit($entity, $objectId, $isClone = false)
    {
        // load existing events into session
        $campaignEvents = [];

        $existingEvents = $entity->getEvents()->toArray();
        $translator     = $this->translator;
        foreach ($existingEvents as $e) {
            $event = $e->convertToArray();

            if ($isClone) {
                $id          = $e->getTempId();
                $event['id'] = $id;
            } else {
                $id = $e->getId();
            }

            unset($event['campaign']);
            unset($event['children']);
            unset($event['parent']);
            unset($event['log']);

            $label = false;
            switch ($event['triggerMode']) {
                case 'interval':
                    $label = $translator->trans(
                        'mautic.campaign.connection.trigger.interval.label'.('no' == $event['decisionPath'] ? '_inaction' : ''),
                        [
                            '%number%' => $event['triggerInterval'],
                            '%unit%'   => $translator->trans(
                                'mautic.campaign.event.intervalunit.'.$event['triggerIntervalUnit'],
                                ['%count%' => $event['triggerInterval']]
                            ),
                        ]
                    );
                    break;
                case 'date':
                    $label = $translator->trans(
                        'mautic.campaign.connection.trigger.date.label'.('no' == $event['decisionPath'] ? '_inaction' : ''),
                        [
                            '%full%' => $this->dateHelper->toFull($event['triggerDate']),
                            '%time%' => $this->dateHelper->toTime($event['triggerDate']),
                            '%date%' => $this->dateHelper->toShort($event['triggerDate']),
                        ]
                    );
                    break;
            }
            if ($label) {
                $event['label'] = $label;
            }

            $campaignEvents[$id] = $event;
        }

        $this->modifiedEvents = $this->campaignEvents = $campaignEvents;
        $this->getCurrentRequest()->getSession()->set('mautic.campaign.'.$objectId.'.events.modified', $campaignEvents);
    }

    protected function prepareCampaignSourcesForEdit($objectId, $campaignSources, $isPost = false)
    {
        $this->campaignSources = [];
        if (is_array($campaignSources)) {
            foreach ($campaignSources as $type => $sources) {
                if (!empty($sources)) {
                    $campaignModel = $this->getModel('campaign');
                    \assert($campaignModel instanceof CampaignModel);

                    $sourceList                   = $campaignModel->getSourceLists($type);
                    $this->campaignSources[$type] = [
                        'sourceType' => $type,
                        'campaignId' => $objectId,
                        'names'      => implode(', ', array_intersect_key($sourceList, $sources)),
                    ];
                }
            }
        }

        if (!$isPost) {
            $session = $this->getCurrentRequest()->getSession();
            $session->set('mautic.campaign.'.$objectId.'.leadsources.current', $campaignSources);
            $session->set('mautic.campaign.'.$objectId.'.leadsources.modified', $campaignSources);
        }
    }

    protected function setSessionCanvasSettings($sessionId, $canvasSettings)
    {
        $this->getCurrentRequest()->getSession()->set('mautic.campaign.'.$sessionId.'.events.canvassettings', $canvasSettings);
    }

    /**
     * @return mixed
     */
    protected function getSessionCanvasSettings($sessionId)
    {
        return $this->getCurrentRequest()->getSession()->get('mautic.campaign.'.$sessionId.'.events.canvassettings');
    }

    /**
     * @return array<string, array<int|string, array<int|string, int|string>>>
     *
     * @throws CacheException
     */
    private function processCampaignLogCounts(int $id, ?\DateTimeImmutable $dateFrom, ?\DateTimeImmutable $dateToPlusOne): array
    {
        if ($this->coreParametersHelper->get('campaign_use_summary')) {
            /** @var SummaryRepository $summaryRepo */
            $summaryRepo                = $this->doctrine->getManager()->getRepository(Summary::class);
            $campaignLogCounts          = $summaryRepo->getCampaignLogCounts($id, $dateFrom, $dateToPlusOne);
            $campaignLogCountsProcessed = $this->getCampaignLogCountsProcessed($campaignLogCounts);
        } else {
            /** @var LeadEventLogRepository $eventLogRepo */
            $eventLogRepo               = $this->doctrine->getManager()->getRepository(LeadEventLog::class);
            $campaignLogCounts          = $eventLogRepo->getCampaignLogCounts($id, false, false, true, $dateFrom, $dateToPlusOne);
            $campaignLogCountsProcessed = $eventLogRepo->getCampaignLogCounts($id, false, false, false, $dateFrom, $dateToPlusOne);
        }

        return [
            'campaignLogCounts'          => $campaignLogCounts,
            'campaignLogCountsProcessed' => $campaignLogCountsProcessed,
        ];
    }

    /**
     * @param array<int, array<int|string, int|string>>        $events
     * @param array<int|string, array<int|string, int|string>> $campaignLogCounts
     * @param array<int|string, array<int|string, int|string>> $campaignLogCountsProcessed
     */
    private function processCampaignEvents(
        array &$events,
        int $leadCount,
        array $campaignLogCounts,
        array $campaignLogCountsProcessed
    ): void {
        foreach ($events as &$event) {
            $event['logCountForPending'] =
            $event['logCountProcessed']  =
            $event['percent']            =
            $event['yesPercent']         =
            $event['noPercent']          = 0;

            if (isset($campaignLogCounts[$event['id']])) {
                $loggedCount                 = array_sum($campaignLogCounts[$event['id']]);
                $logCountsProcessed          = isset($campaignLogCountsProcessed[$event['id']]) ? array_sum($campaignLogCountsProcessed[$event['id']]) : 0;
                $pending                     = $loggedCount - $logCountsProcessed;
                $event['logCountForPending'] = $pending;
                $event['logCountProcessed']  = $logCountsProcessed;
                [$totalNo, $totalYes]        = $campaignLogCounts[$event['id']];
                $total                       = $totalYes + $totalNo;

                if ($leadCount) {
                    $event['percent']    = min(100, max(0, round(($loggedCount / $total) * 100, 1)));
                    $event['yesPercent'] = min(100, max(0, round(($totalYes / $total) * 100, 1)));
                    $event['noPercent']  = min(100, max(0, round(($totalNo / $total) * 100, 1)));
                }
            }
        }
    }

    /**
     * @param array<int, array<int|string, int|string>> $events
     *
     * @return array<string, array<int, array<int|string, int|string>>>
     */
    private function processCampaignEventsFromParentCondition(array &$events): array
    {
        $sortedEvents = [
            'decision'  => [],
            'action'    => [],
            'condition' => [],
        ];

        // rewrite stats data from parent condition if exist
        foreach ($events as &$event) {
            if (!empty($event['decisionPath'])
                && !empty($event['parent_id'])
                && isset($events[$event['parent_id']])
                && 'condition' !== $event['eventType']) {
                $parentEvent                 = $events[$event['parent_id']];
                $event['percent']            = $parentEvent['percent'];
                $event['yesPercent']         = $parentEvent['yesPercent'];
                $event['noPercent']          = $parentEvent['noPercent'];
                if ('yes' === $event['decisionPath']) {
                    $event['noPercent'] = 0;
                } else {
                    $event['yesPercent'] = 0;
                }
            }
            $sortedEvents[$event['eventType']][] = $event;
        }

        return $sortedEvents;
    }

    /**
     * @param array<int, array<int, string>> $campaignLogCounts
     *
     * @return array<int, array<int, string>>
     */
    private function getCampaignLogCountsProcessed(array &$campaignLogCounts): array
    {
        $campaignLogCountsProcessed = [];

        foreach ($campaignLogCounts as $eventId => $campaignLogCount) {
            $campaignLogCountsProcessed[$eventId][] = $campaignLogCount[2];
            unset($campaignLogCounts[$eventId][2]);
        }

        return $campaignLogCountsProcessed;
    }

    protected function getDefaultOrderDirection(): string
    {
        return 'DESC';
    }
}

Spamworldpro Mini