Subversion-Projekte lars-tiefland.laravel_shop

Revision

Revision 148 | Details | Vergleich mit vorheriger | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Foundation;
4
 
5
use Exception;
6
use Illuminate\Contracts\Foundation\Application as ApplicationContract;
7
use Illuminate\Filesystem\Filesystem;
8
 
9
class ProviderRepository
10
{
11
    /**
12
     * The application implementation.
13
     *
14
     * @var \Illuminate\Contracts\Foundation\Application
15
     */
16
    protected $app;
17
 
18
    /**
19
     * The filesystem instance.
20
     *
21
     * @var \Illuminate\Filesystem\Filesystem
22
     */
23
    protected $files;
24
 
25
    /**
26
     * The path to the manifest file.
27
     *
28
     * @var string
29
     */
30
    protected $manifestPath;
31
 
32
    /**
33
     * Create a new service repository instance.
34
     *
35
     * @param  \Illuminate\Contracts\Foundation\Application  $app
36
     * @param  \Illuminate\Filesystem\Filesystem  $files
37
     * @param  string  $manifestPath
38
     * @return void
39
     */
40
    public function __construct(ApplicationContract $app, Filesystem $files, $manifestPath)
41
    {
42
        $this->app = $app;
43
        $this->files = $files;
44
        $this->manifestPath = $manifestPath;
45
    }
46
 
47
    /**
48
     * Register the application service providers.
49
     *
50
     * @param  array  $providers
51
     * @return void
52
     */
53
    public function load(array $providers)
54
    {
55
        $manifest = $this->loadManifest();
56
 
57
        // First we will load the service manifest, which contains information on all
58
        // service providers registered with the application and which services it
59
        // provides. This is used to know which services are "deferred" loaders.
60
        if ($this->shouldRecompile($manifest, $providers)) {
61
            $manifest = $this->compileManifest($providers);
62
        }
63
 
64
        // Next, we will register events to load the providers for each of the events
65
        // that it has requested. This allows the service provider to defer itself
66
        // while still getting automatically loaded when a certain event occurs.
67
        foreach ($manifest['when'] as $provider => $events) {
68
            $this->registerLoadEvents($provider, $events);
69
        }
70
 
71
        // We will go ahead and register all of the eagerly loaded providers with the
72
        // application so their services can be registered with the application as
73
        // a provided service. Then we will set the deferred service list on it.
74
        foreach ($manifest['eager'] as $provider) {
75
            $this->app->register($provider);
76
        }
77
 
78
        $this->app->addDeferredServices($manifest['deferred']);
79
    }
80
 
81
    /**
82
     * Load the service provider manifest JSON file.
83
     *
84
     * @return array|null
85
     */
86
    public function loadManifest()
87
    {
88
        // The service manifest is a file containing a JSON representation of every
89
        // service provided by the application and whether its provider is using
90
        // deferred loading or should be eagerly loaded on each request to us.
91
        if ($this->files->exists($this->manifestPath)) {
92
            $manifest = $this->files->getRequire($this->manifestPath);
93
 
94
            if ($manifest) {
95
                return array_merge(['when' => []], $manifest);
96
            }
97
        }
98
    }
99
 
100
    /**
101
     * Determine if the manifest should be compiled.
102
     *
103
     * @param  array  $manifest
104
     * @param  array  $providers
105
     * @return bool
106
     */
107
    public function shouldRecompile($manifest, $providers)
108
    {
109
        return is_null($manifest) || $manifest['providers'] != $providers;
110
    }
111
 
112
    /**
113
     * Register the load events for the given provider.
114
     *
115
     * @param  string  $provider
116
     * @param  array  $events
117
     * @return void
118
     */
119
    protected function registerLoadEvents($provider, array $events)
120
    {
121
        if (count($events) < 1) {
122
            return;
123
        }
124
 
621 lars 125
        $this->app->make('events')->listen($events, fn () => $this->app->register($provider));
148 lars 126
    }
127
 
128
    /**
129
     * Compile the application service manifest file.
130
     *
131
     * @param  array  $providers
132
     * @return array
133
     */
134
    protected function compileManifest($providers)
135
    {
136
        // The service manifest should contain a list of all of the providers for
137
        // the application so we can compare it on each request to the service
138
        // and determine if the manifest should be recompiled or is current.
139
        $manifest = $this->freshManifest($providers);
140
 
141
        foreach ($providers as $provider) {
142
            $instance = $this->createProvider($provider);
143
 
144
            // When recompiling the service manifest, we will spin through each of the
145
            // providers and check if it's a deferred provider or not. If so we'll
146
            // add it's provided services to the manifest and note the provider.
147
            if ($instance->isDeferred()) {
148
                foreach ($instance->provides() as $service) {
149
                    $manifest['deferred'][$service] = $provider;
150
                }
151
 
152
                $manifest['when'][$provider] = $instance->when();
153
            }
154
 
155
            // If the service providers are not deferred, we will simply add it to an
156
            // array of eagerly loaded providers that will get registered on every
157
            // request to this application instead of "lazy" loading every time.
158
            else {
159
                $manifest['eager'][] = $provider;
160
            }
161
        }
162
 
163
        return $this->writeManifest($manifest);
164
    }
165
 
166
    /**
167
     * Create a fresh service manifest data structure.
168
     *
169
     * @param  array  $providers
170
     * @return array
171
     */
172
    protected function freshManifest(array $providers)
173
    {
174
        return ['providers' => $providers, 'eager' => [], 'deferred' => []];
175
    }
176
 
177
    /**
178
     * Write the service manifest file to disk.
179
     *
180
     * @param  array  $manifest
181
     * @return array
182
     *
183
     * @throws \Exception
184
     */
185
    public function writeManifest($manifest)
186
    {
187
        if (! is_writable($dirname = dirname($this->manifestPath))) {
188
            throw new Exception("The {$dirname} directory must be present and writable.");
189
        }
190
 
191
        $this->files->replace(
192
            $this->manifestPath, '<?php return '.var_export($manifest, true).';'
193
        );
194
 
195
        return array_merge(['when' => []], $manifest);
196
    }
197
 
198
    /**
199
     * Create a new provider instance.
200
     *
201
     * @param  string  $provider
202
     * @return \Illuminate\Support\ServiceProvider
203
     */
204
    public function createProvider($provider)
205
    {
206
        return new $provider($this->app);
207
    }
208
}