Completed
Push — master ( 7a069b...4da1f4 )
by Paweł
11s
created

ThemeSetupCommand::execute()   C

Complexity

Conditions 9
Paths 50

Size

Total Lines 74
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 9

Importance

Changes 0
Metric Value
dl 0
loc 74
ccs 21
cts 21
cp 1
rs 5.9292
c 0
b 0
f 0
cc 9
eloc 51
nc 50
nop 2
crap 9

How to fix   Long Method   

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
/*
4
 * This file is part of the Superdesk Web Publisher Core Bundle.
5
 *
6
 * Copyright 2016 Sourcefabric z.ú. and contributors.
7
 *
8
 * For the full copyright and license information, please see the
9
 * AUTHORS and LICENSE files distributed with this source code.
10
 *
11
 * @copyright 2016 Sourcefabric z.ú
12
 * @license http://www.superdesk.org/license
13
 */
14
15
namespace SWP\Bundle\CoreBundle\Command;
16
17
use SWP\Bundle\CoreBundle\Theme\Repository\ReloadableThemeRepositoryInterface;
18
use SWP\Bundle\MultiTenancyBundle\MultiTenancyEvents;
19
use SWP\Component\Common\Model\ThemeAwareTenantInterface;
20
use SWP\Component\MultiTenancy\Exception\TenantNotFoundException;
21
use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand;
22
use Symfony\Component\Console\Input\InputArgument;
23
use Symfony\Component\Console\Input\InputInterface;
24
use Symfony\Component\Console\Input\InputOption;
25
use Symfony\Component\Console\Output\OutputInterface;
26
use Symfony\Component\Console\Question\ConfirmationQuestion;
27
use Symfony\Component\Filesystem\Filesystem;
28
29
class ThemeSetupCommand extends ContainerAwareCommand
30
{
31
    /**
32 105
     * {@inheritdoc}
33
     */
34
    protected function configure()
35 105
    {
36 105
        $this
37 105
            ->setName('swp:theme:install')
38 105
            ->setDescription('Installs theme.')
39 105
            ->addArgument(
40 105
                'tenant',
41
                InputArgument::REQUIRED,
42 105
                'Tenant code. For this tenant the theme will be installed.'
43 105
            )
44 105
            ->addArgument(
45 105
                'theme_dir',
46
                InputArgument::REQUIRED,
47 105
                'Path to theme you want to install.'
48 105
            )
49 105
            ->addOption(
50 105
                'force',
51 105
                'f',
52
                InputOption::VALUE_NONE,
53 105
                'If set, forces to execute an action without confirmation.'
54
            )
55
            ->addOption(
56
                'activate',
57
                'a',
58
                InputOption::VALUE_NONE,
59
                'If set, theme will be activated in tenant.'
60
            )
61
            ->setHelp(
62
                <<<'EOT'
63
The <info>%command.name%</info> command installs your custom theme for given tenant:
64
65
  <info>%command.full_name% <tenant> <theme_dir></info>
66
67
You need specify the directory (<comment>theme_dir</comment>) argument to install 
68
theme from any directory:
69 105
70
  <info>%command.full_name% <tenant> /dir/to/theme
71
  
72 105
Once executed, it will create directory <comment>app/themes/<tenant></comment>
73
where <comment><tenant></comment> is the tenant code you typed in the first argument.
74
75
To force an action, you need to add an option: <info>--force</info>:
76
77 4
  <info>%command.full_name% <tenant> <theme_dir> --force</info>
78
79 4
To activate this theme in tenant, you need to add and option <info>--activate</info>:
80 4
  <info>%command.full_name% <tenant> <theme_dir> --activate</info>
81 4
82
Theme installation will generated declared in theme config elements 
83
like: routes, articles, menus, widgets, content lists and containers
84 4
EOT
85 4
            );
86
    }
87 4
88
    /**
89 4
     * {@inheritdoc}
90
     */
91 3
    protected function execute(InputInterface $input, OutputInterface $output)
92 1
    {
93
        $fileSystem = new Filesystem();
94 1
        $sourceDir = $input->getArgument('theme_dir');
95
        if (!$fileSystem->exists($sourceDir) || !is_dir($sourceDir)) {
96
            $output->writeln(sprintf('<error>Directory "%s" does not exist or it is not a directory!</error>', $sourceDir));
97 2
98 2
            return;
99 2
        }
100
101
        if (!$fileSystem->exists($sourceDir.DIRECTORY_SEPARATOR.'theme.json')) {
102 2
            $output->writeln(sprintf('<error>Source directory doesn\'t contain a theme!</error>', $sourceDir));
103 2
104 2
            return;
105 2
        }
106
107
        $container = $this->getContainer();
108 2
        $tenantRepository = $container->get('swp.repository.tenant');
109
        $tenantContext = $container->get('swp_multi_tenancy.tenant_context');
110
        $eventDispatcher = $container->get('event_dispatcher');
111
        $revisionListener = $container->get('swp_core.listener.tenant_revision');
112
113
        $tenant = $tenantRepository->findOneByCode($input->getArgument('tenant'));
114 2
        $this->assertTenantIsFound($input->getArgument('tenant'), $tenant);
115
        $tenantContext->setTenant($tenant);
116 1
        $revisionListener->setRevisions();
117 1
        $eventDispatcher->dispatch(MultiTenancyEvents::TENANTABLE_ENABLE);
118 1
        $themeInstaller = $container->get('swp_core.installer.theme');
119 1
120
        $force = true === $input->getOption('force');
121 2
        $activate = true === $input->getOption('activate');
122
        $themesDir = $container->getParameter('swp.theme.configuration.default_directory');
123 4
        $themeDir = $themesDir.\DIRECTORY_SEPARATOR.$tenant->getCode().\DIRECTORY_SEPARATOR.basename($sourceDir);
124
125 4
        try {
126 1
            $helper = $this->getHelper('question');
127
            $question = new ConfirmationQuestion(
128 3
                '<question>This will override your current theme. Continue with this action? (yes/no)<question> <comment>[yes]</comment> ',
129
                true,
130
                '/^(y|j)/i'
131
            );
132
133
            if (!$force) {
134
                if (!$helper->ask($input, $output, $question)) {
135
                    return;
136
                }
137
            }
138
139
            $themeInstaller->install(null, $sourceDir, $themeDir);
140
            /** @var ReloadableThemeRepositoryInterface $themeRepository */
141
            $themeRepository = $container->get('sylius.repository.theme');
142
            $themeRepository->reloadThemes();
143
            $output->writeln('<info>Theme has been installed successfully!</info>');
144
145
            if (file_exists($themeDir.\DIRECTORY_SEPARATOR.'theme.json')) {
146
                $themeName = json_decode(file_get_contents($themeDir.\DIRECTORY_SEPARATOR.'theme.json'), true)['name'];
147
                $tenant->setThemeName($themeName);
148
149
                if ($activate) {
150
                    $tenantRepository->flush();
151
                    $output->writeln('<info>Theme was activated!</info>');
152
                }
153
154
                $output->writeln('<info>Persisting theme required data...</info>');
155
                $theme = $container->get('sylius.context.theme')->getTheme();
156
                $requiredDataProcessor = $container->get('swp_core.processor.theme.required_data');
157
                $requiredDataProcessor->processTheme($theme);
158
                $output->writeln('<info>Theme required data was persisted successfully!</info>');
159
            }
160
        } catch (\Exception $e) {
161
            $output->writeln('<error>Theme could not be installed!</error>');
162
            $output->writeln('<error>Error message: '.$e->getMessage().'</error>');
163
        }
164
    }
165
166
    private function assertTenantIsFound(string $tenantCode, ThemeAwareTenantInterface $tenant = null)
167
    {
168
        if (null === $tenant) {
169
            throw new TenantNotFoundException($tenantCode);
170
        }
171
    }
172
}
173