Completed
Push — ezp_30797 ( b39740...a92ef0 )
by
unknown
17:49
created

warnAboutRelyingOnDeprecatedService()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 2
nop 2
dl 0
loc 27
rs 9.488
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
declare(strict_types=1);
8
9
namespace EzSystems\PlatformInstallerBundle\DependencyInjection\Compiler;
10
11
use EzSystems\DoctrineSchema\API\Builder\SchemaBuilder;
12
use EzSystems\PlatformInstallerBundle\Installer\CoreInstaller;
13
use EzSystems\PlatformInstallerBundle\Installer\DbBasedInstaller;
14
use Symfony\Component\DependencyInjection\ChildDefinition;
15
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Definition;
18
19
/**
20
 * Enable installer which uses SchemaBuilder.
21
 *
22
 * <code>DoctrineSchemaBundle</code> is available via <code>ezsystems/doctrine-dbal-schema</code> package.
23
 *
24
 * @see \EzSystems\DoctrineSchemaBundle\DoctrineSchemaBundle
25
 * @see \EzSystems\PlatformInstallerBundle\Installer\CoreInstaller
26
 */
27
class SchemaBuilderInstallerPass implements CompilerPassInterface
28
{
29
    const CLEAN_INSTALLER_DEF_ID = 'ezplatform.installer.clean_installer';
30
    const DB_BASED_INSTALLER_DEF_ID = 'ezplatform.installer.db_based_installer';
31
32
    /**
33
     * Replace Clean installer with CoreInstaller if required SchemaBuilder from DoctrineSchemaBundle is available.
34
     *
35
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
36
     *
37
     * @throws \Exception
38
     */
39
    public function process(ContainerBuilder $container)
40
    {
41
        if (!$container->hasAlias(SchemaBuilder::class)) {
42
            $container->removeDefinition(CoreInstaller::class);
43
            @trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
44
                sprintf(
45
                    'Using eZ Platform Installer Bundle without enabling Doctrine Schema Bundle (%s) ' .
46
                    'is deprecated since v2.5 LTS and will cause a fatal error in eZ Platform v3.0',
47
                    'https://github.com/ezsystems/doctrine-dbal-schema'
48
                ),
49
                E_USER_DEPRECATED
50
            );
51
        } elseif ($container->hasDefinition(self::CLEAN_INSTALLER_DEF_ID)) {
52
            // remove the actual definition first for alias to work properly
53
            $container->removeDefinition(self::CLEAN_INSTALLER_DEF_ID);
54
            $container->setAlias(self::CLEAN_INSTALLER_DEF_ID, CoreInstaller::class);
55
        }
56
57
        $this->warnAboutRelyingOnDeprecatedService(
58
            $container,
59
            [
60
                self::DB_BASED_INSTALLER_DEF_ID => DbBasedInstaller::class,
61
                self::CLEAN_INSTALLER_DEF_ID => CoreInstaller::class,
62
            ]
63
        );
64
    }
65
66
    /**
67
     * Find usages of deprecated service definitions in custom services.
68
     *
69
     * Note: natural choice would be to use `deprecated` attribute in DIC instead, however
70
     * in Symfony 3.4 neither deprecating service alias nor deprecating abstract service gives
71
     * proper warning in the application logs.
72
     *
73
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
74
     * @param string[] a map of old to new names (associative array)
75
     */
76
    private function warnAboutRelyingOnDeprecatedService(
77
        ContainerBuilder $container,
78
        array $oldNewNameMap
79
    ): void {
80
        // find usages of deprecated definitions as parents
81
        /** @var \Symfony\Component\DependencyInjection\ChildDefinition[] $deprecatedParentDefinitions */
82
        $deprecatedParentDefinitions = array_filter(
83
            $container->getDefinitions(),
84
            function (Definition $definition) use ($oldNewNameMap) {
85
                return $definition instanceof ChildDefinition
86
                    && array_key_exists($definition->getParent(), $oldNewNameMap);
87
            }
88
        );
89
        // trigger deprecation warnings to be logged
90
        foreach ($deprecatedParentDefinitions as $id => $definition) {
91
            $parent = $definition->getParent();
92
            @trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
93
                sprintf(
94
                    'The service definition "%s" relies on the deprecated "%s" service. Use "%s" instead',
95
                    $id,
96
                    $parent,
97
                    $oldNewNameMap[$parent]
98
                ),
99
                E_USER_DEPRECATED
100
            );
101
        }
102
    }
103
}
104