Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
namespace Faker\Container;
6
 
7
use Faker\Extension\Extension;
8
 
9
/**
10
 * A simple implementation of a container.
11
 *
12
 * @experimental This class is experimental and does not fall under our BC promise
13
 */
14
final class Container implements ContainerInterface
15
{
16
    /**
17
     * @var array<string, callable|object|string>
18
     */
19
    private $definitions;
20
 
21
    private $services = [];
22
 
23
    /**
24
     * Create a container object with a set of definitions. The array value MUST
25
     * produce an object that implements Extension.
26
     *
27
     * @param array<string, callable|object|string> $definitions
28
     */
29
    public function __construct(array $definitions)
30
    {
31
        $this->definitions = $definitions;
32
    }
33
 
34
    /**
35
     * Retrieve a definition from the container.
36
     *
37
     * @param string $id
38
     *
39
     * @throws \InvalidArgumentException
40
     * @throws \RuntimeException
41
     * @throws ContainerException
42
     * @throws NotInContainerException
43
     */
44
    public function get($id): Extension
45
    {
46
        if (!is_string($id)) {
47
            throw new \InvalidArgumentException(sprintf(
48
                'First argument of %s::get() must be string',
49
                self::class,
50
            ));
51
        }
52
 
53
        if (array_key_exists($id, $this->services)) {
54
            return $this->services[$id];
55
        }
56
 
57
        if (!$this->has($id)) {
58
            throw new NotInContainerException(sprintf(
59
                'There is not service with id "%s" in the container.',
60
                $id,
61
            ));
62
        }
63
 
64
        $definition = $this->definitions[$id];
65
 
66
        $service = $this->services[$id] = $this->getService($id, $definition);
67
 
68
        if (!$service instanceof Extension) {
69
            throw new \RuntimeException(sprintf(
70
                'Service resolved for identifier "%s" does not implement the %s" interface.',
71
                $id,
72
                Extension::class,
73
            ));
74
        }
75
 
76
        return $service;
77
    }
78
 
79
    /**
80
     * Get the service from a definition.
81
     *
82
     * @param callable|object|string $definition
83
     */
84
    private function getService($id, $definition)
85
    {
86
        if (is_callable($definition)) {
87
            try {
88
                return $definition();
89
            } catch (\Throwable $e) {
90
                throw new ContainerException(
91
                    sprintf('Error while invoking callable for "%s"', $id),
92
                    0,
93
                    $e,
94
                );
95
            }
96
        } elseif (is_object($definition)) {
97
            return $definition;
98
        } elseif (is_string($definition)) {
99
            if (class_exists($definition)) {
100
                try {
101
                    return new $definition();
102
                } catch (\Throwable $e) {
103
                    throw new ContainerException(sprintf('Could not instantiate class "%s"', $id), 0, $e);
104
                }
105
            }
106
 
107
            throw new ContainerException(sprintf(
108
                'Could not instantiate class "%s". Class was not found.',
109
                $id,
110
            ));
111
        } else {
112
            throw new ContainerException(sprintf(
113
                'Invalid type for definition with id "%s"',
114
                $id,
115
            ));
116
        }
117
    }
118
 
119
    /**
120
     * Check if the container contains a given identifier.
121
     *
122
     * @param string $id
123
     *
124
     * @throws \InvalidArgumentException
125
     */
126
    public function has($id): bool
127
    {
128
        if (!is_string($id)) {
129
            throw new \InvalidArgumentException(sprintf(
130
                'First argument of %s::get() must be string',
131
                self::class,
132
            ));
133
        }
134
 
135
        return array_key_exists($id, $this->definitions);
136
    }
137
 
138
    /**
139
     * Get the bindings between Extension interfaces and implementations.
140
     */
141
    public function getDefinitions(): array
142
    {
143
        return $this->definitions;
144
    }
145
}