Passed
Push — master ( bf6cf9...7d0440 )
by Alexey
03:33
created

UpdateSubscriptionsCommand::execute()   C

Complexity

Conditions 11
Paths 17

Size

Total Lines 137
Code Lines 79

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 132

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 137
ccs 0
cts 103
cp 0
rs 5.2653
cc 11
eloc 79
nc 17
nop 2
crap 132

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Skobkin\Bundle\PointToolsBundle\Command;
4
5
use Skobkin\Bundle\PointToolsBundle\Service\SubscriptionsManager;
6
use Skobkin\Bundle\PointToolsBundle\Service\UserApi;
7
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
8
use Symfony\Component\Console\Input\Input;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\Console\Output\Output;
12
use Symfony\Component\Console\Output\OutputInterface;
13
14
class UpdateSubscriptionsCommand extends ContainerAwareCommand
15
{
16
    protected function configure()
17
    {
18
        $this
19
            ->setName('point:update:subscriptions')
20
            ->setDescription('Update subscriptions of users subscribed to service')
21
            ->addOption(
22
                'all-users',
23
                null,
24
                InputOption::VALUE_NONE,
25
                'If set, command will check subscribers of all service users instead of service subscribers only'
26
            )
27
            ->addOption(
28
                'check-only',
29
                null,
30
                InputOption::VALUE_NONE,
31
                'If set, command will not perform write operations in the database'
32
            )
33
            // @todo add option for checking only selected user
34
        ;
35
    }
36
37
    /**
38
     * @param InputInterface $input
39
     * @param OutputInterface $output
40
     *
41
     * @return bool
42
     */
43
    protected function execute(InputInterface $input, OutputInterface $output)
44
    {
45
        $log = $this->getContainer()->get('logger');
46
        $em = $this->getContainer()->get('doctrine.orm.entity_manager');
47
        $userRepository = $em->getRepository('SkobkinPointToolsBundle:User');
48
49
        $log->debug('UpdateSubscriptionsCommand started.');
50
51
        /** @var UserApi $api */
52
        $api = $this->getContainer()->get('app.point.api_user');
53
        /** @var SubscriptionsManager $subscriptionsManager */
54
        $subscriptionsManager = $this->getContainer()->get('app.point.subscriptions_manager');
55
56
        try {
57
            $serviceUserId = $this->getContainer()->getParameter('point_id');
58
        } catch (\InvalidArgumentException $e) {
59
            $log->alert('Could not get point_id parameter from config file', ['exception_message' => $e->getMessage()]);
60
            return 1;
61
        }
62
63
        // Beginning transaction for all changes
64
        $em->beginTransaction();
65
66
        if ($input->getOption('all-users')) {
67
            $usersForUpdate = $userRepository->findAll();
68
        } else {
69
            $serviceUser = $userRepository->find($serviceUserId);
70
71
            if (!$serviceUser) {
72
                $log->info('Service user not found');
73
                // @todo Retrieving user
74
75
                return 1;
76
            }
77
78
            $log->info('Getting service subscribers');
79
80
            try {
81
                $usersForUpdate = $api->getUserSubscribersById($serviceUserId);
82
            } catch (\Exception $e) {
83
                $log->warning(
84
                    'Error while getting service subscribers. Fallback to local list.',
85
                    [
86
                        'user_login' => $serviceUser->getLogin(),
87
                        'user_id' => $serviceUser->getId(),
88
                        'message' => $e->getMessage(),
89
                        'file' => $e->getFile(),
90
                        'line' => $e->getLine()
91
                    ]
92
                );
93
94
                $usersForUpdate = [];
95
96
                foreach ($serviceUser->getSubscribers() as $subscription) {
97
                    $usersForUpdate[] = $subscription->getSubscriber();
98
                }
99
100
                if (!count($usersForUpdate)) {
101
                    $log->info('No local subscribers. Finishing.');
102
                    return 0;
103
                }
104
            }
105
106
            $log->debug('Updating service subscribers');
107
108
            // Updating service subscribers
109
            try {
110
                $subscriptionsManager->updateUserSubscribers($serviceUser, $usersForUpdate);
111
            } catch (\Exception $e) {
112
                $log->error(
113
                    'Error while updating service subscribers',
114
                    [
115
                        'user_login' => $serviceUser->getLogin(),
116
                        'user_id' => $serviceUser->getId(),
117
                        'message' => $e->getMessage(),
118
                        'file' => $e->getFile(),
119
                        'line' => $e->getLine()
120
                    ]
121
                );
122
123
                return 1;
124
            }
125
        }
126
127
        $log->info('Processing users subscribers');
128
129
        // Updating users subscribers
130
        foreach ($usersForUpdate as $user) {
131
            $log->info('Processing @'.$user->getLogin());
132
133
            try {
134
                $userCurrentSubscribers = $api->getUserSubscribersById($user->getId());
135
            } catch (\Exception $e) {
136
                $log->error(
137
                    'Error while getting subscribers. Skipping.',
138
                    [
139
                        'user_login' => $user->getLogin(),
140
                        'user_id' => $user->getId(),
141
                        'message' => $e->getMessage(),
142
                        'file' => $e->getFile(),
143
                        'line' => $e->getLine()
144
                    ]
145
                );
146
147
                continue;
148
            }
149
150
            $log->debug('Updating user subscribers');
151
152
            try {
153
                // Updating user subscribers
154
                $subscriptionsManager->updateUserSubscribers($user, $userCurrentSubscribers);
155
            } catch (\Exception $e) {
156
                $log->error(
157
                    'Error while updating user subscribers',
158
                    [
159
                        'user_login' => $user->getLogin(),
160
                        'user_id' => $user->getId(),
161
                        'message' => $e->getMessage(),
162
                        'file' => $e->getFile(),
163
                        'line' => $e->getLine()
164
                    ]
165
                );
166
            }
167
168
            // @todo move to the config
169
            usleep(500000);
170
        }
171
172
        // Flushing all changes at once to database
173
        $em->flush();
174
        $em->commit();
175
176
        $log->debug('Finished');
177
178
        return 0;
179
    }
180
}