Completed
Push — 5.0 ( a48099...63af02 )
by
unknown
11:33
created

GeneratorBundle/Command/GenerateArticleCommand.php (5 issues)

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\ArticleGenerator;
6
use Symfony\Component\Console\Input\InputOption;
7
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
8
9
/**
10
 * Generates classes based on the AbstractArticle classes from KunstmaanArticleBundle
11
 */
12
class GenerateArticleCommand extends KunstmaanGenerateCommand
13
{
14
    /**
15
     * @var BundleInterface
16
     */
17
    private $bundle;
18
19
    /**
20
     * @var string
21
     */
22
    private $entity;
23
24
    /**
25
     * @var string
26
     */
27
    private $prefix;
28
29
    /**
30
     * @var string
31
     */
32
    private $bundleWithHomePage;
33
34
    /**
35
     * @var array
36
     */
37
    private $parentPages = array();
38
39
    /**
40
     * @var bool
41
     */
42
    private $usesAuthor;
43
44
    /**
45
     * @var bool
46
     */
47
    private $usesCategories;
48
49
    /**
50
     * @var bool
51
     */
52
    private $usesTags;
53
54
    /**
55
     * @var bool
56
     */
57
    private $dummydata;
58
59
    /**
60
     * @see Command
61
     */
62
    protected function configure()
63
    {
64
        $this
65
            ->setDefinition(
66
                array(
67
                    new InputOption('namespace', '', InputOption::VALUE_REQUIRED, 'The namespace to generate the Article classes in'),
68
                    new InputOption('entity', '', InputOption::VALUE_REQUIRED, 'The article class name ("News", "Press", ..."'),
69
                    new InputOption('prefix', '', InputOption::VALUE_OPTIONAL, 'The prefix to be used in the table names of the generated entities'),
70
                    new InputOption('namespacehomepage', '', InputOption::VALUE_OPTIONAL, 'The namespace of the home page entity'),
71
                    new InputOption('articleoverviewpageparent', '', InputOption::VALUE_OPTIONAL, 'Shortnames of the pages that can have the article overview page as a child (comma separated)'),
72
                    new InputOption('with-author', null, InputOption::VALUE_NONE, 'If set, you can use authors'),
73
                    new InputOption('with-category', null, InputOption::VALUE_NONE, 'If set, you can use categories'),
74
                    new InputOption('with-tag', null, InputOption::VALUE_NONE, 'If set, the you can use tags'),
75
                    new InputOption('dummydata', null, InputOption::VALUE_NONE, 'If set, the task will generate data fixtures to populate your database')
76
                )
77
            )
78
            ->setDescription('Generates Article classes based on KunstmaanArticleBundle')
79
            ->setHelp(<<<EOT
80
The <info>kuma:generate:article</info> command generates classes for Articles using the KunstmaanArticleBundle
81
82
<info>php bin/console kuma:generate:article --namespace=Namespace/NamedBundle --entity=Article</info>
83
84
Use the <info>--prefix</info> option to add a prefix to the table names of the generated entities
85
86
<info>php bin/console kuma:generate:article --namespace=Namespace/NamedBundle --prefix=demo_</info>
87
88
Add the <info>--dummydata</info> option to create data fixtures to populate your database
89
90
<info>php bin/console kuma:generate:article --namespace=Namespace/NamedBundle --dummydata</info>
91
EOT
92
            )
93
            ->setName('kuma:generate:article');
94
    }
95
96
    /**
97
     * @return ArticleGenerator
98
     */
99 View Code Duplication
    protected function createGenerator()
100
    {
101
        $filesystem = $this->getContainer()->get('filesystem');
102
        $registry = $this->getContainer()->get('doctrine');
103
104
        return new ArticleGenerator($filesystem, $registry, '/article', $this->parentPages, $this->assistant, $this->getContainer());
105
    }
106
107
    /**
108
     * Do the interaction with the end user.
109
     */
110
    protected function doInteract()
111
    {
112
        /**
113
         * Ask for which bundle we need to create the layout
114
         */
115
        $bundleNamespace = $this->assistant->getOptionOrDefault('namespace', null);
116
        $this->bundle = $this->askForBundleName('article classes', $bundleNamespace);
117
118
        /**
119
         * Entity
120
         */
121
        $this->entity = $this->assistant->getOptionOrDefault('entity', null);
122
123
        if (is_null($this->entity)) {
124
            $this->assistant->writeLine(array(
125
                'You must specify a name for the collection of Article entities.',
126
                'This name will be prefixed before every new entity.',
127
                'For example entering <comment>News</comment> will result in:',
128
                '<comment>News</comment>OverviewPage, <comment>News</comment>Page and <comment>News</comment>Author'
129
            ));
130
131
            $generator = $this->getGenerator();
132
            $bundlePath = $this->bundle->getPath();
133
            $this->entity = $this->assistant->askAndValidate(
134
                'Article class name',
135
                function ($name) use ($generator, $bundlePath) {
136
                    // Check reserved words
137
                    if ($generator->isReservedKeyword($name)){
138
                        throw new \InvalidArgumentException(sprintf('"%s" is a reserved word', $name));
139
                    }
140
                    if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $name)) {
141
                        throw new \InvalidArgumentException(sprintf('Invalid entity name: %s', $name));
142
                    }
143
                    return $name;
144
                }
145
            );
146
        }
147
148
        /**
149
         * Ask if author will be used
150
         */
151
        $this->usesAuthor = $this->askForAuthor();
152
153
        /**
154
         * Ask if category will be used
155
         */
156
        $this->usesCategories = $this->askForCategories();
157
158
        /**
159
         * Ask if tag will be used
160
         */
161
        $this->usesTags = $this->askForTags();
162
163
        /**
164
         * Ask the parent pages
165
         */
166
        $bundleWithHomePageNamespace = $this->assistant->getOptionOrDefault('namespacehomepage', null);
167
        $this->bundleWithHomePage = $this->askForBundleName('', $bundleWithHomePageNamespace, 'In which bundle is the page that you will use as parent for the overview page ?', "%sThe bundle %s will be used for the parent of the overview page.\n");
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->askForBundleName(...f the overview page. ') of type object<Symfony\Component...Bundle\BundleInterface> is incompatible with the declared type string of property $bundleWithHomePage.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
168
        $parentPages = $this->getAvailablePages($this->bundleWithHomePage);
169
        $pagesSelect = array_map(function ($item) { return $item['name']; }, $parentPages);
170
        if (count($pagesSelect) > 0) {
171
            $this->assistant->writeLine('');
172
            $parentPageNames = $this->assistant->getOptionOrDefault('articleoverviewpageparent', null);
173
            if (null !== $parentPageNames) {
174
                $parentPageNames = explode(',', $parentPageNames);
175
                foreach ($parentPageNames as $parentPageName) {
176
                    $id = array_search($parentPageName, $pagesSelect);
177
                    if (false !== $id) {
178
                        $this->parentPages[] = $parentPages[$id]['path'];
179
                    }
180
                }
181
            }
182
183
            if (empty($this->parentPages)) {
184
                $parentPageIds = $this->assistant->askSelect('Which existing page(s) can have the new overview page as sub-page (multiple possible, separated by comma)', $pagesSelect, null, true);
185
                foreach ($parentPageIds as $id) {
186
                    $this->parentPages[] = $parentPages[$id]['path'];
187
                }
188
            }
189
        }
190
191
        /**
192
         * Ask the database table prefix
193
         */
194
        $this->prefix = $this->assistant->getOptionOrDefault('prefix', null);
195
        if (is_null($this->prefix)) {
196
            $this->prefix = $this->askForPrefix(null, $this->bundle->getNamespace());
197
        }
198
199
        /**
200
         * Ask for data fixtures
201
         */
202
        $this->dummydata = $this->askForDummydata();
203
    }
204
205
    /**
206
     * This function implements the final execution of the Generator.
207
     * It calls the execute function with the correct parameters.
208
     */
209
    protected function doExecute()
210
    {
211
        $this->assistant->writeSection('Article classes generation');
212
213
        $this->createGenerator()->generate($this->bundle, $this->entity, $this->prefix, $this->getContainer()->getParameter('multilanguage'), $this->usesAuthor, $this->usesCategories, $this->usesTags, $this->bundleWithHomePage, $this->dummydata);
214
215
        $this->assistant->writeSection('Article classes successfully created', 'bg=green;fg=black');
216
        $this->assistant->writeLine(array(
217
            'Make sure you update your database first before you test the pagepart:',
218
            '    Directly update your database:          <comment>bin/console doctrine:schema:update --force</comment>',
219
            '    Create a Doctrine migration and run it: <comment>bin/console doctrine:migrations:diff && bin/console doctrine:migrations:migrate</comment>'
220
        ));
221
    }
222
223
    /**
224
     * The text to be displayed on top of the generator.
225
     *
226
     * @return string|array
227
     */
228
    protected function getWelcomeText()
229
    {
230
        return 'Welcome to the Kunstmaan article generator';
231
    }
232
233
    /**
234
     * @return bool
235
     */
236 View Code Duplication
    protected function askForDummydata()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
237
    {
238
        $dummydataOption = $this->assistant->getOption('dummydata');
239
        if ($dummydataOption != 'y' && $dummydataOption != 'n') {
240
            /** @var  $question */
241
            $dummydataOption = $this->assistant->askConfirmation("\nDo you want to generate data fixtures to populate your database ? (y/n)\n", 'n', '?', false);
242
        }
243
        return $dummydataOption == 'y';
244
    }
245
246
    /**
247
     * @return bool
248
     */
249 View Code Duplication
    protected function askForCategories()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
250
    {
251
        $categoryOption = $this->assistant->getOption('with-category');
252
        if ($categoryOption != 'y' && $categoryOption != 'n') {
253
            /** @var  $question */
254
            $categoryOption = $this->assistant->askConfirmation("\nDo you want to use categories ? (y/n)\n", 'y', '?', true);
255
        }
256
        return $categoryOption == 'y';
257
    }
258
259
    /**
260
     * @return bool
261
     */
262 View Code Duplication
    protected function askForTags()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
263
    {
264
        $tagOption = $this->assistant->getOption('with-tag');
265
        if ($tagOption != 'y' && $tagOption != 'n') {
266
            /** @var  $question */
267
            $tagOption = $this->assistant->askConfirmation("\nDo you want to use tags ? (y/n)\n", 'y', '?', true);
268
        }
269
        return $tagOption == 'y';
270
    }
271
272
    /**
273
     * @return bool
274
     */
275 View Code Duplication
    protected function askForAuthor()
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
276
    {
277
        $authorOption = $this->assistant->getOption('with-author');
278
        if ($authorOption != 'y' && $authorOption != 'n') {
279
            /** @var  $question */
280
            $authorOption = $this->assistant->askConfirmation("\nDo you want to authors ? (y/n)\n", 'y', '?', true);
281
        }
282
        return $authorOption == 'y';
283
    }
284
285
}
286