MailAdmin::addUsersToEmail()   A
last analyzed

Complexity

Conditions 6
Paths 4

Size

Total Lines 24
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 24
rs 9.1111
c 0
b 0
f 0
cc 6
nc 4
nop 2
1
<?php
2
3
namespace Stfalcon\Bundle\EventBundle\Admin;
4
5
use Application\Bundle\UserBundle\Entity\User;
6
use Doctrine\Common\Collections\ArrayCollection;
7
use Doctrine\ORM\UnitOfWork;
8
use Sonata\AdminBundle\Admin\AbstractAdmin;
9
use Sonata\AdminBundle\Admin\AdminInterface;
10
use Sonata\AdminBundle\Form\FormMapper;
11
use Sonata\AdminBundle\Datagrid\ListMapper;
12
use Sonata\AdminBundle\Route\RouteCollection;
13
use Knp\Menu\ItemInterface as MenuItemInterface;
14
use Stfalcon\Bundle\EventBundle\Entity\EventAudience;
15
use Stfalcon\Bundle\EventBundle\Entity\MailQueue;
16
use Stfalcon\Bundle\EventBundle\Entity\Mail;
17
18
/**
19
 * Class MailAdmin.
20
 */
21
final class MailAdmin extends AbstractAdmin
22
{
23
    private $savedEvents;
24
    private $savedAudiences;
25
    /**
26
     * Default values to the datagrid.
27
     *
28
     * @var array
29
     */
30
    protected $datagridValues = array(
31
        '_sort_by' => 'id',
32
        '_sort_order' => 'DESC',
33
    );
34
35
    /**
36
     * @return array
37
     */
38
    public function getBatchActions()
39
    {
40
        return array();
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function postPersist($mail)
47
    {
48
        $users = $this->getUsersForEmail($mail);
49
50
        $this->addUsersToEmail($mail, $users);
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function preUpdate($object)
57
    {
58
        /** @var Mail $object */
59
        $container = $this->getConfigurationPool()->getContainer();
60
        $em = $container->get('doctrine')->getManager();
61
        /** @var UnitOfWork $uow */
62
        $uow = $em->getUnitOfWork();
63
        $originalObject = $uow->getOriginalEntityData($object);
64
65
        $eventsChange = count($this->savedEvents) !== $object->getEvents()->count();
66
        $audiencesChange = count($this->savedAudiences) !== $object->getAudiences()->count();
67
68
        if (!$eventsChange) {
69
            foreach ($this->savedEvents as $savedEvent) {
70
                $founded = false;
71
                foreach ($object->getEvents() as $event) {
72
                    $founded = $savedEvent === $event->getId();
73
                    if ($founded) {
74
                        break;
75
                    }
76
                }
77
                $eventsChange = !$founded;
78
                if ($eventsChange) {
79
                    break;
80
                }
81
            }
82
        }
83
84
        if (!$audiencesChange) {
85
            foreach ($this->savedAudiences as $savedAudience) {
86
                $founded = false;
87
                /** @var EventAudience $audience */
88
                foreach ($object->getAudiences() as $audience) {
89
                    $founded = $savedAudience === $audience->getId();
90
                    if ($founded) {
91
                        break;
92
                    }
93
                }
94
                $audiencesChange = !$founded;
95
                if ($audiencesChange) {
96
                    break;
97
                }
98
            }
99
        }
100
101
        if ($eventsChange ||
102
            $audiencesChange ||
103
            $originalObject['wantsVisitEvent'] !== $object->isWantsVisitEvent() ||
104
            $originalObject['paymentStatus'] !== $object->getPaymentStatus()
105
        ) {
106
            $objectStatus = $object->getStart();
107
            if (true === $objectStatus) {
108
                $object->setStart(false);
109
                $em->flush();
110
            }
111
            /** @var $queueRepository \Stfalcon\Bundle\EventBundle\Repository\MailQueueRepository */
112
            $queueRepository = $em->getRepository('StfalconEventBundle:MailQueue');
113
            $deleteCount = $queueRepository->deleteAllNotSentMessages($object);
114
            $object->setTotalMessages($object->getTotalMessages() - $deleteCount);
115
            $usersInMail = $em->getRepository('ApplicationUserBundle:User')->getUsersFromMail($object);
116
            $newUsers = $this->getUsersForEmail($object);
117
            $addUsers = array_diff($newUsers, $usersInMail);
118
119
            $this->addUsersToEmail($object, $addUsers);
120
121
            if (true === $objectStatus) {
122
                $object->setStart(true);
123
                $em->flush();
124
            }
125
        }
126
    }
127
128
    /**
129
     * @param RouteCollection $collection
130
     */
131
    protected function configureRoutes(RouteCollection $collection)
132
    {
133
        $collection->add('admin_send', $this->getRouterIdParameter().'/admin-send');
134
        $collection->add('user_send', 'user-send');
135
    }
136
137
    /**
138
     * @param ListMapper $listMapper
139
     */
140
    protected function configureListFields(ListMapper $listMapper)
141
    {
142
        $listMapper
143
            ->addIdentifier('id', null, ['label' => 'id'])
144
            ->addIdentifier('title', null, ['label' => 'Название'])
145
            ->add('statistic', 'string', ['label' => 'всего/отправлено/открыли/отписались'])
146
            ->add('audiences', null, ['label' => 'Аудитории'])
147
            ->add('events', null, ['label' => 'События'])
148
            ->add('_action', 'actions', [
149
                'label' => 'Действие',
150
                'actions' => [
151
                    'edit' => [],
152
                    'delete' => [],
153
                    'ispremium' => [
154
                        'template' => 'StfalconEventBundle:Admin:list__action_adminsend.html.twig',
155
                    ],
156
                    'start' => [
157
                        'template' => 'StfalconEventBundle:Admin:list__action_start.html.twig',
158
                    ],
159
                ],
160
            ]);
161
    }
162
163
    /**
164
     * @param FormMapper $formMapper
165
     */
166
    protected function configureFormFields(FormMapper $formMapper)
167
    {
168
        /** @var Mail $object */
169
        $object = $this->getSubject();
170
        $isEdit = (bool) $object->getId();
171
        $this->savedEvents = [];
172
        foreach ($object->getEvents() as $event) {
173
            $this->savedEvents[] = $event->getId();
174
        }
175
        $this->savedAudiences = [];
176
        foreach ($object->getAudiences() as $audience) {
177
            $this->savedAudiences[] = $audience->getId();
178
        }
179
180
        $formMapper
181
            ->with('Общие')
182
                ->add('title', null, ['label' => 'Название'])
183
                ->add('text', null, ['label' => 'Текст'])
184
                ->add('audiences', null, ['label' => 'Аудитории'])
185
                ->add('events', 'entity', [
186
                    'class' => 'Stfalcon\Bundle\EventBundle\Entity\Event',
187
                    'multiple' => true,
188
                    'expanded' => false,
189
                    'required' => false,
190
                    'read_only' => $isEdit,
191
                    'label' => 'События',
192
                ])
193
                ->add('start', null, ['required' => false, 'label' => 'Запустить'])
194
                ->add('wantsVisitEvent', null, ['label' => 'Подписанным на события', 'required' => false])
195
                ->add('paymentStatus', 'choice', array(
196
                    'choices' => array(
197
                        'paid' => 'Оплачено',
198
                        'pending' => 'Не оплачено',
199
                    ),
200
                    'required' => false,
201
                    'read_only' => $isEdit,
202
                    'label' => 'Статус оплаты',
203
                ))
204
            ->end();
205
    }
206
207
    /**
208
     * @param MenuItemInterface $menu       Menu
209
     * @param string            $action     Action
210
     * @param AdminInterface    $childAdmin Child admin
211
     */
212
    protected function configureSideMenu(MenuItemInterface $menu, $action, AdminInterface $childAdmin = null)
213
    {
214
        if (!$childAdmin && !in_array($action, array('edit', 'show'))) {
215
            return;
216
        }
217
218
        $admin = $this->isChild() ? $this->getParent() : $this;
219
        $id = $admin->getRequest()->get('id');
220
221
        $menu->addChild('Mail', array('uri' => $admin->generateUrl('edit', array('id' => $id))));
222
        $menu->addChild('Line items', array('uri' => $admin->generateUrl('stfalcon_event.admin.mail_queue.list', array('id' => $id))));
223
    }
224
225
    /**
226
     * @param Mail $mail
227
     *
228
     * @return array
229
     */
230
    private function getUsersForEmail($mail)
231
    {
232
        $container = $this->getConfigurationPool()->getContainer();
233
234
        $eventCollection = $mail->getEvents()->toArray();
235
236
        /** @var EventAudience $audience */
237
        foreach ($mail->getAudiences() as $audience) {
238
            $eventCollection = array_merge($eventCollection, $audience->getEvents()->toArray());
239
        }
240
        $events = [];
241
        foreach ($eventCollection as $event) {
242
            $events[$event->getId()] = $event;
243
        }
244
        $events = new ArrayCollection($events);
245
        /** @var \Doctrine\ORM\EntityManager $em */
246
        $em = $container->get('doctrine')->getManager();
247
        if ($events->count() > 0 && $mail->isWantsVisitEvent()) {
248
            $users = $em->getRepository('ApplicationUserBundle:User')->getRegisteredUsers($events);
249
        } elseif ($events->count() > 0 || $mail->getPaymentStatus()) {
250
            $users = $em->getRepository('StfalconEventBundle:Ticket')
251
                ->findUsersSubscribedByEventsAndStatus($events, $mail->getPaymentStatus());
252
        } else {
253
            $users = $em->getRepository('ApplicationUserBundle:User')->getAllSubscribed();
254
        }
255
256
        return $users;
257
    }
258
259
    /**
260
     * @param Mail  $mail
261
     * @param array $users
262
     *
263
     * @throws \Doctrine\ORM\OptimisticLockException
264
     */
265
    private function addUsersToEmail($mail, $users)
266
    {
267
        $container = $this->getConfigurationPool()->getContainer();
268
        /** @var \Doctrine\ORM\EntityManager $em */
269
        $em = $container->get('doctrine')->getManager();
270
271
        if (isset($users)) {
272
            $countSubscribers = $mail->getTotalMessages();
273
            /** @var User $user */
274
            foreach ($users as $user) {
275
                if (filter_var($user->getEmail(), FILTER_VALIDATE_EMAIL) &&
276
                    $user->isEnabled() &&
277
                    $user->isEmailExists()
278
                ) {
279
                    $mailQueue = new MailQueue();
280
                    $mailQueue->setUser($user);
281
                    $mailQueue->setMail($mail);
282
                    $em->persist($mailQueue);
283
                    ++$countSubscribers;
284
                }
285
            }
286
            $mail->setTotalMessages($countSubscribers);
287
            $em->persist($mail);
288
            $em->flush();
289
        }
290
    }
291
}
292