Completed
Push — master ( 8b2998...70f6fb )
by Sebastian
02:49
created

Cmd::handleArgs()   C

Complexity

Conditions 16
Paths 16

Size

Total Lines 41
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
dl 0
loc 41
rs 5.0151
c 2
b 0
f 1
cc 16
eloc 37
nc 16
nop 1

How to fix   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
 * phpbu
4
 *
5
 * Copyright (c) 2014 - 2016 Sebastian Feldmann <[email protected]>
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 *
25
 * @package    phpbu
26
 * @author     Sebastian Feldmann <[email protected]>
27
 * @copyright  Sebastian Feldmann
28
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
29
 * @link       http://phpbu.de/
30
 * @since      Class available since Release 1.0.0
31
 */
32
namespace phpbu\App;
33
34
use Phar;
35
use phpbu\App\Cmd\Args;
36
use phpbu\App\Util\Arr;
37
38
/**
39
 * Main application class.
40
 *
41
 * @package    phpbu
42
 * @author     Sebastian Feldmann <[email protected]>
43
 * @copyright  Sebastian Feldmann <[email protected]>
44
 * @license    https://opensource.org/licenses/MIT The MIT License (MIT)
45
 * @link       http://phpbu.de/
46
 * @since      Class available since Release 1.0.0
47
 */
48
class Cmd
49
{
50
    const EXIT_SUCCESS   = 0;
51
    const EXIT_FAILURE   = 1;
52
    const EXIT_EXCEPTION = 2;
53
54
    /**
55
     * Ascii-Art app logo
56
     *
57
     * @var string
58
     */
59
    private static $logo = '             __          __
60
      ____  / /_  ____  / /_  __  __
61
     / __ \/ __ \/ __ \/ __ \/ / / /
62
    / /_/ / / / / /_/ / /_/ / /_/ /
63
   / .___/_/ /_/ .___/_.___/\__,_/
64
  /_/         /_/
65
';
66
67
    /**
68
     * Is cmd executed from phar.
69
     *
70
     * @var boolean
71
     */
72
    private $isPhar;
73
74
    /**
75
     * Is version string printed already.
76
     *
77
     * @var boolean
78
     */
79
    private $isVersionStringPrinted = false;
80
81
    /**
82
     * List of given arguments
83
     *
84
     * @var array
85
     */
86
    private $arguments;
87
88
    /**
89
     * Runs the application.
90
     *
91
     * @param array $args
92
     */
93
    public function run(array $args)
94
    {
95
        $this->isPhar = defined('__PHPBU_PHAR__');
96
        $this->handleOpt($args);
97
        $this->findConfiguration();
98
99
        $ret    = self::EXIT_FAILURE;
100
        $runner = new Runner(new Factory());
101
102
        try {
103
            $result = $runner->run($this->createConfiguration());
104
105
            if ($result->wasSuccessful()) {
106
                $ret = self::EXIT_SUCCESS;
107
            } elseif ($result->errorCount() > 0) {
108
                $ret = self::EXIT_EXCEPTION;
109
            }
110
        } catch (\Exception $e) {
111
            echo $e->getMessage() . PHP_EOL;
112
            $ret = self::EXIT_EXCEPTION;
113
        }
114
115
        exit($ret);
116
    }
117
118
    /**
119
     * Check arguments and load configuration file.
120
     *
121
     * @param array $args
122
     */
123
    protected function handleOpt(array $args)
124
    {
125
        try {
126
            $parser  = new Args($this->isPhar);
127
            $options = $parser->getOptions($args);
128
            $this->handleArgs($options);
129
        } catch (Exception $e) {
130
            $this->printError($e->getMessage(), true);
131
        }
132
    }
133
134
    /**
135
     * Handle the parsed command line options
136
     *
137
     * @param  array $options
138
     * @return void
139
     */
140
    protected function handleArgs(array $options)
141
    {
142
        foreach ($options as $option => $argument) {
143
            switch ($option) {
144
                case '--bootstrap':
145
                    $this->arguments['bootstrap'] = $argument;
146
                    break;
147
                case '--colors':
148
                    $this->arguments['colors'] = $argument;
149
                    break;
150
                case '--configuration':
151
                    $this->arguments['configuration'] = $argument;
152
                    break;
153
                case '--debug':
154
                    $this->arguments['debug'] = $argument;
155
                    break;
156
                case '-h':
157
                case '--help':
158
                    $this->printHelp();
159
                    exit(self::EXIT_SUCCESS);
160
                case 'include-path':
161
                    $this->arguments['include-path'] = $argument;
162
                    break;
163
                case '--selfupdate':
164
                case '--self-update':
165
                    $this->handleSelfUpdate();
166
                    break;
167
                case '--simulate':
168
                    $this->arguments['simulate'] = $argument;
169
                    break;
170
                case '-v':
171
                case '--verbose':
172
                    $this->arguments['verbose'] = true;
173
                    break;
174
                case '-V':
175
                case '--version':
176
                    $this->printVersionString();
177
                    exit(self::EXIT_SUCCESS);
178
            }
179
        }
180
    }
181
182
    /**
183
     * Try to find the configuration file.
184
     */
185
    protected function findConfiguration()
186
    {
187
        // check configuration argument
188
        // if configuration argument is a directory
189
        // check for default configuration files 'phpbu.xml' and 'phpbu.xml.dist'
190
        if (isset($this->arguments['configuration']) && is_file($this->arguments['configuration'])) {
191
            $this->arguments['configuration'] = realpath($this->arguments['configuration']);
192
        } elseif (isset($this->arguments['configuration']) && is_dir($this->arguments['configuration'])) {
193
            $this->findConfigurationInDir();
194
        } elseif (!isset($this->arguments['configuration'])) {
195
            // no configuration argument search for default configuration files
196
            // 'phpbu.xml' and 'phpbu.xml.dist' in current working directory
197
            $this->findConfigurationDefault();
198
        }
199
        // no config found, exit with some help output
200
        if (!isset($this->arguments['configuration'])) {
201
            $this->printLogo();
202
            $this->printHelp();
203
            exit(self::EXIT_EXCEPTION);
204
        }
205
    }
206
207
    /**
208
     * Check directory for default configuration files phpbu.xml, phpbu.xml.dist.
209
     *
210
     * @return void
211
     */
212
    protected function findConfigurationInDir()
213
    {
214
        $configurationFile = $this->arguments['configuration'] . '/phpbu.xml';
215
216
        if (file_exists($configurationFile)) {
217
            $this->arguments['configuration'] = realpath($configurationFile);
218
        } elseif (file_exists($configurationFile . '.dist')) {
219
            $this->arguments['configuration'] = realpath($configurationFile . '.dist');
220
        }
221
    }
222
223
    /**
224
     * Check default configuration files phpbu.xml, phpbu.xml.dist in current working directory.
225
     *
226
     * @return void
227
     */
228
    protected function findConfigurationDefault()
229
    {
230
        if (file_exists('phpbu.xml')) {
231
            $this->arguments['configuration'] = realpath('phpbu.xml');
232
        } elseif (file_exists('phpbu.xml.dist')) {
233
            $this->arguments['configuration'] = realpath('phpbu.xml.dist');
234
        }
235
    }
236
237
    /**
238
     * Create a application configuration.
239
     *
240
     * @return \phpbu\App\Configuration
241
     */
242
    protected function createConfiguration()
243
    {
244
        $configLoader  = Configuration\Loader\Factory::createLoader($this->arguments['configuration']);
245
        $configuration = $configLoader->getConfiguration();
246
247
        // command line arguments overrule the config file settings
248
        $this->overrideConfigWithArgument($configuration, 'verbose');
249
        $this->overrideConfigWithArgument($configuration, 'colors');
250
        $this->overrideConfigWithArgument($configuration, 'debug');
251
        $this->overrideConfigWithArgument($configuration, 'simulate');
252
253
        // check for command line bootstrap option
254
        $bootstrap = Arr::getValue($this->arguments, 'bootstrap');
255
        if (!empty($bootstrap)) {
256
            $configuration->setBootstrap($bootstrap);
257
        }
258
259
        // add a cli printer for some output
260
        $configuration->addLogger(
261
            new Result\PrinterCli(
262
                $configuration->getVerbose(),
263
                $configuration->getColors(),
264
                ($configuration->getDebug() || $configuration->isSimulation())
265
            )
266
        );
267
        return $configuration;
268
    }
269
270
    /**
271
     * Override configuration settings with command line arguments.
272
     *
273
     * @param \phpbu\App\Configuration $configuration
274
     * @param string                   $value
275
     */
276
    protected function overrideConfigWithArgument(Configuration $configuration, $value)
277
    {
278
        if (Arr::getValue($this->arguments, $value) === true) {
279
            $setter = 'set' . ucfirst($value);
280
            $configuration->{$setter}(true);
281
        }
282
    }
283
284
    /**
285
     * Handle the phar self-update.
286
     */
287
    protected function handleSelfUpdate()
288
    {
289
        $this->printVersionString();
290
291
        $remoteFilename = 'http://phar.phpbu.de/phpbu.phar';
292
        $localFilename  = realpath($_SERVER['argv'][0]);
293
        $tempFilename   = basename($localFilename, '.phar') . '-temp.phar';
294
295
        echo 'Updating the phpbu PHAR ... ';
296
297
        $old  = error_reporting(0);
298
        $phar = file_get_contents($remoteFilename);
299
        error_reporting($old);
300
        if (!$phar) {
301
            echo ' failed' . PHP_EOL . 'Could not reach phpbu update site' . PHP_EOL;
302
            exit(self::EXIT_EXCEPTION);
303
        }
304
        file_put_contents($tempFilename, $phar);
305
306
        chmod($tempFilename, 0777 & ~umask());
307
308
        // check downloaded phar
309
        try {
310
            $phar = new Phar($tempFilename);
311
            unset($phar);
312
            // replace current phar with the new one
313
            rename($tempFilename, $localFilename);
314
        } catch (Exception $e) {
315
            // cleanup crappy phar
316
            unlink($tempFilename);
317
            echo 'failed' . PHP_EOL . $e->getMessage() . PHP_EOL;
318
            exit(self::EXIT_EXCEPTION);
319
        }
320
321
        echo 'done' . PHP_EOL;
322
        exit(self::EXIT_SUCCESS);
323
    }
324
325
    /**
326
     * Shows the current application version.
327
     */
328
    private function printVersionString()
329
    {
330
        if ($this->isVersionStringPrinted) {
331
            return;
332
        }
333
334
        echo Version::getVersionString() . PHP_EOL;
335
        $this->isVersionStringPrinted = true;
336
    }
337
338
    /**
339
     * Show the phpbu logo
340
     */
341
    protected function printLogo()
342
    {
343
        echo self::$logo . PHP_EOL;
344
    }
345
346
    /**
347
     * Show the help message.
348
     */
349
    protected function printHelp()
350
    {
351
        $this->printVersionString();
352
        echo <<<EOT
353
354
Usage: phpbu [option]
355
356
  --bootstrap=<file>     A "bootstrap" PHP file that is included before the backup.
357
  --configuration=<file> A phpbu xml config file.
358
  --colors               Use colors in output.
359
  --debug                Display debugging information during backup generation.
360
  -h, --help             Prints this usage information.
361
  -v, --verbose          Output more verbose information.
362
  -V, --version          Output version information and exit.
363
364
EOT;
365
        if ($this->isPhar) {
366
            echo '  --self-update          Update phpbu to the latest version.' . PHP_EOL;
367
        }
368
    }
369
370
    /**
371
     * Shows some given error message.
372
     *
373
     * @param string $message
374
     * @param bool   $hint
375
     */
376
    private function printError($message, $hint = false)
377
    {
378
        $help = $hint ? ', use "phpbu -h" for help' : '';
379
        $this->printVersionString();
380
        echo $message . $help . PHP_EOL;
381
        exit(self::EXIT_EXCEPTION);
382
    }
383
384
    /**
385
     * Main method, is called by phpbu command and the phar file.
386
     */
387
    public static function main()
388
    {
389
        $app = new static();
390
        $app->run($_SERVER['argv']);
391
    }
392
}
393