Completed
Push — master ( 1de9b7...830752 )
by Kristof
38:46 queued 24:09
created

GeneratorBundle/Command/GeneratePageCommand.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Kunstmaan\GeneratorBundle\Command;
4
5
use Kunstmaan\GeneratorBundle\Generator\PageGenerator;
6
use Symfony\Component\Console\Input\InputOption;
7
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
8
9
/**
10
 * Generates a new page
11
 */
12
class GeneratePageCommand extends KunstmaanGenerateCommand
13
{
14
    /**
15
     * @var BundleInterface
16
     */
17
    private $bundle;
18
19
    /**
20
     * @var string
21
     */
22
    private $prefix;
23
24
    /**
25
     * @var string
26
     */
27
    private $pageName;
28
29
    /**
30
     * @var array
31
     */
32
    private $fields;
33
34
    /**
35
     * @var array
36
     */
37
    private $template;
38
39
    /**
40
     * @var array
41
     */
42
    private $sections = array();
43
44
    /**
45
     * @var array
46
     */
47
    private $parentPages = array();
48
49
    /**
50
     * @see Command
51
     */
52
    protected function configure()
53
    {
54
        $this->setDescription('Generates a new page')
55
            ->setHelp(<<<'EOT'
56
The <info>kuma:generate:page</info> command generates a new page and its configuration.
57
58
<info>php bin/console kuma:generate:page</info>
59
EOT
60
            )
61
            ->addOption('prefix', '', InputOption::VALUE_OPTIONAL, 'The prefix to be used in the table name of the generated entity')
62
            ->setName('kuma:generate:page');
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    protected function getWelcomeText()
69
    {
70
        return 'Welcome to the Kunstmaan page generator';
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    protected function doExecute()
77
    {
78
        $this->assistant->writeSection('Page generation');
79
80
        $this->createGenerator()->generate($this->bundle, $this->pageName, $this->prefix, $this->fields, $this->template, $this->sections, $this->parentPages);
81
82
        $this->assistant->writeSection('Page successfully created', 'bg=green;fg=black');
83
84 View Code Duplication
        if (count($this->parentPages) == 0) {
85
            $this->assistant->writeLine(array(
86
                'To use this page you must first add the definition below to the <comment>getPossibleChildTypes</comment> funtion of the parent page:',
87
                '<comment>    [</comment>',
88
                "<comment>        'name' => '".$this->pageName."',</comment>",
89
                "<comment>        'class'=> '".$this->bundle->getNamespace().'\\Entity\\Pages\\'.$this->pageName."'</comment>",
90
                '<comment>    ],</comment>',
91
                '',
92
            ));
93
        }
94
95
        $this->assistant->writeLine(array(
96
            'Make sure you update your database first before you use the page:',
97
            '    Directly update your database:          <comment>bin/console doctrine:schema:update --force</comment>',
98
            '    Create a Doctrine migration and run it: <comment>bin/console doctrine:migrations:diff && bin/console doctrine:migrations:migrate</comment>',
99
            '',
100
        ));
101
    }
102
103
    /**
104
     * {@inheritdoc}
105
     */
106
    protected function doInteract()
107
    {
108
        if (!$this->isBundleAvailable('KunstmaanPagePartBundle')) {
109
            $this->assistant->writeError('KunstmaanPagePartBundle not found', true);
110
        }
111
112
        $this->assistant->writeLine(array("This command helps you to generate a new page.\n"));
113
114
        /*
115
         * Ask for which bundle we need to create the pagepart
116
         */
117
        $this->bundle = $this->askForBundleName('page');
118
119
        /*
120
         * Ask the database table prefix
121
         */
122
        $this->prefix = $this->askForPrefix(null, $this->bundle->getNamespace());
123
124
        /*
125
         * Ask the name of the pagepart
126
         */
127
        $this->assistant->writeLine(array(
128
            '',
129
            'The name of your Page: For example: <comment>SponsorPage</comment>, <comment>NewsOverviewPage</comment>',
130
            '',
131
        ));
132
        $generator = $this->getGenerator();
133
        $bundlePath = $this->bundle->getPath();
134
135
        $name = $this->assistant->askAndValidate(
136
            'Page name',
137 View Code Duplication
            function ($name) use ($generator, $bundlePath) {
138
                // Check reserved words
139
                if ($generator->isReservedKeyword($name)) {
140
                    throw new \InvalidArgumentException(sprintf('"%s" is a reserved word', $name));
141
                }
142
143
                // Name should end on Page
144
                if (!preg_match('/Page$/', $name)) {
145
                    throw new \InvalidArgumentException('The page name must end with Page');
146
                }
147
148
                // Name should contain more characters than Page
149
                if (strlen($name) <= strlen('Page') || !preg_match('/^[a-zA-Z]+$/', $name)) {
150
                    throw new \InvalidArgumentException('Invalid page name');
151
                }
152
153
                // Check that entity does not already exist
154
                if (file_exists($bundlePath . '/Entity/Pages/' . $name . '.php')) {
155
                    throw new \InvalidArgumentException(sprintf('Page or entity "%s" already exists', $name));
156
                }
157
158
                return $name;
159
            }
160
        );
161
        $this->pageName = $name;
162
163
        /*
164
         * Ask which fields need to be present
165
         */
166
        $this->assistant->writeLine(array("\nInstead of starting with a blank page, you can add some fields now.\n"));
167
        $fields = $this->askEntityFields($this->bundle, array('title', 'pageTitle', 'parent', 'id'));
168
        $this->fields = array();
169
        foreach ($fields as $fieldInfo) {
170
            $this->fields[] = $this->getEntityFields(
171
                $this->bundle,
172
                $this->pageName,
173
                $this->prefix,
174
                $fieldInfo['name'],
175
                $fieldInfo['type'],
176
                $fieldInfo['extra'],
177
                true,
178
                $fieldInfo['minHeight'],
179
                $fieldInfo['maxHeight'],
180
                $fieldInfo['minWidth'],
181
                $fieldInfo['maxWidth'],
182
                $fieldInfo['mimeTypes']
183
            );
184
        }
185
186
        /**
187
         * Ask which default page template we need to use
188
         */
189
        $templateSelect = $this->getTemplateList();
190
        if (empty($templateSelect)) {
191
            throw new \RuntimeException('You need to define at least one page template before running the page generator!');
192
        }
193
194
        $this->assistant->writeLine('');
195
        $templateId = $this->assistant->askSelect('Which page template do you want to use', $templateSelect);
196
        $templateConfigs = $this->getAvailableTemplates($this->bundle);
197
        $templateConfig = $templateConfigs[$templateId];
198
        $this->template = $templateConfig['file'];
199
200
        /*
201
         * Ask for which sections pagepart configuration the end user wants to use for the different sections
202
         */
203
        $this->assistant->writeLine(array("\nThe select page template consists of these contexts: " . implode(', ', $templateConfig['contexts'])));
204
        $this->section = array();
205
        foreach ($templateConfig['contexts'] as $context) {
206
            $question = "Which pagepart configuration would you like to use for the '$context' context";
207
            $section = $this->askForSections($question, $this->bundle, false, $context);
208
            if (is_null($section)) {
209
                $this->assistant->writeError(sprintf('No section pagepart configuration found for context "%s"', $context), true);
210
            }
211
            $this->sections[] = $section;
212
        }
213
214
        /**
215
         * Ask the parent pages
216
         */
217
        $parentPages = $this->getAvailablePages($this->bundle);
218
        $pagesSelect = array_map(function ($item) {
219
            return $item['name'];
220
        }, $parentPages);
221 View Code Duplication
        if (count($pagesSelect) > 0) {
222
            $this->assistant->writeLine('');
223
            $parentPageIds = $this->assistant->askSelect('Which existing page(s) can have the new page as sub-page (multiple possible, separated by comma)', $pagesSelect, null, true);
224
            foreach ($parentPageIds as $id) {
0 ignored issues
show
The expression $parentPageIds of type array|false|integer|string is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
225
                $this->parentPages[] = $parentPages[$id]['path'];
226
            }
227
        }
228
    }
229
230
    /**
231
     * Get the generator.
232
     *
233
     * @return PageGenerator
234
     */
235 View Code Duplication
    protected function createGenerator()
236
    {
237
        $filesystem = $this->getContainer()->get('filesystem');
238
        $registry = $this->getContainer()->get('doctrine');
239
240
        return new PageGenerator($filesystem, $registry, '/page', $this->assistant, $this->getContainer());
241
    }
242
243
    /**
244
     * Get all the available default templates.
245
     *
246
     * @return array
247
     */
248
    private function getTemplateList()
249
    {
250
        $templates = $this->getAvailableTemplates($this->bundle);
251
252
        $types = array();
253
        foreach ($templates as $key => $template) {
254
            $types[$key] = $template['name'];
255
        }
256
257
        return $types;
258
    }
259
}
260