Issues (3099)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

GeneratorBundle/Generator/KunstmaanGenerator.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\Generator;
4
5
use Doctrine\Common\Inflector\Inflector;
6
use Doctrine\ORM\Mapping\ClassMetadataInfo;
7
use Doctrine\ORM\Mapping\UnderscoreNamingStrategy;
8
use Doctrine\ORM\Tools\EntityGenerator;
9
use Doctrine\ORM\Tools\EntityRepositoryGenerator;
10
use Kunstmaan\GeneratorBundle\Helper\CommandAssistant;
11
use Kunstmaan\GeneratorBundle\Helper\GeneratorUtils;
12
use Sensio\Bundle\GeneratorBundle\Generator\Generator;
13
use Symfony\Bridge\Doctrine\RegistryInterface;
14
use Symfony\Component\DependencyInjection\ContainerInterface;
15
use Symfony\Component\Filesystem\Filesystem;
16
use Symfony\Component\Finder\Finder;
17
use Symfony\Component\HttpKernel\Bundle\BundleInterface;
18
use Symfony\Component\HttpKernel\Kernel;
19
use Twig\Environment;
20
use Twig\Lexer;
21
use Twig\Loader\FilesystemLoader;
22
23
/**
24
 * Class that contains all common generator logic.
25
 */
26
class KunstmaanGenerator extends Generator
27
{
28
    /**
29
     * @var Filesystem
30
     */
31
    protected $filesystem;
32
33
    /**
34
     * @var RegistryInterface
35
     */
36
    protected $registry;
37
38
    /**
39
     * @var string
40
     */
41
    protected $skeletonDir;
42
43
    /**
44
     * @var CommandAssistant
45
     */
46
    protected $assistant;
47
48
    /**
49
     * @var ContainerInterface
50
     */
51
    protected $container;
52
53
    /**
54
     * @param Filesystem         $filesystem  The filesystem
55
     * @param RegistryInterface  $registry    The registry
56
     * @param string             $skeletonDir The directory of the skeleton
57
     * @param CommandAssistant   $assistant   The command assistant
58
     * @param ContainerInterface $container   The container
59
     */
60 1
    public function __construct(
61
        Filesystem $filesystem,
62
        RegistryInterface $registry,
63
        $skeletonDir,
64
        CommandAssistant $assistant,
65
        ContainerInterface $container = null
66
    ) {
67 1
        $this->filesystem = $filesystem;
68 1
        $this->registry = $registry;
69 1
        $this->skeletonDir = GeneratorUtils::getFullSkeletonPath($skeletonDir);
70 1
        $this->assistant = $assistant;
71 1
        $this->container = $container;
72
73 1
        $this->setSkeletonDirs(array($this->skeletonDir, GeneratorUtils::getFullSkeletonPath('/common')));
74 1
    }
75
76
    /**
77
     * Check that the keyword is a reserved word for the database system.
78
     *
79
     * @param string $keyword
80
     *
81
     * @return bool
82
     */
83
    public function isReservedKeyword($keyword)
84
    {
85
        return $this->registry->getConnection()->getDatabasePlatform()->getReservedKeywordsList()->isKeyword($keyword);
86
    }
87
88
    /**
89
     * Generate the entity PHP code.
90
     *
91
     * @param BundleInterface $bundle
92
     * @param string          $name
93
     * @param array           $fields
94
     * @param string          $namePrefix
95
     * @param string          $dbPrefix
96
     * @param string|null     $extendClass
97
     * @param bool            $withRepository
98
     *
99
     * @return array
100
     *
101
     * @throws \RuntimeException
102
     */
103
    protected function generateEntity(
104
        BundleInterface $bundle,
105
        $name,
106
        $fields,
107
        $namePrefix,
108
        $dbPrefix,
109
        $extendClass = null,
110
        $withRepository = false
111
    ) {
112
        // configure the bundle (needed if the bundle does not contain any Entities yet)
113
        $config = $this->registry->getManager(null)->getConfiguration();
114
        $config->setEntityNamespaces(
115
            array_merge(
116
                array($bundle->getName() => $bundle->getNamespace() . '\\Entity' . ($namePrefix ? '\\' . $namePrefix : '')),
117
                $config->getEntityNamespaces()
118
            )
119
        );
120
121
        $entityClass = $this->registry->getAliasNamespace($bundle->getName()) . ($namePrefix ? '\\' . $namePrefix : '') . '\\' . $name;
122
        $entityPath = $bundle->getPath() . '/Entity/' . ($namePrefix ? $namePrefix . '/' : '') . str_replace('\\', '/', $name) . '.php';
123
        if (file_exists($entityPath)) {
124
            throw new \RuntimeException(sprintf('Entity "%s" already exists.', $entityClass));
125
        }
126
127
        $class = new ClassMetadataInfo($entityClass, new UnderscoreNamingStrategy());
128
        if ($withRepository) {
129
            if ($this->isSymfony4()) {
130
                $repositoryClass = preg_replace('/\\\\Entity\\\\/', '\\Repository\\', $entityClass, 1) . 'Repository';
131
                $class->customRepositoryClassName = $repositoryClass;
132
                $this->getSymfony4RepositoryGenerator()->writeEntityRepositoryClass($entityClass, $repositoryClass, $bundle->getPath());
133
            } else {
134
                $entityClass = preg_replace('/\\\\Entity\\\\/', '\\Repository\\', $entityClass, 1);
135
                $class->customRepositoryClassName = $entityClass.'Repository';
136
                $path = $bundle->getPath().str_repeat('/..', substr_count(get_class($bundle), '\\'));
137
                $this->getRepositoryGenerator()->writeEntityRepositoryClass($class->customRepositoryClassName, $path);
138
            }
139
        }
140
141
        foreach ($fields as $fieldSet) {
142
            foreach ($fieldSet as $fieldArray) {
143
                foreach ($fieldArray as $field) {
144
                    if (array_key_exists('joinColumn', $field)) {
145
                        $class->mapManyToOne($field);
146
                    } elseif (array_key_exists('joinTable', $field)) {
147
                        $class->mapManyToMany($field);
148
                    } else {
149
                        $class->mapField($field);
150
                    }
151
                }
152
            }
153
        }
154
        $class->setPrimaryTable(
155
            array(
156
                'name' => strtolower($dbPrefix) . Inflector::tableize(Inflector::pluralize($name)),
157
            )
158
        );
159
        $entityCode = $this->getEntityGenerator($extendClass)->generateEntityClass($class);
160
161
        return array($entityCode, $entityPath);
162
    }
163
164
    /**
165
     * Get a Doctrine EntityGenerator instance.
166
     *
167
     * @param string|null $classToExtend
168
     *
169
     * @return EntityGenerator
170
     */
171
    protected function getEntityGenerator($classToExtend = null)
172
    {
173
        $entityGenerator = new EntityGenerator();
174
        if (!is_null($classToExtend)) {
175
            $entityGenerator->setClassToExtend($classToExtend);
176
        }
177
        $entityGenerator->setGenerateAnnotations(true);
178
        $entityGenerator->setGenerateStubMethods(true);
179
        $entityGenerator->setRegenerateEntityIfExists(false);
180
        $entityGenerator->setUpdateEntityIfExists(true);
181
        $entityGenerator->setNumSpaces(4);
182
        $entityGenerator->setAnnotationPrefix('ORM\\');
183
184
        return $entityGenerator;
185
    }
186
187
    /**
188
     * Generate the entity admin type.
189
     *
190
     * @param        $bundle
191
     * @param        $entityName
192
     * @param        $entityPrefix
193
     * @param array  $fields
194
     * @param string $extendClass
195
     */
196
    protected function generateEntityAdminType(
197
        $bundle,
198
        $entityName,
199
        $entityPrefix,
200
        array $fields,
201
        $extendClass = '\Symfony\Component\Form\AbstractType'
202
    ) {
203
        $className = $entityName . 'AdminType';
204
        $savePath = $bundle->getPath() . '/Form/' . $entityPrefix . '/' . $className . '.php';
205
        $name = str_replace(
206
                '\\',
207
                '_',
208
                strtolower($bundle->getNamespace())
209
            ) . '_' . strtolower($entityName) . 'type';
210
211
        $params = array(
212
            'className' => $className,
213
            'name' => $name,
214
            'namespace' => $bundle->getNamespace(),
215
            'entity' => '\\' . $bundle->getNamespace() . '\Entity\\' . $entityPrefix . '\\' . $entityName,
216
            'fields' => $fields,
217
            'entity_prefix' => $entityPrefix,
218
            'extend_class' => $extendClass,
219
        );
220
        $this->renderFile('/Form/EntityAdminType.php', $savePath, $params);
221
    }
222
223
    /**
224
     * Install the default page templates.
225
     *
226
     * @param BundleInterface $bundle
227
     */
228
    protected function installDefaultPageTemplates($bundle)
229
    {
230
        // Configuration templates
231 View Code Duplication
        if ($this->isSymfony4()) {
232
            $dirPath = $this->container->getParameter('kernel.project_dir') . '/config/kunstmaancms/pagetemplates/';
233
        } else {
234
            $dirPath = sprintf('%s/Resources/config/pagetemplates/', $bundle->getPath());
235
        }
236
237
        $skeletonDir = sprintf('%s/Resources/config/pagetemplates/', GeneratorUtils::getFullSkeletonPath('/common'));
238
239
        // Only copy templates over when the folder does not exist yet...
240
        if (!$this->filesystem->exists($dirPath)) {
241
            $files = array(
242
                'default-one-column.yml',
243
                'default-two-column-left.yml',
244
                'default-two-column-right.yml',
245
                'default-three-column.yml',
246
            );
247
            foreach ($files as $file) {
248
                $this->filesystem->copy($skeletonDir . $file, $dirPath . $file, false);
249
                GeneratorUtils::replace('~~~BUNDLE~~~', $bundle->getName(), $dirPath . $file);
250
            }
251
        }
252
253
        // Twig templates
254
        $dirPath = $this->getTemplateDir($bundle) . '/Pages/Common/';
255
256
        $skeletonDir = sprintf('%s/Resources/views/Pages/Common/', GeneratorUtils::getFullSkeletonPath('/common'));
257
258
        if (!$this->filesystem->exists($dirPath)) {
259
            $files = array(
260
                'one-column-pagetemplate.html.twig',
261
                'two-column-left-pagetemplate.html.twig',
262
                'two-column-right-pagetemplate.html.twig',
263
                'three-column-pagetemplate.html.twig',
264
            );
265
            foreach ($files as $file) {
266
                $this->filesystem->copy($skeletonDir . $file, $dirPath . $file, false);
267
            }
268
            $this->filesystem->copy($skeletonDir . 'view.html.twig', $dirPath . 'view.html.twig', false);
269
        }
270
271
        $contents = file_get_contents($dirPath . 'view.html.twig');
272
273
        $twigFile = $this->isSymfony4() ?
274
            $twigFile = "{% extends 'Layout/layout.html.twig' %}\n" :
275
            $twigFile = "{% extends '".$bundle->getName().":Layout:layout.html.twig' %}\n"
276
        ;
277
278
        if (strpos($contents, '{% extends ') === false) {
279
            GeneratorUtils::prepend(
280
                $twigFile,
281
                $dirPath . 'view.html.twig'
282
            );
283
        }
284
    }
285
286
    /**
287
     * Install the default pagepart configuration.
288
     *
289
     * @param BundleInterface $bundle
290
     */
291
    protected function installDefaultPagePartConfiguration($bundle)
292
    {
293
        // Pagepart configuration
294 View Code Duplication
        if ($this->isSymfony4()) {
295
            $dirPath = $this->container->getParameter('kernel.project_dir') . '/config/kunstmaancms/pageparts/';
296
        } else {
297
            $dirPath = sprintf('%s/Resources/config/pageparts/', $bundle->getPath());
298
        }
299
300
        $skeletonDir = sprintf('%s/Resources/config/pageparts/', GeneratorUtils::getFullSkeletonPath('/common'));
301
302
        // Only copy when folder does not exist yet
303
        if (!$this->filesystem->exists($dirPath)) {
304
            $files = array('footer.yml', 'main.yml', 'left-sidebar.yml', 'right-sidebar.yml');
305
            foreach ($files as $file) {
306
                $this->filesystem->copy($skeletonDir . $file, $dirPath . $file, false);
307
            }
308
        }
309
    }
310
311
    /**
312
     * Render all files in the source directory and copy them to the target directory.
313
     *
314
     * @param string $sourceDir  The source directory where we need to look in
315
     * @param string $targetDir  The target directory where we need to copy the files too
316
     * @param array  $parameters The parameters that will be passed to the templates
317
     * @param bool   $override   Whether to override an existing file or not
318
     * @param bool   $recursive  Whether to render all files recursively or not
319
     */
320 1
    public function renderFiles($sourceDir, $targetDir, array $parameters, $override = false, $recursive = true)
321
    {
322
        // Make sure the source -and target dir contain a trailing slash
323 1
        $sourceDir = rtrim($sourceDir, '/') . '/';
324 1
        $targetDir = rtrim($targetDir, '/') . '/';
325
326 1
        $this->setSkeletonDirs(array($sourceDir));
327
328 1
        $finder = new Finder();
329 1
        $finder->files()->in($sourceDir);
330 1
        if (!$recursive) {
331
            $finder->depth('== 0');
332
        }
333
334
        // Get all files in the source directory
335 1
        foreach ($finder as $file) {
336 1
            $name = $file->getRelativePathname();
337
338
            // Check that we are allowed to overwrite the file if it already exists
339 1 View Code Duplication
            if (!is_file($targetDir . $name) || $override === true) {
340 1
                $fileParts = explode('.', $name);
341 1
                if (end($fileParts) === 'twig') {
342 1
                    $this->renderTwigFile($name, $targetDir . $name, $parameters, $sourceDir);
343
                } else {
344
                    $this->renderFile($name, $targetDir . $name, $parameters);
345
                }
346
            }
347
        }
348 1
    }
349
350
    /**
351
     * Render all files in the source directory and copy them to the target directory.
352
     *
353
     * @param string      $sourceDir      The source directory where we need to look in
354
     * @param string      $targetDir      The target directory where we need to copy the files too
355
     * @param string      $filename       The name of the file that needs to be rendered
356
     * @param array       $parameters     The parameters that will be passed to the templates
357
     * @param bool        $override       Whether to override an existing file or not
358
     * @param string|null $targetFilename The name of the target file (if null, then use $filename)
359
     */
360 1
    public function renderSingleFile($sourceDir, $targetDir, $filename, array $parameters, $override = false, $targetFilename = null)
361
    {
362
        // Make sure the source -and target dir contain a trailing slash
363 1
        $sourceDir = rtrim($sourceDir, '/') . '/';
364 1
        $targetDir = rtrim($targetDir, '/') . '/';
365 1
        if (is_null($targetFilename)) {
366 1
            $targetFilename = $filename;
367
        }
368
369 1
        $this->setSkeletonDirs(array($sourceDir));
370
371 1 View Code Duplication
        if (is_file($sourceDir . $filename)) {
372
            // Check that we are allowed the overwrite the file if it already exists
373 1
            if (!is_file($targetDir . $targetFilename) || $override === true) {
374 1
                $fileParts = explode('.', $filename);
375 1
                if (end($fileParts) === 'twig') {
376 1
                    $this->renderTwigFile($filename, $targetDir . $targetFilename, $parameters, $sourceDir);
377
                } else {
378 1
                    $this->renderFile($filename, $targetDir . $targetFilename, $parameters);
379
                }
380
            }
381
        }
382 1
    }
383
384
    /**
385
     * Render a file and make it executable.
386
     *
387
     * @param string $sourceDir  The source directory where we need to look in
388
     * @param string $targetDir  The target directory where we need to copy the files too
389
     * @param string $filename   The name of the file that needs to be rendered
390
     * @param array  $parameters The parameters that will be passed to the templates
391
     * @param bool   $override   Whether to override an existing file or not
392
     * @param int    $mode       The mode
393
     */
394
    public function renderExecutableFile($sourceDir, $targetDir, $filename, array $parameters, $override = false, $mode = 0774)
395
    {
396
        $this->renderSingleFile($sourceDir, $targetDir, $filename, $parameters, $override);
397
398
        $targetDir = rtrim($targetDir, '/') . '/';
399
        $targetFile = $targetDir . $filename;
400
        $this->filesystem->chmod($targetFile, $mode);
401
    }
402
403
    /**
404
     * Copy all files in the source directory to the target directory.
405
     *
406
     * @param string $sourceDir The source directory where we need to look in
407
     * @param string $targetDir The target directory where we need to copy the files too
408
     * @param bool   $override  Whether to override an existing file or not
409
     */
410
    public function copyFiles($sourceDir, $targetDir, $override = false)
411
    {
412
        // Make sure the source -and target dir contain a trailing slash
413
        $sourceDir = rtrim($sourceDir, '/') . '/';
414
        $targetDir = rtrim($targetDir, '/') . '/';
415
416
        $this->filesystem->mirror($sourceDir, $targetDir, null, array('override' => $override));
417
    }
418
419
    /**
420
     * Remove a directory from the filesystem.
421
     *
422
     * @param string $targetDir
423
     */
424
    public function removeDirectory($targetDir)
425
    {
426
        // Make sure the target dir contain a trailing slash
427
        $targetDir = rtrim($targetDir, '/') . '/';
428
429
        $this->filesystem->remove($targetDir);
430
    }
431
432
    /**
433
     * Remove a file from the filesystem.
434
     *
435
     * @param string $file
436
     */
437
    public function removeFile($file)
438
    {
439
        $this->filesystem->remove($file);
440
    }
441
442
    /**
443
     * Render a twig file with custom twig tags.
444
     *
445
     * @param string $template
446
     * @param array  $parameters
447
     * @param string $sourceDir
448
     *
449
     * @return string
450
     */
451 1
    public function renderTwig($template, array $parameters, $sourceDir)
452
    {
453 1
        $twig = new Environment(
454 1
            new FilesystemLoader(array($sourceDir)), array(
455 1
                'debug' => true,
456
                'cache' => false,
457
                'strict_variables' => true,
458
                'autoescape' => false,
459
            )
460
        );
461
462
        // Ruby erb template syntax
463 1
        $lexer = new Lexer(
464 1
            $twig, array(
465 1
                'tag_comment' => array('<%#', '%>'),
466
                'tag_block' => array('<%', '%>'),
467
                'tag_variable' => array('<%=', '%>'),
468
            )
469
        );
470
471 1
        $twig->setLexer($lexer);
472
473 1
        return $twig->render($template, $parameters);
474
    }
475
476
    /**
477
     * Render a twig file, and save it to disk.
478
     *
479
     * @param string $template
480
     * @param string $target
481
     * @param array  $parameters
482
     * @param string $sourceDir
483
     *
484
     * @return int
485
     */
486 1
    public function renderTwigFile($template, $target, array $parameters, $sourceDir)
487
    {
488 1
        if (!is_dir(dirname($target))) {
489 1
            mkdir(dirname($target), 0777, true);
490
        }
491
492 1
        return file_put_contents($target, $this->renderTwig($template, $parameters, $sourceDir));
493
    }
494
495
    /**
496
     * @return \Doctrine\ORM\Tools\EntityRepositoryGenerator
497
     */
498
    protected function getRepositoryGenerator()
499
    {
500
        return new EntityRepositoryGenerator();
0 ignored issues
show
Deprecated Code introduced by
The class Doctrine\ORM\Tools\EntityRepositoryGenerator has been deprecated with message: 2.7 This class is being removed from the ORM and won't have any replacement

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
501
    }
502
503
    /**
504
     * @return \Kunstmaan\GeneratorBundle\Generator\Symfony4EntityRepositoryGenerator
505
     */
506
    protected function getSymfony4RepositoryGenerator()
507
    {
508
        return new \Kunstmaan\GeneratorBundle\Generator\Symfony4EntityRepositoryGenerator();
509
    }
510
511
    /**
512
     * @internal
513
     */
514 1 View Code Duplication
    protected function getTemplateDir(BundleInterface $bundle)
515
    {
516 1
        if ($this->isSymfony4()) {
517 1
            return $this->container->getParameter('kernel.project_dir') . '/templates';
518
        }
519
520
        return $bundle->getPath() . '/Resources/views';
521
    }
522
523
    /**
524
     * @internal
525
     */
526 View Code Duplication
    protected function getAssetsDir(BundleInterface $bundle)
527
    {
528
        if ($this->isSymfony4()) {
529
            return $this->container->getParameter('kernel.project_dir') . '/assets';
530
        }
531
532
        return $bundle->getPath() . '/Resources';
533
    }
534
535
    /**
536
     * @internal
537
     */
538 1
    protected function isSymfony4()
539
    {
540 1
        return Kernel::VERSION_ID >= 40000;
541
    }
542
}
543