CreateCommand::execute()   F
last analyzed

Complexity

Conditions 25
Paths 116

Size

Total Lines 144
Code Lines 102

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 25
eloc 102
c 2
b 0
f 0
nc 116
nop 2
dl 0
loc 144
rs 3.2266

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 wapmorgan\UnifiedArchive\Commands;
4
5
use http\Exception\InvalidArgumentException;
6
use Symfony\Component\Console\Helper\ProgressBar;
7
use Symfony\Component\Console\Input\InputArgument;
8
use Symfony\Component\Console\Input\InputInterface;
9
use Symfony\Component\Console\Input\InputOption;
10
use Symfony\Component\Console\Output\OutputInterface;
11
use wapmorgan\UnifiedArchive\Drivers\Basic\BasicDriver;
12
use wapmorgan\UnifiedArchive\Formats;
13
use wapmorgan\UnifiedArchive\UnifiedArchive;
14
15
class CreateCommand extends BaseCommand
16
{
17
    protected static $defaultName = 'archive:create';
18
19
    protected function configure()
20
    {
21
        parent::configure();
22
        $this
23
            ->setDescription('Creates new archive')
24
            ->setHelp('Creates new archive.')
25
            ->addArgument('archive', InputArgument::REQUIRED, 'New archive filename. Type of archive will be recognized from extension')
26
            ->addArgument('file', InputArgument::IS_ARRAY | InputArgument::REQUIRED, 'Files to pack')
27
            ->addOption('password', NULL, InputOption::VALUE_REQUIRED, 'Password for new archive')
28
            ->addOption('compression', NULL, InputOption::VALUE_OPTIONAL, 'Compression level for new archive. Variants: none/weak/average/strong/maximum.', 'average')
29
            ->addOption('comment', NULL, InputOption::VALUE_OPTIONAL, 'Comment for new archive')
30
            ->addOption('path', NULL, InputOption::VALUE_OPTIONAL, 'Path resolving if destination is not passed. Variants: full/root/relative/basename', 'root')
31
            ->addOption('stdout', NULL, InputOption::VALUE_NONE, 'Print archive to stdout')
32
            ->addOption('format', NULL, InputOption::VALUE_REQUIRED, 'Format')
33
            ->addOption('dry-run', NULL, InputOption::VALUE_NONE, 'Do not perform real archiving. Just print prepared data')
34
        ;
35
    }
36
37
    protected static $compressionLevels = [
38
        'none' => BasicDriver::COMPRESSION_NONE,
39
        'weak' => BasicDriver::COMPRESSION_WEAK,
40
        'average' => BasicDriver::COMPRESSION_AVERAGE,
41
        'strong' => BasicDriver::COMPRESSION_STRONG,
42
        'maximum' => BasicDriver::COMPRESSION_MAXIMUM,
43
    ];
44
45
    /**
46
     * @throws \wapmorgan\UnifiedArchive\Exceptions\UnsupportedOperationException
47
     * @throws \wapmorgan\UnifiedArchive\Exceptions\FileAlreadyExistsException
48
     */
49
    public function execute(InputInterface $input, OutputInterface $output)
50
    {
51
        $archive_file = $input->getArgument('archive');
52
        $files_to_pack = $input->getArgument('file');
53
54
        $password = $input->getOption('password');
55
        $compression = $input->getOption('compression');
56
        if (!isset(static::$compressionLevels[$compression])) {
57
            throw new \InvalidArgumentException('Compression "' . $compression . '" is not valid');
58
        }
59
        $compression = static::$compressionLevels[$compression];
60
        $path = $input->getOption('path');
61
        if (!in_array($path, ['full', 'root', 'relative', 'basename'], true)) {
62
            throw new \InvalidArgumentException('Path can not have this value');
63
        }
64
        $dry_run = $input->getOption('dry-run');
65
        $comment = $input->getOption('comment');
66
        $stdout = $input->getOption('stdout');
67
68
        if (file_exists($archive_file)) {
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type null and string[]; however, parameter $filename of file_exists() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

68
        if (file_exists(/** @scrutinizer ignore-type */ $archive_file)) {
Loading history...
69
            if (is_dir($archive_file))
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type null and string[]; however, parameter $filename of is_dir() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

69
            if (is_dir(/** @scrutinizer ignore-type */ $archive_file))
Loading history...
70
                throw new \InvalidArgumentException($archive_file . ' is a directory!');
0 ignored issues
show
Bug introduced by
Are you sure $archive_file of type null|string|string[] can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

70
                throw new \InvalidArgumentException(/** @scrutinizer ignore-type */ $archive_file . ' is a directory!');
Loading history...
71
            else {
72
                throw new \InvalidArgumentException('File "' . $archive_file . '" already exists!');
73
            }
74
        }
75
76
        $files_list = [];
77
78
        foreach ($files_to_pack as $i => $file_to_pack) {
79
            $file_to_pack = realpath($file_to_pack);
80
            switch ($path) {
81
                case 'full':
82
                    $destination = ltrim($file_to_pack, '/');
83
                    $files_list[$destination] = $file_to_pack;
84
                    if (!$stdout) {
85
                        $output->writeln(
86
                            '<comment>' . $file_to_pack . ' => ' . $destination . '</comment>',
87
                            OutputInterface::VERBOSITY_VERBOSE
88
                        );
89
                    }
90
                    break;
91
                case 'root':
92
                    if (is_dir($file_to_pack)) {
93
                        if (!$stdout) {
94
                            $output->writeln(
95
                                '<comment>' . $file_to_pack . ' => root</comment>',
96
                                OutputInterface::VERBOSITY_VERBOSE
97
                            );
98
                        }
99
                        if (!isset($files_list[''])) {
100
                            $files_list[''] = $file_to_pack;
101
                        } elseif (is_string($files_list[''])) {
102
                            $files_list[''] = [$files_list[''], $file_to_pack];
103
                        } else {
104
                            $files_list[''][] = $file_to_pack;
105
                        }
106
                    } else {
107
                        if (!$stdout) {
108
                            $output->writeln(
109
                                '<comment>' . $file_to_pack . ' => ' . basename($file_to_pack) . '</comment>',
110
                                OutputInterface::VERBOSITY_VERBOSE
111
                            );
112
                        }
113
                        $files_list[basename($file_to_pack)] = $file_to_pack;
114
                    }
115
                    break;
116
                case 'relative':
117
                    $destination = ltrim($file_to_pack, '/.');
118
                    $files_list[$destination] = $file_to_pack;
119
                    if (!$stdout) {
120
                        $output->writeln(
121
                            '<comment>' . $file_to_pack . ' => ' . $destination . '</comment>',
122
                            OutputInterface::VERBOSITY_VERBOSE
123
                        );
124
                    }
125
                    break;
126
                case 'basename':
127
                    $destination = basename($file_to_pack);
128
                    $files_list[$destination] = $file_to_pack;
129
                    if (!$stdout) {
130
                        $output->writeln(
131
                            '<comment>' . $file_to_pack . ' => ' . $destination . '</comment>',
132
                            OutputInterface::VERBOSITY_VERBOSE
133
                        );
134
                    }
135
                    break;
136
            }
137
        }
138
139
        $information = UnifiedArchive::prepareForArchiving($files_list, $archive_file);
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type string[]; however, parameter $archiveName of wapmorgan\UnifiedArchive...::prepareForArchiving() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

139
        $information = UnifiedArchive::prepareForArchiving($files_list, /** @scrutinizer ignore-type */ $archive_file);
Loading history...
140
        if ($dry_run) {
141
            $output->writeln('Format: <info>' . $information['type'] . '</info>');
142
            $output->writeln('Original size: <info>' . implode($this->formatSize($information['totalSize'])) . '</info>');
143
            $output->writeln('Files: <info>' . $information['numberOfFiles'] . '</info>');
144
            foreach ($information['files'] as $destination => $source) {
145
                // is folder
146
                if ($source === null) {
147
                    continue;
148
                }
149
150
                $output->writeln($source . ' => <comment>' . $destination . '</comment>');
151
            }
152
            return 0;
153
        }
154
155
        ProgressBar::setFormatDefinition('archiving', '  %current%/%max% [%bar%] %percent:3s%% %elapsed:6s%: %message%');
156
157
        if ($stdout) {
158
            fwrite(STDOUT, UnifiedArchive::createInString($files_list, Formats::detectArchiveFormat($archive_file, false), $compression, $password));
0 ignored issues
show
Bug introduced by
It seems like $password can also be of type string[]; however, parameter $password of wapmorgan\UnifiedArchive...chive::createInString() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

158
            fwrite(STDOUT, UnifiedArchive::createInString($files_list, Formats::detectArchiveFormat($archive_file, false), $compression, /** @scrutinizer ignore-type */ $password));
Loading history...
Bug introduced by
It seems like $archive_file can also be of type string[]; however, parameter $originalFileName of wapmorgan\UnifiedArchive...::detectArchiveFormat() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

158
            fwrite(STDOUT, UnifiedArchive::createInString($files_list, Formats::detectArchiveFormat(/** @scrutinizer ignore-type */ $archive_file, false), $compression, $password));
Loading history...
159
            return 0;
160
        }
161
        $progressBar = new ProgressBar($output, $information['numberOfFiles']);
162
        $progressBar->setFormat('archiving');
163
        $progressBar->start();
164
        $archived_files = UnifiedArchive::create($files_list, $archive_file, $compression, $password, function ($currentFile, $totalFiles, $fsFilename, $archiveFilename)
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type string[]; however, parameter $archiveName of wapmorgan\UnifiedArchive\UnifiedArchive::create() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
        $archived_files = UnifiedArchive::create($files_list, /** @scrutinizer ignore-type */ $archive_file, $compression, $password, function ($currentFile, $totalFiles, $fsFilename, $archiveFilename)
Loading history...
Bug introduced by
It seems like $password can also be of type string[]; however, parameter $password of wapmorgan\UnifiedArchive\UnifiedArchive::create() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

164
        $archived_files = UnifiedArchive::create($files_list, $archive_file, $compression, /** @scrutinizer ignore-type */ $password, function ($currentFile, $totalFiles, $fsFilename, $archiveFilename)
Loading history...
165
        use ($progressBar) {
166
            if ($fsFilename === null) {
167
                $progressBar->setMessage('Creating ' . $archiveFilename);
168
            } else {
169
                $progressBar->setMessage($fsFilename);
170
            }
171
            $progressBar->advance();
172
        });
173
        $progressBar->finish();
174
        $progressBar->clear();
175
        $output->writeln('');
176
177
        if (!$archived_files) {
178
            throw new \RuntimeException('archiveFiles result is false');
179
        }
180
181
        $archive = $this->open($archive_file);
182
        if (!empty($comment)) {
183
            $archive->setComment($comment);
0 ignored issues
show
Bug introduced by
It seems like $comment can also be of type string[]; however, parameter $comment of wapmorgan\UnifiedArchive...edArchive::setComment() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

183
            $archive->setComment(/** @scrutinizer ignore-type */ $comment);
Loading history...
184
        }
185
186
        $output->writeln(
187
            'Created <info>' . $archive_file . '</info> with <comment>' . $archived_files . '</comment> file(s) ('
188
            . implode($this->formatSize($archive->getOriginalSize())) . ') of total size '
189
            . implode($this->formatSize(filesize($archive_file)))
0 ignored issues
show
Bug introduced by
It seems like $archive_file can also be of type null and string[]; however, parameter $filename of filesize() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

189
            . implode($this->formatSize(filesize(/** @scrutinizer ignore-type */ $archive_file)))
Loading history...
190
        );
191
192
        return 0;
193
    }
194
}
195