Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | 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
 
125
        $this->app->make('events')->listen($events, function () use ($provider) {
126
            $this->app->register($provider);
127
        });
128
    }
129
 
130
    /**
131
     * Compile the application service manifest file.
132
     *
133
     * @param  array  $providers
134
     * @return array
135
     */
136
    protected function compileManifest($providers)
137
    {
138
        // The service manifest should contain a list of all of the providers for
139
        // the application so we can compare it on each request to the service
140
        // and determine if the manifest should be recompiled or is current.
141
        $manifest = $this->freshManifest($providers);
142
 
143
        foreach ($providers as $provider) {
144
            $instance = $this->createProvider($provider);
145
 
146
            // When recompiling the service manifest, we will spin through each of the
147
            // providers and check if it's a deferred provider or not. If so we'll
148
            // add it's provided services to the manifest and note the provider.
149
            if ($instance->isDeferred()) {
150
                foreach ($instance->provides() as $service) {
151
                    $manifest['deferred'][$service] = $provider;
152
                }
153
 
154
                $manifest['when'][$provider] = $instance->when();
155
            }
156
 
157
            // If the service providers are not deferred, we will simply add it to an
158
            // array of eagerly loaded providers that will get registered on every
159
            // request to this application instead of "lazy" loading every time.
160
            else {
161
                $manifest['eager'][] = $provider;
162
            }
163
        }
164
 
165
        return $this->writeManifest($manifest);
166
    }
167
 
168
    /**
169
     * Create a fresh service manifest data structure.
170
     *
171
     * @param  array  $providers
172
     * @return array
173
     */
174
    protected function freshManifest(array $providers)
175
    {
176
        return ['providers' => $providers, 'eager' => [], 'deferred' => []];
177
    }
178
 
179
    /**
180
     * Write the service manifest file to disk.
181
     *
182
     * @param  array  $manifest
183
     * @return array
184
     *
185
     * @throws \Exception
186
     */
187
    public function writeManifest($manifest)
188
    {
189
        if (! is_writable($dirname = dirname($this->manifestPath))) {
190
            throw new Exception("The {$dirname} directory must be present and writable.");
191
        }
192
 
193
        $this->files->replace(
194
            $this->manifestPath, '<?php return '.var_export($manifest, true).';'
195
        );
196
 
197
        return array_merge(['when' => []], $manifest);
198
    }
199
 
200
    /**
201
     * Create a new provider instance.
202
     *
203
     * @param  string  $provider
204
     * @return \Illuminate\Support\ServiceProvider
205
     */
206
    public function createProvider($provider)
207
    {
208
        return new $provider($this->app);
209
    }
210
}