Completed
Push — master ( 46c45d...1f3eb2 )
by Aivis
14s
created

UnderstandLaravel5ServiceProvider::provides()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 0
1
<?php namespace Understand\UnderstandLaravel5;
2
3
use Illuminate\Support\ServiceProvider;
4
use Illuminate\Foundation\AliasLoader;
5
use Illuminate\Support\Str;
6
use Illuminate\Foundation\Application;
7
use Illuminate\Database\Eloquent\Model as EloquentModel;
8
9
class UnderstandLaravel5ServiceProvider extends ServiceProvider
10
{
11
12
	/**
13
	 * Indicates if loading of the provider is deferred.
14
	 *
15
	 * @var bool
16
	 */
17
	protected $defer = false;
18
19
	/**
20
	 * Bootstrap the application events.
21
	 *
22
	 * @return void
23
	 */
24
	public function boot()
25
	{
26
        $configPath = __DIR__ . '/../../config/understand-laravel.php';
27
        $this->publishes([$configPath => config_path('understand-laravel.php')], 'config');
28
29
        if ($this->app['config']->get('understand-laravel.log_types.eloquent_log.enabled'))
30
        {
31
            $this->listenEloquentEvents();
32
        }
33
34
        if ($this->app['config']->get('understand-laravel.log_types.laravel_log.enabled'))
35
        {
36
            $this->listenLaravelEvents();
37
        }
38
	}
39
40
	/**
41
	 * Register the service provider.
42
	 *
43
	 * @return void
44
	 */
45
	public function register()
46
	{
47
		$this->registerConfig();
48
        $this->registerFieldProvider();
49
        $this->registerTokenProvider();
50
        $this->registerLogger();
51
        $this->registerModelEventListenerProvider();
52
        $this->registerExceptionEncoder();
53
        $this->registerExceptionLogger();
54
	}
55
56
    /**
57
     * Register config
58
     *
59
     * @return void
60
     */
61
    protected function registerConfig()
62
    {
63
        $configPath = __DIR__ . '/../../config/understand-laravel.php';
64
        $this->mergeConfigFrom($configPath, 'understand-laravel');
65
    }
66
67
    /**
68
     * Register field provider
69
     *
70
     * @return void
71
     */
72
    protected function registerFieldProvider()
73
    {
74
        $this->app->bind('understand.field-provider', function($app)
75
        {
76
            $fieldProvider = new FieldProvider();
77
78
	    if ($app['config']['session.driver']) 
79
	    {
80
                $fieldProvider->setSessionStore($app['session.store']);
81
            }
82
            $fieldProvider->setRouter($app['router']);
83
            $fieldProvider->setRequest($app['request']);
84
            $fieldProvider->setEnvironment($app->environment());
85
            $fieldProvider->setTokenProvider($app['understand.token-provider']);
86
87
            return $fieldProvider;
88
        });
89
90
        $this->app->booting(function()
91
        {
92
            $loader = AliasLoader::getInstance();
93
            $loader->alias('UnderstandFieldProvider', 'Understand\UnderstandLaravel5\Facades\UnderstandFieldProvider');
94
        });
95
    }
96
97
    /**
98
     * Register token generator class
99
     *
100
     * @return void
101
     */
102
    protected function registerTokenProvider()
103
    {
104
        $this->app->singleton('understand.token-provider', function()
105
        {
106
            return new TokenProvider();
107
        });
108
    }
109
110
    /**
111
     * Register exception encoder
112
     *
113
     * @return void
114
     */
115
    protected function registerExceptionEncoder()
116
    {
117
        $this->app->bind('understand.exception-encoder', function()
118
        {
119
            return new ExceptionEncoder;
120
        });
121
    }
122
123
    /**
124
     * Register exception logger
125
     *
126
     * @return void
127
     */
128
    protected function registerExceptionLogger()
129
    {
130
        $this->app->bind('understand.exceptionLogger', function($app)
131
        {
132
            $logger = $app['understand.logger'];
133
            $encoder = $app['understand.exception-encoder'];
134
135
            return new ExceptionLogger($logger, $encoder, $app['config']);
136
        });
137
138
        $this->app->booting(function()
139
        {
140
            $loader = AliasLoader::getInstance();
141
            $loader->alias('UnderstandExceptionLogger', 'Understand\UnderstandLaravel5\Facades\UnderstandExceptionLogger');
142
        });
143
    }
144
145
    /**
146
     * Register understand logger
147
     *
148
     * @return void
149
     */
150
    protected function registerLogger()
151
    {
152
        $this->app->singleton('understand.logger', function($app)
153
        {
154
            $fieldProvider = $app['understand.field-provider'];
155
            $handler = $this->resolveHandler($app);
156
            $silent = $app['config']->get('understand-laravel.silent');
157
158
            return new Logger($fieldProvider, $handler, $silent);
159
        });
160
161
        $this->app->booting(function()
162
        {
163
            $loader = AliasLoader::getInstance();
164
            $loader->alias('UnderstandLogger', 'Understand\UnderstandLaravel5\Facades\UnderstandLogger');
165
        });
166
    }
167
168
    /**
169
     * Return default handler
170
     *
171
     * @param type $app
172
     * @return mixed
173
     * @throws \ErrorException
174
     */
175
    protected function resolveHandler($app)
176
    {
177
        $inputToken = $app['config']->get('understand-laravel.token');
178
179
        $apiUrl = $app['config']->get('understand-laravel.url', 'https://api.understand.io');
180
        $silent = $app['config']->get('understand-laravel.silent');
181
        $handlerType = $app['config']->get('understand-laravel.handler');
182
        $sslBundlePath = $app['config']->get('understand-laravel.ssl_ca_bundle');
183
184
        if ($handlerType == 'async')
185
        {
186
            return new Handlers\AsyncHandler($inputToken, $apiUrl, $silent, $sslBundlePath);
187
        }
188
189
        if ($handlerType == 'sync')
190
        {
191
            return new Handlers\SyncHandler($inputToken, $apiUrl, $silent, $sslBundlePath);
192
        }
193
194
        if ($handlerType == 'queue')
195
        {
196
            return new Handlers\LaravelQueueHandler($inputToken, $apiUrl, $silent, $sslBundlePath);
197
        }
198
199
        throw new \ErrorException('understand-laravel handler misconfiguration:' . $handlerType);
200
    }
201
202
    /**
203
     * Register model event listener provider
204
     *
205
     * @return void
206
     */
207
    protected function registerModelEventListenerProvider()
208
    {
209
        $this->app->bind('understand.model-event-listener-provider', function($app)
210
        {
211
            $logger = $app['understand.logger'];
212
            $additional = $app['config']->get('understand-laravel.additional.model_log', []);
213
214
            return new ModelEventListener($logger, $additional);
215
        });
216
    }
217
    
218
    /**
219
     * Detect Laravel version
220
     * 
221
     * @param array $versions
222
     * @return type
223
     */
224
    protected function detectLaravelVersion(array $versions)
225
    {
226
        return Str::startsWith(Application::VERSION, $versions);
227
    }
228
    
229
    /**
230
     * Listen Laravel logs
231
     *
232
     * @return void
233
     */
234
    protected function listenLaravelEvents()
235
    {
236
        // only Laravel versions below L5.4 supports `illuminate.log`
237
        if ($this->detectLaravelVersion(['5.0', '5.1', '5.2', '5.3']))
238
        {
239
            $this->app['events']->listen('illuminate.log', function($level, $message, $context)
240
            {
241
                $this->handleEvent($level, $message, $context);
242
            });
243
        }
244
        else
245
        {
246
            // starting from L5.4 MessageLogged event class was introduced
247
            // https://github.com/laravel/framework/commit/57c82d095c356a0fe0f9381536afec768cdcc072
248
            $this->app['events']->listen('Illuminate\Log\Events\MessageLogged', function($log) 
249
            {
250
251
                $this->handleEvent($log->level, $log->message, $log->context);
252
            });
253
        }
254
    }
255
256
    /**
257
     * Handle a new log event
258
     * 
259
     * @param string $level
260
     * @param mixed $message
261
     * @param array $context
262
     * @return void
263
     */
264
    protected function handleEvent($level, $message, $context)
265
    {
266
        $log = [];
267
        
268
        if ($message instanceof Exceptions\HandlerException)
269
        {
270
            return;
271
        }
272
        else if ($message instanceof \Exception)
273
        {
274
            $log = $this->app['understand.exception-encoder']->exceptionToArray($message);
275
            $log['tags'] = ['exception_log'];
276
        }
277
        // // integer, float, string or boolean as message
278
        else if (is_scalar($message))
279
        {
280
            $log['message'] = $message;
281
            $log['tags'] = ['laravel_log'];
282
        }
283
        else
284
        {
285
            $log = (array)$message;
286
            $log['tags'] = ['laravel_log'];
287
        }
288
289
        if ($context)
0 ignored issues
show
Bug Best Practice introduced by
The expression $context of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
290
        {
291
            $log['context'] = $context;
292
        }
293
294
        $log['level'] = $level;
295
296
        $additional = $this->app['config']->get('understand-laravel.log_types.laravel_log.meta', []);
297
        $this->app['understand.logger']->log($log, $additional);
298
    }
299
    
300
    /**
301
     * Listen eloquent model events and log them
302
     *
303
     * @return void
304
     */
305
    protected function listenEloquentEvents()
306
    {
307
        $modelLogger = $this->app['understand.model-event-listener-provider'];
308
309
        $events = [
310
            'eloquent.created*' => 'created',
311
            'eloquent.updated*' => 'updated',
312
            'eloquent.deleted*' => 'deleted',
313
            'eloquent.restored*' => 'restored',
314
        ];
315
316
        foreach ($events as $listenerName => $eventName)
317
        {
318
            if ($this->detectLaravelVersion(['5.0', '5.1', '5.2', '5.3']))
319
            {
320
                $this->app['events']->listen($listenerName, function($model) use($modelLogger, $eventName)
321
                {
322
                    $modelLevelEventName = 'eloquent.' . $eventName . ': ' . get_class($model);
323
                    
324
                    $modelLogger->logModelEvent($eventName, $model, $modelLevelEventName);
325
                });
326
            }
327
            else
328
            {
329
                $this->app['events']->listen($listenerName, function($modelLevelEventName, $eventPayload) use($modelLogger, $eventName)
330
                {
331
                    if (isset($eventPayload[0]) && $eventPayload[0] instanceof EloquentModel)
332
                    {
333
                        $modelLogger->logModelEvent($eventName, $eventPayload[0], $modelLevelEventName);
334
                    }
335
                });
336
            }
337
        }
338
    }
339
340
    /**
341
     * Get the services provided by the provider.
342
     *
343
     * @return array
344
     */
345
    public function provides()
346
    {
347
        return [
348
            'understand.field-provider',
349
            'understand.logger',
350
            'understand.model-event-listener-provider',
351
            'understand.exception-encoder',
352
            'understand.exceptionLogger'
353
        ];
354
    }
355
}
356