Issues (16)

src/Environment/LazyEnvironmentLoader.php (2 issues)

Labels
Severity
1
<?php declare(strict_types=1);
2
3
namespace Cocotte\Environment;
4
5
use Assert\Assertion;
6
use Cocotte\Console\CommandEventStore;
7
use Cocotte\Console\CommandExecuteEvent;
8
use Cocotte\Console\Style;
9
use Cocotte\Shell\Env;
10
use ProxyManager\Proxy\VirtualProxyInterface;
11
use Symfony\Component\Console\Input\InputInterface;
12
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
13
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
14
15
final class LazyEnvironmentLoader implements EventSubscriberInterface
16
{
17
    /**
18
     * @var LazyEnvironmentValue|VirtualProxyInterface[]
19
     */
20
    private $values = [];
21
    /**
22
     * @var Style
23
     */
24
    private $style;
25
    /**
26
     * @var EventDispatcherInterface
27
     */
28
    private $eventDispatcher;
29
    /**
30
     * @var Env
31
     */
32
    private $env;
33
34
    public function __construct(Style $style, EventDispatcherInterface $eventDispatcher, Env $env)
35
    {
36
        $this->style = $style;
37
        $this->eventDispatcher = $eventDispatcher;
38
        $this->env = $env;
39
    }
40
41
    public static function getSubscribedEvents()
42
    {
43
        return [
44
            CommandEventStore::COMMAND_EXECUTE => 'onCommandExecute',
45
        ];
46
    }
47
48
    public function onCommandExecute(CommandExecuteEvent $event)
49
    {
50
        $command = $event->command();
51
        if ($command instanceof LazyEnvironment) {
52
            $this->load($command, $event->input());
53
        }
54
    }
55
56
    public function registerValue(LazyEnvironmentValue $value)
57
    {
58
        $this->values[] = $value;
59
    }
60
61
    public function load(LazyEnvironment $environment, InputInterface $input)
62
    {
63
        foreach ($environment->lazyEnvironmentValues() as $className) {
64
            $lazyValue = $this->getLazyValue($className);
65
            if ($lazyValue instanceof LazyExportableOption) {
66
                $this->exportOption($input, $lazyValue);
67
            }
68
            $this->initializeProxy($lazyValue);
69
        }
70
        $this->eventDispatcher->dispatch(
71
            EnvironmentEventStore::ENVIRONMENT_LOADED,
72
            new EnvironmentLoadedEvent($environment)
73
        );
74
        $this->style->debug("Lazy loaded env:\n".print_r(getenv(), true));
0 ignored issues
show
Are you sure print_r(getenv(), true) of type string|true can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

74
        $this->style->debug("Lazy loaded env:\n"./** @scrutinizer ignore-type */ print_r(getenv(), true));
Loading history...
75
    }
76
77
    private function getLazyValue(string $className): VirtualProxyInterface
78
    {
79
        foreach ($this->values as $value) {
80
            if ($value instanceof $className) {
81
                return $value;
82
            }
83
        }
84
        throw new \Exception("Could not find '$className'");
85
    }
86
87
    private function initializeProxy(VirtualProxyInterface $lazyValue)
88
    {
89
        if ($lazyValue->isProxyInitialized()) {
90
            throw new \Exception(
91
                sprintf(
92
                    "Managing a lazy environment value ".
93
                    "'%s' which is already initialized.",
94
                    get_class($lazyValue->getWrappedValueHolderValue())
0 ignored issues
show
It seems like $lazyValue->getWrappedValueHolderValue() can also be of type null; however, parameter $object of get_class() does only seem to accept object, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

94
                    get_class(/** @scrutinizer ignore-type */ $lazyValue->getWrappedValueHolderValue())
Loading history...
95
                )
96
            );
97
        }
98
        $lazyValue->initializeProxy();
99
        if ($lazyValue instanceof LazyLoadAware) {
100
            $lazyValue->onLazyLoad($this->env);
101
        }
102
    }
103
104
    private function exportOption(InputInterface $input, LazyExportableOption $optionExportValue): void
105
    {
106
        $name = $optionExportValue::optionName();
107
        Assertion::true($input->hasOption($name), sprintf("input does not have an option named '%s'", $name));
108
        $value = $input->getOption($name);
109
        if (null !== $value) {
110
            $optionExportValue::toEnv($value, $this->env);
111
        }
112
    }
113
114
}