Completed
Push — master ( 5ea837...9dec3c )
by Paul
9s
created

AssetsInstallCommand::execute()   C

Complexity

Conditions 10
Paths 8

Size

Total Lines 47
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 47
rs 5.1578
cc 10
eloc 27
nc 8
nop 2

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
 * This file is part of the PPI Framework.
4
 *
5
 * @copyright  Copyright (c) 2011-2016 Paul Dragoonis <[email protected]>
6
 * @license    http://opensource.org/licenses/mit-license.php MIT
7
 *
8
 * @link       http://www.ppi.io
9
 */
10
11
namespace PPI\Framework\Console\Command;
12
13
use Symfony\Component\Console\Input\InputArgument;
14
use Symfony\Component\Console\Input\InputInterface;
15
use Symfony\Component\Console\Input\InputOption;
16
use Symfony\Component\Console\Output\OutputInterface;
17
use Symfony\Component\Finder\Finder;
18
19
/**
20
 * Command that places module web assets into a given directory.
21
 *
22
 * @author      Fabien Potencier <[email protected]>
23
 * @author      Vítor Brandão <[email protected]>
24
 * @author      Paul Dragoonis <[email protected]>
25
 */
26
class AssetsInstallCommand extends AbstractCommand
27
{
28
    /**
29
     * {@inheritdoc}
30
     */
31
    protected function configure()
32
    {
33
        $this
34
            ->setName('assets:install')
35
            ->setDefinition(array(
36
                new InputArgument('target', InputArgument::OPTIONAL, 'The target directory', 'public'),
37
            ))
38
            ->addOption('symlink', null, InputOption::VALUE_NONE, 'Symlinks the assets instead of copying it')
39
            ->addOption('relative', null, InputOption::VALUE_NONE, 'Make relative symlinks')
40
            ->setDescription('Installs modules public assets under a public directory')
41
            ->setHelp(<<<EOT
42
The <info>%command.name%</info> command installs module assets into a given
43
directory (e.g. the public directory).
44
45
<info>php %command.full_name% public</info>
46
47
A "modules" directory will be created inside the target directory, and the
48
"Resources/public" directory of each module will be copied into it.
49
50
To create a symlink to each module instead of copying its assets, use the
51
<info>--symlink</info> option:
52
53
<info>php %command.full_name% public --symlink</info>
54
55
To make symlink relative, add the <info>--relative</info> option:
56
57
<info>php %command.full_name% public --symlink --relative</info>
58
59
EOT
60
            );
61
    }
62
63
    /**
64
     * {@inheritdoc}
65
     *
66
     * @throws \InvalidArgumentException When the target directory does not exist or symlink cannot be used
67
     */
68
    protected function execute(InputInterface $input, OutputInterface $output)
69
    {
70
        $targetArg = rtrim($input->getArgument('target'), '/');
71
72
        if (!is_dir($targetArg)) {
73
            throw new \InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $input->getArgument('target')));
74
        }
75
76
        if (!function_exists('symlink') && $input->getOption('symlink')) {
77
            throw new \InvalidArgumentException('The symlink() function is not available on your system. You need to install the assets without the --symlink option.');
78
        }
79
80
        $filesystem = $this->getServiceManager()->get('filesystem');
81
82
        // Create the modules directory otherwise symlink will fail.
83
        $filesystem->mkdir($targetArg . '/modules/', 0777);
84
85
        $output->writeln(sprintf("Installing assets using the <comment>%s</comment> option", $input->getOption('symlink') ? 'symlink' : 'hard copy'));
86
87
        foreach ($this->getServiceManager()->get('modulemanager')->getLoadedModules() as $module) {
88
            if (!method_exists($module, 'getPath')) {
89
                continue;
90
            }
91
            if (!is_dir($originDir = $module->getPath() . '/resources/public')) {
92
                continue;
93
            }
94
            $modulesDir = $targetArg . '/modules/';
95
            $targetDir = $modulesDir . str_replace('module', '', strtolower($module->getName()));
96
97
            $output->writeln(sprintf('Installing assets for <comment>%s</comment> into <comment>%s</comment>', $module->getNamespace(), $targetDir));
98
99
            $filesystem->remove($targetDir);
100
101
            if ($input->getOption('symlink')) {
102
                if ($input->getOption('relative')) {
103
                    $relativeOriginDir = $filesystem->makePathRelative($originDir, realpath($modulesDir));
104
                } else {
105
                    $relativeOriginDir = $originDir;
106
                }
107
                $filesystem->symlink($relativeOriginDir, $targetDir);
108
            } else {
109
                $filesystem->mkdir($targetDir, 0777);
110
                // We use a custom iterator to ignore VCS files
111
                $filesystem->mirror($originDir, $targetDir, Finder::create()->in($originDir));
112
            }
113
        }
114
    }
115
}
116