RetrieveBackupCommand::execute()   D
last analyzed

Complexity

Conditions 13
Paths 171

Size

Total Lines 121
Code Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 75
nc 171
nop 2
dl 0
loc 121
rs 4.6605
c 0
b 0
f 0

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
 * Created by PhpStorm.
4
 * User: nicolas
5
 * Date: 14/02/17
6
 * Time: 19:41
7
 */
8
9
namespace Devgiants\Command;
10
11
use Devgiants\Configuration\ApplicationConfiguration as AppConf;
12
use Devgiants\Configuration\ConfigurationManager;
13
use Devgiants\Model\ApplicationCommand;
14
use Devgiants\Service\BackupTools;
15
use Monolog\Handler\RotatingFileHandler;
0 ignored issues
show
Bug introduced by
The type Monolog\Handler\RotatingFileHandler was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Monolog\Logger;
0 ignored issues
show
Bug introduced by
The type Monolog\Logger was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Pimple\Container;
0 ignored issues
show
Bug introduced by
The type Pimple\Container was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Symfony\Component\Console\Command\Command;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Command\Command was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Symfony\Component\Console\Exception\InvalidArgumentException;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Consol...nvalidArgumentException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
20
use Symfony\Component\Console\Input\InputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Input\InputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use Symfony\Component\Console\Input\InputOption;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Input\InputOption was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use Symfony\Component\Console\Output\OutputInterface;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Output\OutputInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use Symfony\Component\Console\Question\ChoiceQuestion;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Console\Question\ChoiceQuestion was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
24
use Symfony\Component\Filesystem\Filesystem;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Filesystem\Filesystem was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
25
use Symfony\Component\Yaml\Yaml;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Yaml\Yaml was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
26
27
class RetrieveBackupCommand extends ApplicationCommand {
28
	const STORAGE_OPTION = 'storage';
29
30
31
	/**
32
	 * RetrieveBackupCommand constructor.
33
	 *
34
	 * @param null|string $name
35
	 * @param Container $container
36
	 */
37
	public function __construct( $name, Container $container ) {
38
		parent::__construct( $name, $container );
39
	}
40
41
	/**
42
	 * @inheritdoc
43
	 */
44
	protected function configure() {
45
		$this
46
			->setName( 'retrieve' )
47
			->setDescription( 'Retrieve sites backup accordingly to the YML configuration file and storage key chosen in backup configuration' )
48
			->setHelp( "This command allows you to retrieve sites backup on /tmp folder" )
49
			->addOption( BackupCommand::FILE_OPTION, "f", InputOption::VALUE_REQUIRED, "The YML configuration file" )
50
			->addOption( self::STORAGE_OPTION, "s", InputOption::VALUE_OPTIONAL, "The storage key in configuration file to retrieve backups from" );
51
	}
52
53
	/**
54
	 * @inheritdoc
55
	 */
56
	protected function execute( InputInterface $input, OutputInterface $output ) {
57
		// Get conf file
58
		$ymlFile    = $input->getOption( BackupCommand::FILE_OPTION );
59
		$storageKey = $input->getOption( static::STORAGE_OPTION );
60
61
62
		if ( $ymlFile !== null && is_file( $ymlFile ) ) {
63
			try {
64
65
				// Structures check and configuration loading
66
				$configurationManager = new ConfigurationManager( $ymlFile );
67
				$configuration        = $configurationManager->load();
68
69
70
				// Defines 1 handler
71
				$this->log
72
					->pushHandler( new RotatingFileHandler(
73
							"{$configuration[AppConf::LOG_NODE[AppConf::NODE_NAME]]}/main.log",
74
							Logger::DEBUG )
75
					);
76
77
				$this->log->addDebug( "" );
78
				$this->log->addDebug( "----- START RETRIEVE SESSION -----" );
79
80
				// If storageKey not provided, start question
81
				if ( null === $storageKey ) {
82
					$this->log->addDebug( "No storage key provided, start question" );
83
					$storageKeysAvailable = [];
84
85
					foreach ( $configuration[ AppConf::BACKUP_STORAGES ] as $storageKeyAvailable => $storage ) {
86
						$storageKeysAvailable[] = $storageKeyAvailable;
87
					}
88
					$this->log->addDebug( "Storages keys available", [ 'storages' => $storageKeysAvailable ] );
89
					$helper   = $this->getHelper( 'question' );
90
					$question = new ChoiceQuestion(
91
						'Please select the storage retrieve backup from',
92
						$storageKeysAvailable,
93
						0
94
					);
95
					$question->setErrorMessage( 'Storage %s is invalid.' );
96
					$storageKey = $helper->ask( $input, $output, $question );
97
				} else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
98
					// TODO handle
99
				}
100
101
				// Try to retrieve storage key
102
				if ( isset( $configuration[ AppConf::BACKUP_STORAGES ][ $storageKey ] ) && $currentStorageData = $configuration[ AppConf::BACKUP_STORAGES ][ $storageKey ] ) {
103
					$currentStorage = $this->tools->getStorageByType( $currentStorageData );
104
					$this->log->addDebug( "Storage populated" );
105
106
					$currentStorage->connect();
107
108
					// Get sites list from root dir. No params in this case
109
					$sitesBackuped = $currentStorage->getItemsList( $currentStorageData[ AppConf::ROOT_DIR ] );
110
					$this->log->addDebug( "Backuped sites list", [ 'sites' => $sitesBackuped ] );
111
112
					if ( is_array( $sitesBackuped ) && count( $sitesBackuped ) > 0 ) {
113
						$helper   = $this->getHelper( 'question' );
114
						$question = new ChoiceQuestion(
115
							'Please select the site you want retrieve backup from',
116
							$sitesBackuped,
117
							0
118
						);
119
						$question->setErrorMessage( 'Site %s is invalid.' );
120
						$siteChosen = $helper->ask( $input, $output, $question );
121
						$this->log->addDebug( "Site chosen : {$siteChosen}" );
122
123
						// Get backups. pass root dir for complete path
124
						$backups = $currentStorage->getItemsList( $siteChosen, [ 'root_dir' => $currentStorageData[ AppConf::ROOT_DIR ] ] );
125
						$this->log->addDebug( "Backups available", [ 'backup' => $backups ] );
126
127
						$helper   = $this->getHelper( 'question' );
128
						$question = new ChoiceQuestion(
129
							'Please select the backup you want to retrieve',
130
							$backups,
131
							0
132
						);
133
						$question->setErrorMessage( 'Site %s is invalid.' );
134
						$backupChosen = $helper->ask( $input, $output, $question );
135
						$this->log->addDebug( "Backup chosen : {$backupChosen}" );
136
137
						// TODO add retrieve folder option
138
						$fs = new Filesystem();
139
140
						if ( strpos( $backupChosen, $currentStorageData[ AppConf::ROOT_DIR ] ) !== false ) {
141
							$tempRootDir = "/tmp{$backupChosen}";
142
						} else {
143
							$tempRootDir = "/tmp/{$siteChosen}/{$backupChosen}";
144
						}
145
						if ( $fs->exists( $tempRootDir ) ) {
146
							$this->log->addDebug( "Temp dir {$tempRootDir} exists, kill it." );
147
							$fs->remove( $tempRootDir );
148
						}
149
						$fs->mkdir( $tempRootDir );
150
151
						// Get items. pass root dir + site chosen for complete path
152
						foreach ( $currentStorage->getItemsList( $backupChosen, [ 'root_dir' => "{$currentStorageData[ AppConf::ROOT_DIR ]}/{$siteChosen}" ] ) as $remoteFile ) {
153
							$name = pathinfo( $remoteFile, PATHINFO_BASENAME );
154
							$this->log->addDebug( "Start retrieving {$name}, storing it at <comment>{$tempRootDir}/{$name}" );
155
							$output->write( "Start retrieving for <info>{$name}</info> file, storing it at <comment>{$tempRootDir}/{$name}</comment>..." );
156
							$currentStorage->get( $remoteFile, "{$tempRootDir}/{$name}", [ 'root_dir' => "{$currentStorageData[ AppConf::ROOT_DIR ]}/{$siteChosen}/{$backupChosen}" ] );
157
							$this->log->addDebug( "Done" );
158
							$output->write( "<info> DONE</info>" . PHP_EOL );
159
						}
160
						$output->writeln( "" );
161
						$output->writeln( "<info>Backup is retrieved.</info>" );
162
					}
163
				} else {
164
					$this->log->addDebug( "Storage empty, no sites. abort." );
165
				}
166
167
			} catch ( \Exception $e ) {
168
				$output->writeln( "<error>Error happened : {$e->getMessage()}</error>" );
169
				$this->tools->maximumDetailsErrorHandling( $output, $this->log, $e );
170
			}
171
		} else {
172
			$output->writeln( "<error>Filename is not correct : {$ymlFile}</error>" );
173
			$this->log->addError( "Filename is not correct : {$ymlFile}" );
174
		}
175
176
		$this->log->addDebug( "----- END RETRIEVE SESSION -----" );
177
	}
178
}