Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

GeneratorBundle/Command/GenerateArticleCommand.php (3 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 = [];
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
                [
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());
0 ignored issues
show
$filesystem is of type object|null, but the function expects a object<Symfony\Component\Filesystem\Filesystem>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
$registry is of type object|null, but the function expects a object<Symfony\Bridge\Doctrine\RegistryInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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([
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
            $this->entity = $this->assistant->askAndValidate(
133
                'Article class name',
134
                function ($name) use ($generator) {
135
                    // Check reserved words
136
                    if ($generator->isReservedKeyword($name)) {
137
                        throw new \InvalidArgumentException(sprintf('"%s" is a reserved word', $name));
138
                    }
139
                    if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $name)) {
140
                        throw new \InvalidArgumentException(sprintf('Invalid entity name: %s', $name));
141
                    }
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) {
170
            return $item['name'];
171
        }, $parentPages);
172
        if (count($pagesSelect) > 0) {
173
            $this->assistant->writeLine('');
174
            $parentPageNames = $this->assistant->getOptionOrDefault('articleoverviewpageparent', null);
175
            if (null !== $parentPageNames) {
176
                $parentPageNames = explode(',', $parentPageNames);
177
                foreach ($parentPageNames as $parentPageName) {
178
                    $id = array_search($parentPageName, $pagesSelect);
179
                    if (false !== $id) {
180
                        $this->parentPages[] = $parentPages[$id]['path'];
181
                    }
182
                }
183
            }
184
185
            if (empty($this->parentPages)) {
186
                $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);
187
                foreach ($parentPageIds as $id) {
188
                    $this->parentPages[] = $parentPages[$id]['path'];
189
                }
190
            }
191
        }
192
193
        /*
194
         * Ask the database table prefix
195
         */
196
        $this->prefix = $this->assistant->getOptionOrDefault('prefix', null);
197
        if (is_null($this->prefix)) {
198
            $this->prefix = $this->askForPrefix(null, $this->bundle->getNamespace());
199
        }
200
201
        /*
202
         * Ask for data fixtures
203
         */
204
        $this->dummydata = $this->askForDummydata();
205
    }
206
207
    /**
208
     * This function implements the final execution of the Generator.
209
     * It calls the execute function with the correct parameters.
210
     */
211
    protected function doExecute()
212
    {
213
        $this->assistant->writeSection('Article classes generation');
214
215
        $this->createGenerator()->generate($this->bundle, $this->entity, $this->prefix, $this->getContainer()->getParameter('kunstmaan_admin.multi_language'), $this->usesAuthor, $this->usesCategories, $this->usesTags, $this->bundleWithHomePage, $this->dummydata);
216
217
        $this->assistant->writeSection('Article classes successfully created', 'bg=green;fg=black');
218
        $this->assistant->writeLine([
219
            'Make sure you update your database first before you test the pagepart:',
220
            '    Directly update your database:          <comment>bin/console doctrine:schema:update --force</comment>',
221
            '    Create a Doctrine migration and run it: <comment>bin/console doctrine:migrations:diff && bin/console doctrine:migrations:migrate</comment>',
222
        ]);
223
224
        return 0;
225
    }
226
227
    /**
228
     * The text to be displayed on top of the generator.
229
     *
230
     * @return string|array
231
     */
232
    protected function getWelcomeText()
233
    {
234
        return 'Welcome to the Kunstmaan article generator';
235
    }
236
237
    /**
238
     * @return bool
239
     */
240 View Code Duplication
    protected function askForDummydata()
241
    {
242
        $dummydataOption = $this->assistant->getOption('dummydata');
243
        if ($dummydataOption != 'y' && $dummydataOption != 'n') {
244
            /** @var $question */
245
            $dummydataOption = $this->assistant->askConfirmation("\nDo you want to generate data fixtures to populate your database ? (y/n)\n", 'n', '?', false);
246
        }
247
248
        return $dummydataOption == 'y';
249
    }
250
251
    /**
252
     * @return bool
253
     */
254 View Code Duplication
    protected function askForCategories()
255
    {
256
        $categoryOption = $this->assistant->getOption('with-category');
257
        if ($categoryOption != 'y' && $categoryOption != 'n') {
258
            /** @var $question */
259
            $categoryOption = $this->assistant->askConfirmation("\nDo you want to use categories ? (y/n)\n", 'y', '?', true);
260
        }
261
262
        return $categoryOption == 'y';
263
    }
264
265
    /**
266
     * @return bool
267
     */
268 View Code Duplication
    protected function askForTags()
269
    {
270
        $tagOption = $this->assistant->getOption('with-tag');
271
        if ($tagOption != 'y' && $tagOption != 'n') {
272
            /** @var $question */
273
            $tagOption = $this->assistant->askConfirmation("\nDo you want to use tags ? (y/n)\n", 'y', '?', true);
274
        }
275
276
        return $tagOption == 'y';
277
    }
278
279
    /**
280
     * @return bool
281
     */
282 View Code Duplication
    protected function askForAuthor()
283
    {
284
        $authorOption = $this->assistant->getOption('with-author');
285
        if ($authorOption != 'y' && $authorOption != 'n') {
286
            /** @var $question */
287
            $authorOption = $this->assistant->askConfirmation("\nDo you want to use authors ? (y/n)\n", 'y', '?', true);
288
        }
289
290
        return $authorOption == 'y';
291
    }
292
}
293