PurgePadCommand::execute()   F
last analyzed

Complexity

Conditions 20
Paths 530

Size

Total Lines 105

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 105
rs 0.5222
c 0
b 0
f 0
cc 20
nc 530
nop 2

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 EtherpadLite\Console\Command;
4
5
use DateInterval;
6
use DateTime;
7
use EtherpadLite\Helper\Pad;
8
use Exception;
9
use Symfony\Component\Console\Command\Command;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Input\InputOption;
12
use Symfony\Component\Console\Output\OutputInterface;
13
14
class PurgePadCommand extends Command
15
{
16
    /** @var string */
17
    protected $dateFormat = 'Y-m-d H:i:s';
18
    /** @var null|DateTime */
19
    protected $threshold = null;
20
    /** @var int */
21
    protected $countPads = 0;
22
    /** @var int */
23
    protected $countPadsFailed = 0;
24
    /** @var int */
25
    protected $countPadsDeleted = 0;
26
27
    protected function configure()
28
    {
29
        $this->setName('pad:purge')
30
            ->setDescription('Purge pads older than x days')
31
            ->setDefinition(
32
                array(
33
                    new InputOption('apikey', null, InputOption::VALUE_REQUIRED, 'The API Key of your Etherpad Instance'),
34
                    new InputOption('days', null, InputOption::VALUE_OPTIONAL, 'Days after Pads will deleted', '30'),
35
                    new InputOption('suffix', null, InputOption::VALUE_OPTIONAL, 'Only delete pads with this suffix', null),
36
                    new InputOption('ignore-suffix', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Ignore pads with this suffix', []),
37
                    new InputOption('host', null, InputOption::VALUE_OPTIONAL, 'The HTTP Address of your Etherpad Instance', 'http://localhost:9001'),
38
                    new InputOption('dry-run', 'd', InputOption::VALUE_NONE, ''),
39
                )
40
            );
41
    }
42
43
    protected function execute(InputInterface $input, OutputInterface $output)
44
    {
45
        $this->setThreshold($input->getOption('days'));
46
47
        $suffix = $input->getOption('suffix');
48
        $ignoreSuffixes = $input->getOption('ignore-suffix');
49
50
        $suffixRegex = sprintf('/%s$/', $suffix);
51
        $ignoreSuffixesRegex = sprintf('/(%s)$/', join('|', $ignoreSuffixes));
52
53
        if ($input->getOption('dry-run')) {
54
            $output->writeln('<info>This is a dry-run run, no pad will deleted.</info>');
55
        }
56
57
        if ($output->isVerbose()) {
58
            $output->writeln(
59
                sprintf('<info>INFO:</info> Pads before %s will be deleted', $this->threshold->format($this->dateFormat))
60
            );
61
            if (null !== $suffix) {
62
                $output->writeln(
63
                    sprintf('<info>INFO:</info> Only pads ending with suffix \'%s\' will be deleted', $suffix)
64
                );
65
            }
66
            if (!empty($ignoreSuffixes)) {
67
                $output->writeln(
68
                    sprintf('<info>INFO:</info> Pads ending with suffixes \'%s\' will be ignored', join('\', \'', $ignoreSuffixes))
69
                );
70
            }
71
        }
72
73
        $padIds = $this->getAllPads($input->getOption('apikey'), $input->getOption('host'));
74
75
        if ($padIds === false) {
76
            $output->writeln('<error>Could not receive all pads.</error>');
77
78
            return 0;
79
        }
80
81
        if ($output->isVerbose()) {
82
            $output->writeln(
83
                sprintf('<info>INFO:</info> %s pad(s) stored', $this->countPads)
84
            );
85
        }
86
87
        foreach ($padIds as $padId) {
88
            if (null !== $suffix && !preg_match($suffixRegex, $padId)) {
89
                if ($output->isDebug()) {
90
                    $output->writeln(
91
                        sprintf('<info>DEBUG:</info> "%s" will be ignored as it doesn\'t match suffix', $padId)
92
                    );
93
                }
94
                continue;
95
            }
96
            if (!empty($ignoreSuffixes) && preg_match($ignoreSuffixesRegex, $padId)) {
97
                if ($output->isDebug()) {
98
                    $output->writeln(
99
                        sprintf('<info>DEBUG:</info> "%s" will be ignored as it matches an ignore-suffix', $padId)
100
                    );
101
                }
102
                continue;
103
            }
104
105
            $lastEdited = Pad::getLastEdited(
106
                $padId,
107
                $input->getOption('apikey'),
108
                $input->getOption('host')
109
            );
110
111
            if ($lastEdited === false) {
112
                $this->countPadsFailed++;
113
                continue;
114
            }
115
116
            if ($lastEdited < $this->threshold->getTimestamp()) {
117
                if ($output->isDebug()) {
118
                    $output->writeln(
119
                        sprintf(
120
                            '<info>DEBUG:</info> "%s" was last edited on %s and will purged',
121
                            $padId,
122
                            date($this->dateFormat, $lastEdited)
123
                        )
124
                    );
125
                }
126
127
                if (!$input->getOption('dry-run')) {
128
                    if (!Pad::deletePad(
129
                        $padId,
130
                        $input->getOption('apikey'),
131
                        $input->getOption('host')
132
                    )) {
133
                        $this->countPadsFailed++;
134
                    }
135
                }
136
137
                $this->countPadsDeleted++;
138
            }
139
        }
140
141
        if ($output->isVerbose()) {
142
            $output->writeln(sprintf('<info>INFO:</info> %s pad(s) deleted', $this->countPadsDeleted));
143
            $output->writeln(sprintf('<info>INFO:</info> %s pad(s) failed', $this->countPadsFailed));
144
        }
145
146
        return 0;
147
    }
148
149
    /**
150
     * @param $days
151
     * @throws Exception
152
     */
153
    private function setThreshold($days)
154
    {
155
        $this->threshold = new DateTime();
156
        $this->threshold->sub(
157
            new DateInterval(
158
                sprintf('P%sD', $days)
159
            )
160
        );
161
    }
162
163
    /**
164
     * @param $apikey
165
     * @param $host
166
     * @return array
167
     * @throws Exception
168
     */
169
    private function getAllPads($apikey, $host)
170
    {
171
        $pads = Pad::getAllPadIds($apikey, $host);
172
173
        $this->countPads = count($pads);
174
175
        return $pads;
176
    }
177
}
178