Completed
Push — master ( 91fdab...75a7b9 )
by
unknown
13:37
created

GeneratorBundle/Generator/PagePartGenerator.php (2 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\Generator;
4
5
use Faker\Provider\Base;
6
use Faker\Provider\DateTime;
7
use Faker\Provider\Lorem;
8
use Symfony\Component\DependencyInjection\Container;
9
use Symfony\Component\Finder\Finder;
10
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
11
use Symfony\Component\Yaml\Yaml;
12
13
/**
14
 * Generates all classes/files for a new pagepart
15
 */
16
class PagePartGenerator extends KunstmaanGenerator
17
{
18
    /**
19
     * @var BundleInterface
20
     */
21
    private $bundle;
22
23
    /**
24
     * @var string
25
     */
26
    private $entity;
27
28
    /**
29
     * @var string
30
     */
31
    private $prefix;
32
33
    /**
34
     * @var array
35
     */
36
    private $fields;
37
38
    /**
39
     * @var array
40
     */
41
    private $sections;
42
43
    /**
44
     * Generate the pagepart.
45
     *
46
     * @param BundleInterface $bundle    The bundle
47
     * @param string          $entity    The entity name
48
     * @param string          $prefix    The database prefix
49
     * @param array           $fields    The fields
50
     * @param array           $sections  The page sections
51
     * @param bool            $behatTest If we need to generate a behat test for this pagepart
52
     *
53
     * @throws \RuntimeException
54
     */
55 View Code Duplication
    public function generate(BundleInterface $bundle, $entity, $prefix, array $fields, array $sections, $behatTest)
56
    {
57
        $this->bundle   = $bundle;
58
        $this->entity   = $entity;
59
        $this->prefix   = $prefix;
60
        $this->fields   = $fields;
61
        $this->sections = $sections;
62
63
        $this->generatePagePartEntity();
64
        $this->generateFormType();
65
        $this->generateResourceTemplate();
66
        $this->generateSectionConfig();
67
        if ($behatTest) {
68
            $this->generateBehatTest();
69
        }
70
    }
71
72
    /**
73
     * Generate the pagepart entity.
74
     *
75
     * @throws \RuntimeException
76
     */
77
    private function generatePagePartEntity()
78
    {
79
        if (file_exists($this->bundle->getPath() . '/Entity/PageParts/AbstractPagePart.php')) {
80
            $abstractClass = $this->bundle->getNamespace() . '\Entity\PageParts\AbstractPagePart';
81
        } else {
82
            $abstractClass = 'Kunstmaan\PagePartBundle\Entity\AbstractPagePart';
83
        }
84
85
        list($entityCode, $entityPath) = $this->generateEntity(
86
            $this->bundle,
87
            $this->entity,
88
            $this->fields,
89
            'PageParts',
90
            $this->prefix,
91
            $abstractClass
92
        );
93
94
        // Add some extra functions in the generated entity :s
95
        $params    = array(
96
            'bundle'    => $this->bundle->getName(),
97
            'pagepart'  => $this->entity,
98
            'adminType' => '\\' . $this->bundle->getNamespace() . '\\Form\\PageParts\\' . $this->entity . 'AdminType'
99
        );
100
        $extraCode = $this->render('/Entity/PageParts/ExtraFunctions.php', $params);
101
102
        $pos        = strrpos($entityCode, "\n}");
103
        $trimmed    = substr($entityCode, 0, $pos);
104
        $entityCode = $trimmed."\n\n".$extraCode."\n}\n";
105
106
        // Write class to filesystem
107
        $this->filesystem->mkdir(dirname($entityPath));
108
        file_put_contents($entityPath, $entityCode);
109
110
        $this->assistant->writeLine('Generating entity : <info>OK</info>');
111
    }
112
113
    /**
114
     * Generate the admin form type entity.
115
     */
116
    private function generateFormType()
117
    {
118
        $this->generateEntityAdminType($this->bundle, $this->entity, 'PageParts', $this->fields);
119
120
        $this->assistant->writeLine('Generating form type : <info>OK</info>');
121
    }
122
123
    /**
124
     * Generate the twig template.
125
     */
126
    private function generateResourceTemplate()
127
    {
128
        $savePath = $this->bundle->getPath() . '/Resources/views/PageParts/' . $this->entity . '/view.html.twig';
129
130
        $params = array(
131
            'pagepart' => strtolower(
132
                    preg_replace('/([a-z])([A-Z])/', '$1-$2', str_ireplace('PagePart', '', $this->entity))
133
                ) . '-pp',
134
            'fields'   => $this->fields
135
        );
136
        $this->renderFile('/Resources/views/PageParts/view.html.twig', $savePath, $params);
137
138
        $this->assistant->writeLine('Generating template : <info>OK</info>');
139
    }
140
141
    /**
142
     * Update the page section config files
143
     */
144
    private function generateSectionConfig()
145
    {
146
        if (count($this->sections) > 0) {
147
            $dir = $this->bundle->getPath() . '/Resources/config/pageparts/';
148
            foreach ($this->sections as $section) {
149
                $data = Yaml::parse(file_get_contents($dir . $section));
150
                if (!array_key_exists('types', $data)) {
151
                    $data['types'] = array();
152
                }
153
                $data['types'][] = array(
154
                    'name'  => str_replace('PagePart', '', $this->entity),
155
                    'class' => $this->bundle->getNamespace() . '\\Entity\\PageParts\\' . $this->entity
156
                );
157
158
                $ymlData = Yaml::dump($data);
159
                file_put_contents($dir . $section, $ymlData);
160
            }
161
162
            $this->assistant->writeLine('Updating section config : <info>OK</info>');
163
        }
164
    }
165
166
    /**
167
     * Generate the admin form type entity.
168
     */
169
    private function generateBehatTest()
170
    {
171
        $configDir = $this->bundle->getPath() . '/Resources/config';
172
173
        // Get the context names for each section config file
174
        $sectionInfo = array();
175
        $dir         = $configDir . '/pageparts/';
176
        foreach ($this->sections as $section) {
177
            $data                                    = Yaml::parse(file_get_contents($dir . $section));
178
            $sectionInfo[basename($section, '.yml')] = array('context' => $data['context'], 'pagetempates' => array());
179
        }
180
181
        /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
182
            Example $sectionInfo contents:
183
            Array
184
            (
185
                [main] => Array
186
                    (
187
                        [context] => main
188
                        [pagetempates] => Array
189
                            (
190
                            )
191
                    )
192
            )
193
        */
194
195
        // Get a list of page templates that use this context
196
        $templateFinder = new Finder();
197
        $templateFinder->files()->in($configDir . '/pagetemplates')->name('*.yml');
198
199
        $contextTemplates = array();
200
        foreach ($templateFinder as $templatePath) {
201
            $parts    = explode("/", $templatePath);
202
            $fileName = basename($parts[count($parts) - 1], '.yml');
203
204
            $data         = Yaml::parse(file_get_contents($templatePath));
205
            $templateName = $data['name'];
206
            if (array_key_exists('rows', $data) && is_array($data['rows'])) {
207
                foreach ($data['rows'] as $row) {
208
                    if (is_array($row) && array_key_exists('regions', $row) && is_array($row['regions'])) {
209
                        foreach ($row['regions'] as $region) {
210
                            $contextTemplates[$region['name']][$fileName] = $templateName;
211
                        }
212
                    }
213
                }
214
            }
215
        }
216
217
        /*
218
            Example $contextTemplates contents:
219
            Array
220
            (
221
                [main] => Array
222
                    (
223
                        [full-width-page] => Full width page
224
                        [homepage] => Home page
225
                        [sidebar-page] => Page with left sidebar
226
                    )
227
                [top] => Array
228
                    (
229
                        [homepage] => Home page
230
                    )
231
                [sidebar] => Array
232
                    (
233
                        [homepage] => Home page
234
                        [sidebar-page] => Page with left sidebar
235
                    )
236
            )
237
        */
238
239
        // Link the page templates to the sections
240
        foreach ($sectionInfo as $fileName => $info) {
241
            $context = $info['context'];
242
            if (array_key_exists($context, $contextTemplates)) {
243
                $sectionInfo[$fileName]['pagetempates'] = $contextTemplates[$context];
244
            }
245
        }
246
247
        /*
248
            Example $sectionInfo contents:
249
            Array
250
            (
251
                [main] => Array
252
                    (
253
                        [context] => main
254
                        [pagetempates] => Array
255
                            (
256
                                [full-width-page] => Full width page
257
                                [homepage] => Home page
258
                                [sidebar-page] => Page with left sidebar
259
                            )
260
261
                    )
262
263
            )
264
        */
265
266
        $folder = $this->registry->getRepository('KunstmaanMediaBundle:Folder')->findOneBy(array('rel' => 'image'));
267
        $images = $this->registry->getRepository('KunstmaanMediaBundle:Media')->findBy(
268
            array('folder' => $folder, 'deleted' => false),
269
            array(),
270
            2
271
        );
272
273
        // Get all the available pages
274
        $finder = new Finder();
275
        $finder->files()->in($this->bundle->getPath() . '/Entity/Pages')->name('*.php');
276
277
        $pages = array();
278
        foreach ($finder as $pageFile) {
279
            $parts     = explode("/", $pageFile);
280
            $className = basename($parts[count($parts) - 1], '.php');
281
282
            $contents = file_get_contents($pageFile);
283
            if (strpos($contents, 'abstract class') === false && strpos($contents, 'interface ') === false && strpos($contents, 'trait ') === false) {
284
                $classNamespace = '\\' . $this->bundle->getNamespace() . '\Entity\Pages\\' . $className;
285
                $entity         = new $classNamespace;
286
287
                if (!method_exists($entity, 'getPagePartAdminConfigurations') || !method_exists(
288
                        $entity,
289
                        'getPageTemplates'
290
                    )
291
                ) {
292
                    continue;
293
                }
294
295
                $ppConfigs = $entity->getPagePartAdminConfigurations();
296
                $ptConfigs = $entity->getPageTemplates();
297
298
                foreach ($ppConfigs as $ppConfig) {
299
                    $parts            = explode(":", $ppConfig);
300
                    $ppConfigFilename = $parts[count($parts) - 1];
301
302
                    // Context found in this Page class
303
                    if (array_key_exists($ppConfigFilename, $sectionInfo)) {
304
                        // Search for templates
305
                        foreach ($ptConfigs as $ptConfig) {
306
                            $parts            = explode(":", $ptConfig);
307
                            $ptConfigFilename = $parts[count($parts) - 1];
308
309
                            // Page template found
310
                            if (array_key_exists($ptConfigFilename, $sectionInfo[$ppConfigFilename]['pagetempates'])) {
311
                                // Get all page properties
312
                                $form     = $this->container->get('form.factory')->create($entity->getDefaultAdminType());
313
                                $children = $form->createView()->children;
314
315
                                $pageFields = array();
316
                                foreach ($children as $field) {
317
                                    $name   = $field->vars['name'];
318
                                    $attr   = $field->vars['attr'];
319
                                    $blocks = $field->vars['block_prefixes'];
320
321
                                    if ($name == 'title' || $name == 'pageTitle') {
322
                                        continue;
323
                                    }
324
325
                                    if ($blocks[1] == 'hidden') {
326
                                        // do nothing
327
                                    } elseif ($blocks[1] == 'choice' && $blocks[1] == 'entity') {
328
                                        // do nothing
329
                                    } elseif ($blocks[1] == 'datetime') {
330
                                        $pageFields[]['datetime'] = array(
331
                                            'label'       => $this->labelCase($name),
332
                                            'date_random' => DateTime::date('d/m/Y'),
333
                                            'time_random' => DateTime::time('H:i')
334
                                        );
335
                                    } elseif ($blocks[1] == 'number') {
336
                                        $pageFields[]['decimal'] = array(
337
                                            'label'  => $this->labelCase($name),
338
                                            'random' => Base::randomFloat(2, 0, 99999)
339
                                        );
340
                                    } elseif ($blocks[1] == 'integer') {
341
                                        $pageFields[]['integer'] = array(
342
                                            'label'  => $this->labelCase($name),
343
                                            'random' => Base::randomNumber(3000, 99999)
344
                                        );
345
                                    } elseif ($blocks[1] == 'checkbox') {
346
                                        $pageFields[]['boolean'] = array(
347
                                            'label' => $this->labelCase($name)
348
                                        );
349
                                    } elseif ($blocks[1] == 'media') {
350
                                        $id                    = (count($images) > 0 ? $images[0]->getId() : 1);
351
                                        $pageFields[]['media'] = array(
352
                                            'label'  => $this->labelCase($name),
353
                                            'random' => $id
354
                                        );
355
                                    } elseif ($blocks[2] == 'urlchooser') {
356
                                        $pageFields[]['link'] = array(
357
                                            'label'  => $this->labelCase($name),
358
                                            'random' => 'http://www.' . strtolower(Lorem::word()) . '.com'
359
                                        );
360
                                    } elseif ($blocks[2] == 'textarea' && array_key_exists(
361
                                            'class',
362
                                            $attr
363
                                        ) && $attr['class'] == 'js-rich-editor rich-editor'
364
                                    ) {
365
                                        $pageFields[]['rich_text'] = array(
366
                                            'label'  => $this->labelCase($name),
367
                                            'random' => Lorem::sentence()
368
                                        );
369
                                    } elseif ($blocks[2] == 'textarea' || $blocks[1] == 'text') {
370
                                        $pageFields[]['text'] = array(
371
                                            'label'  => $this->labelCase($name),
372
                                            'random' => Lorem::word()
373
                                        );
374
                                    }
375
                                }
376
377
                                $pages[] = array(
378
                                    'name'     => $className,
379
                                    'section'  => $sectionInfo[$ppConfigFilename]['context'],
380
                                    'template' => $sectionInfo[$ppConfigFilename]['pagetempates'][$ptConfigFilename],
381
                                    'fields'   => $pageFields,
382
                                );
383
                            }
384
                        }
385
                    }
386
                }
387
            }
388
        }
389
390
        /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
391
            Example $pages contents:
392
            Array
393
            (
394
                [0] => Array
395
                    (
396
                        [name] => ContentPage
397
                        [section] => main
398
                        [template] => Page with left sidebar
399
                        [fields] => Array
400
                            (
401
                                ...
402
                            )
403
                    )
404
                [1] => Array
405
                    (
406
                        [name] => ContentPage
407
                        [section] => main
408
                        [template] => Full width page
409
                        [fields] => Array
410
                            (
411
                                ...
412
                            )
413
                    )
414
                [2] => Array
415
                    (
416
                        [name] => HomePage
417
                        [section] => main
418
                        [template] => Home page
419
                        [fields] => Array
420
                            (
421
                                ...
422
                            )
423
                    )
424
            )
425
        */
426
427
        // Add some random values in the field array, so that this values can be uses as test values
428
        foreach ($this->fields as $fkey => $fieldSet) {
429
            foreach ($fieldSet as $key => $values) {
430
                switch ($key) {
431
                    case 'multi_line':
432 View Code Duplication
                    case 'single_line':
433
                        $values[0]['random1'] = Lorem::word();
434
                        $values[0]['random2'] = Lorem::word();
435
                        $values[0]['lName']   = $this->labelCase($values[0]['fieldName']);
436
                        break;
437 View Code Duplication
                    case 'rich_text':
438
                        $values[0]['random1'] = Lorem::sentence();
439
                        $values[0]['random2'] = Lorem::sentence();
440
                        $values[0]['lName']   = $this->labelCase($values[0]['fieldName']);
441
                        break;
442
                    case 'link':
443
                        $values['url']['random1']      = 'http://www.' . strtolower(Lorem::word()) . '.com';
444
                        $values['url']['random2']      = 'http://www.' . strtolower(Lorem::word()) . '.com';
445
                        $values['url']['lName']        = $this->labelCase($values['url']['fieldName']);
446
                        $values['text']['random1']     = Lorem::word();
447
                        $values['text']['random2']     = Lorem::word();
448
                        $values['text']['lName']       = $this->labelCase($values['text']['fieldName']);
449
                        $values['new_window']['lName'] = $this->labelCase($values['new_window']['fieldName']);
450
                        break;
451
                    case 'image':
452
                        if (count($images) > 0) {
453
                            if (count($images) > 1) {
454
                                $values['image']['id_random1']  = $images[0]->getId();
455
                                $values['image']['url_random1'] = $images[0]->getUrl();
456
                                $values['image']['id_random2']  = $images[1]->getId();
457
                                $values['image']['url_random2'] = $images[1]->getUrl();
458
                            } else {
459
                                $values['image']['id_random1']  = $values['image']['id_random2'] = $images[0]->getId();
460
                                $values['image']['url_random1'] = $values['image']['url_random2'] = $images[0]->getUrl(
461
                                );
462
                            }
463
                        } else {
464
                            $values['image']['id_random1']  = $values['image']['id_random2'] = '1';
465
                            $values['image']['url_random1'] = $values['image']['url_random2'] = 'XXX';
466
                        }
467
                        $values['image']['lName']      = $this->labelCase($values['image']['fieldName']);
468
                        $values['alt_text']['random1'] = Lorem::word();
469
                        $values['alt_text']['random2'] = Lorem::word();
470
                        $values['alt_text']['lName']   = $this->labelCase($values['alt_text']['fieldName']);
471
                        break;
472
                    case 'boolean':
473
                        $values[0]['lName'] = $this->labelCase($values[0]['fieldName']);
474
                        break;
475 View Code Duplication
                    case 'integer':
476
                        $values[0]['random1'] = Base::randomNumber(3000, 99999);
477
                        $values[0]['random2'] = Base::randomNumber(3000, 99999);
478
                        $values[0]['lName']   = $this->labelCase($values[0]['fieldName']);
479
                        break;
480 View Code Duplication
                    case 'decimal':
481
                        $values[0]['random1'] = Base::randomFloat(2, 0, 99999);
482
                        $values[0]['random2'] = Base::randomFloat(2, 0, 99999);
483
                        $values[0]['lName']   = $this->labelCase($values[0]['fieldName']);
484
                        break;
485
                    case 'datetime':
486
                        $values[0]['date_random1']     = DateTime::date('d/m/Y');
487
                        $values[0]['date_random2']     = DateTime::date('d/m/Y');
488
                        $values[0]['time_random1']     = DateTime::time('H:i');
489
                        $values[0]['time_random2']     = DateTime::time('H:i');
490
                        $dparts                        = explode('/', $values[0]['date_random1']);
491
                        $values[0]['datetime_random1'] = $dparts[2] . '-' . $dparts[1] . '-' . $dparts[0] . ' ' . $values[0]['time_random1'] . ':00';
492
                        $dparts                        = explode('/', $values[0]['date_random2']);
493
                        $values[0]['datetime_random2'] = $dparts[2] . '-' . $dparts[1] . '-' . $dparts[0] . ' ' . $values[0]['time_random2'] . ':00';
494
                        $values[0]['lName']            = $this->labelCase($values[0]['fieldName']);
495
                        break;
496
                }
497
498
                $this->fields[$fkey][$key] = $values;
499
            }
500
        }
501
502
        $params = array(
503
            'name'   => $this->entity,
504
            'pages'  => $pages,
505
            'fields' => $this->fields
506
        );
507
        $this->renderFile(
508
            '/Features/PagePart.feature',
509
            $this->bundle->getPath() . '/Features/Admin' . $this->entity . '.feature',
510
            $params
511
        );
512
513
        $this->assistant->writeLine('Generating behat test : <info>OK</info>');
514
    }
515
516
    /**
517
     * Camel case string to space delimited string that will be used for form labels.
518
     *
519
     * @param string $text
520
     *
521
     * @return string
522
     */
523
    private function labelCase($text)
524
    {
525
        return ucfirst(str_replace('_', ' ', Container::underscore($text)));
526
    }
527
528
}
529