MailChimpUpdateParticipantsListCommand   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 95
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
c 1
b 0
f 0
lcom 0
cbo 9
dl 0
loc 95
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A configure() 0 7 1
C execute() 0 69 8
A toBatch() 0 9 2
1
<?php
2
3
/**
4
 * @author    Markus Tacker <[email protected]>
5
 * @copyright 2013-2016 Verein zur Förderung der Netzkultur im Rhein-Main-Gebiet e.V. | http://netzkultur-rheinmain.de/
6
 */
7
8
namespace BCRM\BackendBundle\Command;
9
10
use BCRM\BackendBundle\Entity\Event\EventRepository;
11
use BCRM\BackendBundle\Entity\Event\TicketRepository;
12
use BCRM\BackendBundle\Exception\CommandException;
13
use Coderbyheart\MailChimpBundle\Exception\BadMethodCallException;
14
use Coderbyheart\MailChimpBundle\MailChimp\Api as MailChimpApi;
15
use Doctrine\Common\Collections\ArrayCollection;
16
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
17
use Symfony\Component\Console\Input\InputArgument;
18
use Symfony\Component\Console\Input\InputInterface;
19
use Symfony\Component\Console\Output\OutputInterface;
20
21
class MailChimpUpdateParticipantsListCommand extends ContainerAwareCommand
22
{
23
    protected function configure()
24
    {
25
        $this
26
            ->setName('bcrm:mailchimp:update-participants-list')
27
            ->setDescription('Updates the given list to reflect the participants for the given event')
28
            ->addArgument('list', InputArgument::REQUIRED, 'MailChimp list identifier');
29
    }
30
31
    protected function execute(InputInterface $input, OutputInterface $output)
32
    {
33
        /* @var MailChimpApi $mailchimp */
34
        /* @var TicketRepository $ticketRepo */
35
        /* @var EventRepository $eventRepo */
36
        $mailchimp = $this->getContainer()->get('mailchimp');
37
38
        // There is no "clear subscribers" api endpoint, so we have to batch unsubscribe the non-participants
39
40
        $output->writeln('Fetching subscribers …');
41
        $subscribers = new ArrayCollection();
42
        $page        = 0;
43
        do {
44
            $result = $mailchimp->listsMembers(
45
                array(
46
                    'id'   => $input->getArgument('list'),
47
                    'opts' => array(
48
                        'start' => $page++
49
                    )
50
                )
51
            );
52
            foreach ($result->data as $subscriber) {
53
                $subscribers->add(strtolower($subscriber->email));
54
            }
55
        } while (count($result->data) > 0);
56
        $output->writeln(sprintf("%d subscribers in list.", $subscribers->count()));
57
58
        $eventRepo    = $this->getContainer()->get('bcrm.backend.repo.event');
59
        $ticketRepo   = $this->getContainer()->get('bcrm.backend.repo.ticket');
60
        $participants = new ArrayCollection();
61
        foreach ($ticketRepo->getTicketsForEvent($eventRepo->getNextEvent()->getOrThrow(
62
            new BadMethodCallException('No event.')
63
        )) as $ticket) {
64
            if ($participants->contains(strtolower($ticket->getEmail()))) continue;
65
            $participants->add(strtolower($ticket->getEmail()));
66
        }
67
68
        // Unsubscribe former participants
69
        $unsubscribe = new ArrayCollection(array_diff($subscribers->toArray(), $participants->toArray()));
70
        $output->writeln(sprintf('Unsubscribing %d participants.', $unsubscribe->count()));
71
        $result = $mailchimp->listsBatch_unsubscribe(
72
            array(
73
                'id'            => $input->getArgument('list'),
74
                'batch'         => $this->toBatch($unsubscribe, false),
75
                'delete_member' => true,
76
                'send_goodbye'  => false,
77
            )
78
        );
79
        if ($output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG) {
80
            $output->writeln(print_r($result, true));
81
        }
82
        if ($result->error_count > 0) {
83
            throw new CommandException(sprintf('Failed to unsubscribe %d participants!', $result->error_count));
84
        }
85
86
        // Subscribe new participiants
87
        $newSubcsribers = new ArrayCollection(array_diff($participants->toArray(), $subscribers->toArray()));
88
        $output->writeln(sprintf('Subscribing %d new participants.', $newSubcsribers->count()));
89
        $result = $mailchimp->listsBatch_subscribe(
90
            array(
91
                'id'           => $input->getArgument('list'),
92
                'batch'        => $this->toBatch($newSubcsribers),
93
                'double_optin' => false
94
            )
95
        );
96
        if ($output->getVerbosity() >= OutputInterface::VERBOSITY_DEBUG) {
97
            $output->writeln(print_r($result, true));
98
        }
99
    }
100
101
    /**
102
     * @param ArrayCollection $emails
103
     *
104
     * @return string[]
105
     */
106
    protected function toBatch(ArrayCollection $emails, $deep = true)
107
    {
108
        return $emails->map(function ($email) use($deep) {
109
            return array(
110
                'email'      => $deep ? array('email' => $email) : $email,
111
                'email_type' => 'html'
112
            );
113
        })->toArray();
114
    }
115
}
116