Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
34 | class Application extends \Symfony\Component\Console\Application { |
||
35 | |||
36 | /** @var Container */ |
||
37 | public static $container; |
||
38 | |||
39 | /** @var Container */ |
||
40 | protected $diContainer; |
||
41 | |||
42 | /** @var array */ |
||
43 | protected $allowFailure = [ |
||
44 | 'upgrade:executeCoreUpgradeScripts', |
||
45 | 'upgrade:checkpoint', |
||
46 | 'upgrade:maintenanceMode', |
||
47 | 'help', |
||
48 | 'list' |
||
49 | ]; |
||
50 | |||
51 | /** |
||
52 | * Pass Pimple container into application |
||
53 | * @param Container $container |
||
54 | */ |
||
55 | public function setContainer(Container $container){ |
||
56 | $this->diContainer = $container; |
||
57 | self::$container = $container; |
||
58 | } |
||
59 | |||
60 | /** |
||
61 | * Get Pimple container |
||
62 | * @return Container |
||
63 | */ |
||
64 | public function getContainer(){ |
||
65 | return $this->diContainer; |
||
66 | } |
||
67 | |||
68 | /** |
||
69 | * Get logger instance |
||
70 | * @return \Psr\Log\LoggerInterface |
||
71 | */ |
||
72 | public function getLogger(){ |
||
73 | return $this->diContainer['logger']; |
||
74 | } |
||
75 | |||
76 | /** |
||
77 | * Log exception with trace |
||
78 | * @param \Exception $e |
||
79 | */ |
||
80 | public function logException($e){ |
||
81 | $buffer = new BufferedOutput(OutputInterface::VERBOSITY_VERBOSE); |
||
82 | $this->renderException($e, $buffer); |
||
83 | $this->getLogger()->error($buffer->fetch()); |
||
84 | } |
||
85 | |||
86 | public function doRun(InputInterface $input, OutputInterface $output){ |
||
87 | if (!($this->diContainer['logger.output'] instanceof StreamOutput)){ |
||
88 | $output->writeln('[Warning] Failed to init logger. Logging is disabled.'); |
||
89 | $output->writeln(CURRENT_DIR . ' is not writable'); |
||
90 | } |
||
91 | try{ |
||
92 | $configReader = $this->diContainer['utils.configReader']; |
||
93 | $commandName = $this->getCommandName($input); |
||
94 | |||
95 | try{ |
||
96 | $configReader->init(); |
||
97 | } catch (ProcessFailedException $e){ |
||
98 | if (!in_array($commandName, $this->allowFailure)){ |
||
99 | $this->logException($e); |
||
100 | $output->writeln("<error>Initialization failed with message:</error>"); |
||
101 | $output->writeln($e->getProcess()->getOutput()); |
||
102 | $output->writeln('<info>Use upgrade:checkpoint --list to view a list of checkpoints</info>'); |
||
103 | $output->writeln('<info>upgrade:checkpoint --restore [checkpointid] to revert to the last checkpoint</info>'); |
||
104 | $output->writeln('Please attach your update.log to the issues you reporting.'); |
||
105 | return 1; |
||
106 | } |
||
107 | } |
||
108 | // TODO: check if the current command needs a valid OC instance |
||
109 | $this->assertOwnCloudFound(); |
||
110 | |||
111 | return parent::doRun($input, $output); |
||
112 | } catch (\Exception $e){ |
||
113 | $this->logException($e); |
||
114 | throw $e; |
||
115 | } |
||
116 | } |
||
117 | |||
118 | protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output){ |
||
119 | if ($command instanceof \Owncloud\Updater\Command\Command){ |
||
120 | $command->setContainer($this->getContainer()); |
||
121 | $commandName = $this->getCommandName($input); |
||
122 | $this->getLogger()->info('Execution of ' . $commandName . ' command started'); |
||
123 | if (!empty($command->getMessage())){ |
||
124 | $message = sprintf('<info>%s</info>', $command->getMessage()); |
||
125 | $output->writeln($message); |
||
126 | } |
||
127 | $exitCode = parent::doRunCommand($command, $input, $output); |
||
128 | $this->getLogger()->info( |
||
129 | 'Execution of ' . $commandName . ' command stopped. Exit code is ' . $exitCode |
||
130 | ); |
||
131 | } else { |
||
132 | $exitCode = parent::doRunCommand($command, $input, $output); |
||
133 | } |
||
134 | return $exitCode; |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * Check for ownCloud instance |
||
139 | * @throws \RuntimeException |
||
140 | */ |
||
141 | protected function assertOwnCloudFound(){ |
||
142 | $container = $this->getContainer(); |
||
143 | /** @var Locator $locator */ |
||
144 | $locator = $container['utils.locator']; |
||
145 | $fsHelper = $container['utils.filesystemhelper']; |
||
146 | |||
147 | // assert minimum version |
||
148 | $installedVersion = implode('.', $locator->getInstalledVersion()); |
||
149 | if (version_compare($installedVersion, '9.0.0', '<')){ |
||
150 | throw new \RuntimeException("Minimum ownCloud version 9.0. |
||
151 | } |
||
152 | |||
153 | // has to be installed |
||
154 | $file = $locator->getPathToConfigFile(); |
||
155 | if (!file_exists($file) || !is_file($file)){ |
||
156 | throw new \RuntimeException('ownCloud in ' . dirname(dirname($file)) . ' is not installed.'); |
||
157 | } |
||
158 | |||
159 | // version.php should exist |
||
160 | $file = $locator->getPathToVersionFile(); |
||
161 | if (!file_exists($file) || !is_file($file)){ |
||
162 | throw new \RuntimeException('ownCloud is not found in ' . dirname($file)); |
||
163 | } |
||
164 | |||
165 | // datadir should exist |
||
166 | $dataDir = $locator->getDataDir(); |
||
167 | if (!$fsHelper->fileExists($dataDir)){ |
||
168 | throw new \RuntimeException('Datadirectory ' . $dataDir . ' does not exist.'); |
||
169 | } |
||
170 | |||
171 | // datadir should be writable |
||
172 | if (!$fsHelper->isWritable($dataDir)){ |
||
173 | throw new \RuntimeException('Datadirectory ' . $dataDir . ' is not writable.'); |
||
174 | } |
||
175 | |||
176 | if (!$fsHelper->fileExists($locator->getUpdaterBaseDir())){ |
||
177 | $fsHelper->mkdir($locator->getUpdaterBaseDir()); |
||
178 | } |
||
179 | |||
180 | if (!$fsHelper->fileExists($locator->getDownloadBaseDir())){ |
||
181 | $fsHelper->mkdir($locator->getDownloadBaseDir()); |
||
182 | } |
||
183 | if (!$fsHelper->fileExists($locator->getCheckpointDir())){ |
||
184 | $fsHelper->mkdir($locator->getCheckpointDir()); |
||
185 | } |
||
186 | } |
||
187 | |||
188 | } |
||
189 | |||
|