Issues (30)

src/Bridges/LeagueContainer.php (1 issue)

Labels
Severity
1
<?php
2
3
namespace Nip\Container\Bridges;
4
5
use Closure;
6
use League\Container\Container as Container;
7
use League\Container\Definition\Definition;
8
use League\Container\Definition\DefinitionAggregateInterface;
9
use League\Container\Definition\DefinitionInterface;
10
use League\Container\Exception\NotFoundException;
11
use League\Container\Inflector\InflectorAggregateInterface;
12
use League\Container\ServiceProvider\ServiceProviderAggregateInterface;
13
use LogicException;
14
use Nip\Container\Traits\ContainerArrayAccessTrait;
15
16
/**
17
 * Class LeagueContainer
18
 * @package Nip\Container\Bridges
19
 */
20
abstract class LeagueContainer extends Container implements BridgeInterface
21
{
22
    protected $reflectionContainer;
23
24
    use ContainerArrayAccessTrait;
25
26
    /**
27 2
     * @inheritdoc
28
     */
29 2
    public function __construct(
30
        DefinitionAggregateInterface $definitions = null,
31
        ServiceProviderAggregateInterface $providers = null,
32
        InflectorAggregateInterface $inflectors = null
33
    ) {
34
        parent::__construct($definitions, $providers, $inflectors);
35
36
        $this->reflectionContainer = new \League\Container\ReflectionContainer;
37
38
        // register the reflection container as a delegate to enable auto wiring
39
        $this->delegate($this->reflectionContainer);
40
    }
41
42
    /**
43
     * The registered type aliases.
44
     *
45
     * @var array
46
     */
47
    protected $aliases = [];
48
49
    /**
50
     * @inheritdoc
51
     */
52
    public function set($alias, $concrete = null, $share = false)
53
    {
54
        return $this->add($alias, $concrete, $share);
55
    }
56
57
    /**
58
     * @inheritDoc
59
     */
60
    public function add(string $id, $concrete = null, bool $shared = null): DefinitionInterface
61
    {
62
        // Overwrite definition if already exists
63
        if ($this->definitions->has($id)) {
64
            $concrete = $concrete ?? $id;
65
            $shared = $shared ?? $this->defaultToShared;
66
67
            $definition = $this->definitions->getDefinition($id);
68
            $definition->setConcrete($concrete);
69
            $definition->setShared($shared);
70
            return $definition;
71
        }
72
        return parent::add($id, $concrete, $shared);
73
    }
74
75
76
    /**
77
     * @inheritdoc
78
     */
79
    public function remove($alias)
80
    {
81
    }
82
83
    /**
84
     * Determine if a given string is an alias.
85
     *
86
     * @param  string $name
87
     * @return bool
88
     */
89
    public function isAlias($name)
90
    {
91
        return isset($this->aliases[$name]);
92
    }
93
94
    /**
95
     * Alias a type to a different name.
96
     *
97
     * @param  string $abstract
98
     * @param  string $alias
99
     * @return void
100
     */
101
    public function alias($abstract, $alias)
102
    {
103
        $this->aliases[$alias] = $abstract;
104
//        $this->abstractAliases[$abstract][] = $alias;
105
106
        $this->share($alias, function () use ($abstract) {
107
            return $this->get($abstract);
108
        });
109
    }
110
111
    /**
112
     * Get the alias for an abstract if available.
113
     *
114
     * @param  string $abstract
115
     * @return string
116
     *
117
     * @throws \LogicException
118
     */
119
    public function getAlias($abstract)
120
    {
121
        if (!isset($this->aliases[$abstract])) {
122
            return $abstract;
123
        }
124
        if ($this->aliases[$abstract] === $abstract) {
125
            throw new LogicException("[{$abstract}] is aliased to itself.");
126
        }
127
        return $this->getAlias($this->aliases[$abstract]);
128
    }
129
130
    /**
131
     * An alias function name for make().
132
     *
133
     * @param string|callable $abstract
134
     * @param array $parameters
135
     * @return mixed
136
     * @throws \ReflectionException
137
     */
138
    public function makeWith($abstract, array $parameters = [])
139
    {
140
        return $this->make($abstract, $parameters);
141
    }
142
143
    /**
144
     * Resolve the given type from the container.
145
     *
146
     * @param string|callable $abstract
147
     * @param array $parameters
148
     * @return mixed
149
     * @throws \ReflectionException
150
     */
151
    public function make($abstract, array $parameters = [])
152
    {
153
        try {
154
            $definition = $this->extend($abstract);
0 ignored issues
show
It seems like $abstract can also be of type callable; however, parameter $id of League\Container\Container::extend() does only seem to accept string, 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

154
            $definition = $this->extend(/** @scrutinizer ignore-type */ $abstract);
Loading history...
155
            $newDefinition = new Definition($definition->getAlias(), $definition->getConcrete());
156
            $newDefinition->addArguments($parameters);
157
            return $newDefinition->resolve();
158
        } catch (NotFoundException $exception) {
159
            return $this->build($abstract, $parameters);
160
        }
161
    }
162
163
    /**
164
     * @param $concrete
165
     * @param array $parameters
166
     * @return mixed
167
     * @throws \ReflectionException
168
     */
169
    protected function build($concrete, array $parameters)
170
    {
171
        // If the concrete type is actually a Closure, we will just execute it and
172
        // hand back the results of the functions, which allows functions to be
173
        // used as resolvers for more fine-tuned resolution of these objects.
174
        if ($concrete instanceof Closure) {
175
            return $concrete($this, $parameters);
176
        }
177
        return $this->reflectionContainer->get($concrete, $parameters);
178
    }
179
}
180