Test Failed
Push — master ( 8c47c2...3acf9f )
by Steve
12:37
created

engine/classes/Elgg/Di/ServiceProvider.php (4 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Elgg\Di;
3
4
use Elgg\Cache\Pool;
5
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
6
use Symfony\Component\HttpFoundation\Session\Session as SymfonySession;
7
use Zend\Mail\Transport\TransportInterface as Mailer;
8
9
/**
10
 * Provides common Elgg services.
11
 *
12
 * We extend the container because it allows us to document properties in the PhpDoc, which assists
13
 * IDEs to auto-complete properties and understand the types returned. Extension allows us to keep
14
 * the container generic.
15
 *
16
 * @property-read \Elgg\Database\AccessCollections         $accessCollections
17
 * @property-read \ElggStaticVariableCache                 $accessCache
18
 * @property-read \Elgg\ActionsService                     $actions
19
 * @property-read \Elgg\Database\AdminNotices              $adminNotices
20
 * @property-read \Elgg\Ajax\Service                       $ajax
21
 * @property-read \Elgg\Amd\Config                         $amdConfig
22
 * @property-read \Elgg\Database\Annotations               $annotations
23
 * @property-read \ElggAutoP                               $autoP
24
 * @property-read \Elgg\AutoloadManager                    $autoloadManager
25
 * @property-read \Elgg\BatchUpgrader                      $batchUpgrader
26
 * @property-read \Elgg\BootService                        $boot
27
 * @property-read \Elgg\ClassLoader                        $classLoader
28
 * @property-read \ElggCrypto                              $crypto
29
 * @property-read \Elgg\Config                             $config
30
 * @property-read \Elgg\Database\ConfigTable               $configTable
31
 * @property-read \Elgg\Context                            $context
32
 * @property-read \Elgg\Database                           $db
33
 * @property-read \Elgg\DeprecationService                 $deprecation
34
 * @property-read \Elgg\EmailService                       $emails
35
 * @property-read \Elgg\Cache\EntityCache                  $entityCache
36
 * @property-read \Elgg\EntityPreloader                    $entityPreloader
37
 * @property-read \Elgg\Database\EntityTable               $entityTable
38
 * @property-read \Elgg\EventsService                      $events
39
 * @property-read \Elgg\Assets\ExternalFiles               $externalFiles
40
 * @property-read \ElggFileCache                           $fileCache
41
 * @property-read \ElggDiskFilestore                       $filestore
42
 * @property-read \Elgg\FormsService                       $forms
43
 * @property-read \Elgg\HandlersService                    $handlers
44
 * @property-read \Elgg\Security\HmacFactory               $hmac
45
 * @property-read \Elgg\PluginHooksService                 $hooks
46
 * @property-read \Elgg\EntityIconService                  $iconService
47
 * @property-read \Elgg\Http\Input                         $input
48
 * @property-read \Elgg\ImageService                       $imageService
49
 * @property-read \Elgg\Logger                             $logger
50
 * @property-read Mailer                                   $mailer
51
 * @property-read \Elgg\Menu\Service                       $menus
52
 * @property-read \Elgg\Cache\MetadataCache                $metadataCache
53
 * @property-read \Stash\Pool|null                         $memcacheStashPool
54
 * @property-read \Elgg\Database\MetadataTable             $metadataTable
55
 * @property-read \Elgg\Database\Mutex                     $mutex
56
 * @property-read \Elgg\Notifications\NotificationsService $notifications
57
 * @property-read \Elgg\Cache\NullCache                    $nullCache
58
 * @property-read \Elgg\PasswordService                    $passwords
59
 * @property-read \Elgg\PersistentLoginService             $persistentLogin
60
 * @property-read \Elgg\Database\Plugins                   $plugins
61
 * @property-read \Elgg\Cache\PluginSettingsCache          $pluginSettingsCache
62
 * @property-read \Elgg\Database\PrivateSettingsTable      $privateSettings
63
 * @property-read \Elgg\Application\Database               $publicDb
64
 * @property-read \Elgg\Database\QueryCounter              $queryCounter
65
 * @property-read \Elgg\RedirectService                    $redirects
66
 * @property-read \Elgg\Http\Request                       $request
67
 * @property-read \Elgg\Http\ResponseFactory               $responseFactory
68
 * @property-read \Elgg\Database\RelationshipsTable        $relationshipsTable
69
 * @property-read \Elgg\Router                             $router
70
 * @property-read \Elgg\Application\ServeFileHandler       $serveFileHandler
71
 * @property-read \ElggSession                             $session
72
 * @property-read \Elgg\Cache\SimpleCache                  $simpleCache
73
 * @property-read \Elgg\Database\SiteSecret                $siteSecret
74
 * @property-read \Elgg\Forms\StickyForms                  $stickyForms
75
 * @property-read \Elgg\Database\SubtypeTable              $subtypeTable
76
 * @property-read \Elgg\Cache\SystemCache                  $systemCache
77
 * @property-read \Elgg\SystemMessagesService              $systemMessages
78
 * @property-read \Elgg\Views\TableColumn\ColumnFactory    $table_columns
79
 * @property-read \Elgg\Timer                              $timer
80
 * @property-read \Elgg\I18n\Translator                    $translator
81
 * @property-read \Elgg\Security\UrlSigner                 $urlSigner
82
 * @property-read \Elgg\UpgradeService                     $upgrades
83
 * @property-read \Elgg\Upgrade\Locator                    $upgradeLocator
84
 * @property-read \Elgg\UploadService                      $uploads
85
 * @property-read \Elgg\UserCapabilities                   $userCapabilities
86
 * @property-read \Elgg\Database\UsersTable                $usersTable
87
 * @property-read \Elgg\ViewsService                       $views
88
 * @property-read \Elgg\WidgetsService                     $widgets
89
 *
90
 * @package Elgg.Core
91
 * @access private
92
 */
93
class ServiceProvider extends \Elgg\Di\DiContainer {
94
95
	/**
96
	 * Constructor
97
	 *
98
	 * @param \Elgg\Config $config Elgg Config service
99
	 */
100 197
	public function __construct(\Elgg\Config $config) {
101
102
		$this->setFactory('autoloadManager', function(ServiceProvider $c) {
103 1
			$manager = new \Elgg\AutoloadManager($c->classLoader);
104 1
			if (!$c->config->get('AutoloaderManager_skip_storage')) {
105
				$manager->setStorage($c->fileCache);
106
				$manager->loadCache();
107
			}
108 1
			return $manager;
109 196
		});
110
111
		$this->setFactory('accessCache', function(ServiceProvider $c) {
112 196
			return new \ElggStaticVariableCache('access');
113 196
		});
114
115
		$this->setFactory('accessCollections', function(ServiceProvider $c) {
116
			return new \Elgg\Database\AccessCollections(
117
					$c->config, $c->db, $c->entityTable, $c->accessCache, $c->hooks, $c->session, $c->translator);
118 196
		});
119
120
		$this->setFactory('actions', function(ServiceProvider $c) {
121 1
			return new \Elgg\ActionsService($c->config, $c->session, $c->crypto);
122 196
		});
123
124 196
		$this->setClassName('adminNotices', \Elgg\Database\AdminNotices::class);
125
126
		$this->setFactory('ajax', function(ServiceProvider $c) {
127 1
			return new \Elgg\Ajax\Service($c->hooks, $c->systemMessages, $c->input, $c->amdConfig);
128 196
		});
129
130
		$this->setFactory('amdConfig', function(ServiceProvider $c) {
131 3
			$obj = new \Elgg\Amd\Config($c->hooks);
132 3
			$obj->setBaseUrl($c->simpleCache->getRoot());
133 3
			return $obj;
134 196
		});
135
136
		$this->setFactory('annotations', function(ServiceProvider $c) {
137
			return new \Elgg\Database\Annotations($c->db, $c->session, $c->events);
138 196
		});
139
140 196
		$this->setClassName('autoP', \ElggAutoP::class);
141
142 View Code Duplication
		$this->setFactory('boot', function(ServiceProvider $c) {
1 ignored issue
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
143 196
			$boot = new \Elgg\BootService();
144 196
			if ($c->config->getVolatile('enable_profiling')) {
145
				$boot->setTimer($c->timer);
146
			}
147 196
			return $boot;
148 196
		});
149
150
		$this->setFactory('batchUpgrader', function(ServiceProvider $c) {
151 1
			return new \Elgg\BatchUpgrader($c->config);
152 196
		});
153
154
		$this->setFactory('classLoader', function(ServiceProvider $c) {
155 1
			$loader = new \Elgg\ClassLoader(new \Elgg\ClassMap());
156 1
			$loader->register();
157 1
			return $loader;
158 196
		});
159
160 196
		$this->setValue('config', $config);
161
162
		$this->setFactory('configTable', function(ServiceProvider $c) {
163 196
			return new \Elgg\Database\ConfigTable($c->db, $c->boot, $c->logger);
164 196
		});
165
166
		$this->setFactory('context', function(ServiceProvider $c) {
167 196
			$context = new \Elgg\Context();
168 196
			$context->initialize($c->request);
169 196
			return $context;
170 196
		});
171
172 196
		$this->setClassName('crypto', \ElggCrypto::class);
173
174
		$this->setFactory('db', function(ServiceProvider $c) {
175
			// gonna need dbprefix from settings
176 196
			$c->config->loadSettingsFile();
177 196
			$db_config = new \Elgg\Database\Config($c->config->getStorageObject());
178
179
			// we inject the logger in _elgg_engine_boot()
180 196
			$db = new \Elgg\Database($db_config);
181
182 196
			if ($c->config->getVolatile('profiling_sql')) {
183
				$db->setTimer($c->timer);
184
			}
185
186 196
			return $db;
187 196
		});
188
189
		$this->setFactory('deprecation', function(ServiceProvider $c) {
190 4
			return new \Elgg\DeprecationService($c->logger);
191 196
		});
192
193
		$this->setFactory('emails', function(ServiceProvider $c) {
194 4
			return new \Elgg\EmailService($c->config, $c->hooks, $c->mailer, $c->logger);
195 196
		});
196
197
		$this->setFactory('entityCache', function(ServiceProvider $c) {
198 196
			return new \Elgg\Cache\EntityCache($c->session, $c->metadataCache);
199 196
		});
200
201
		$this->setFactory('entityPreloader', function(ServiceProvider $c) {
202 1
			return new \Elgg\EntityPreloader($c->entityCache, $c->entityTable);
203 196
		});
204
205
		$this->setFactory('entityTable', function(ServiceProvider $c) {
206
			return new \Elgg\Database\EntityTable(
207
				$c->config,
208
				$c->db,
209
				$c->entityCache,
210
				$c->metadataCache,
211
				$c->subtypeTable,
212
				$c->events,
213
				$c->session,
214
				$c->translator,
215
				$c->logger
216
			);
217 196
		});
218
219 View Code Duplication
		$this->setFactory('events', function (ServiceProvider $c) {
1 ignored issue
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
220 197
			$events = new \Elgg\EventsService();
221 197
			if ($c->config->getVolatile('enable_profiling')) {
222
				$events->setTimer($c->timer);
223
			}
224 197
			return $events;
225 196
		});
226
227
		$this->setFactory('externalFiles', function(ServiceProvider $c) {
228 1
			return new \Elgg\Assets\ExternalFiles($c->config->getStorageObject());
229 196
		});
230
231
		$this->setFactory('fileCache', function(ServiceProvider $c) {
232 1
			return new \ElggFileCache($c->config->getCachePath() . 'system_cache/');
233 196
		});
234
235
		$this->setFactory('filestore', function(ServiceProvider $c) {
236 5
			return new \ElggDiskFilestore($c->config->getDataPath());
237 196
		});
238
239
		$this->setFactory('forms', function(ServiceProvider $c) {
240 3
			return new \Elgg\FormsService($c->views, $c->logger);
241 196
		});
242
243 196
		$this->setClassName('handlers', \Elgg\HandlersService::class);
244
245
		$this->setFactory('hmac', function(ServiceProvider $c) {
246 5
			return new \Elgg\Security\HmacFactory($c->siteSecret, $c->crypto);
247 196
		});
248
249 196
		$this->setClassName('hooks', \Elgg\PluginHooksService::class);
250
251
		$this->setFactory('iconService', function(ServiceProvider $c) {
252 1
			return new \Elgg\EntityIconService($c->config, $c->hooks, $c->request, $c->logger, $c->entityTable);
253 196
		});
254
255 196
		$this->setClassName('input', \Elgg\Http\Input::class);
256
257
		$this->setFactory('imageService', function(ServiceProvider $c) {
258 2
			$imagine = new \Imagine\Gd\Imagine();
259 2
			return new \Elgg\ImageService($imagine, $c->config);
260 196
		});
261
262
		$this->setFactory('logger', function (ServiceProvider $c) {
263 196
			return new \Elgg\Logger($c->hooks, $c->config, $c->context);
264 196
		});
265
266
		// TODO(evan): Support configurable transports...
267 196
		$this->setClassName('mailer', 'Zend\Mail\Transport\Sendmail');
268
269
		$this->setFactory('menus', function(ServiceProvider $c) {
270 1
			return new \Elgg\Menu\Service($c->hooks, $c->config);
271 196
		});
272
273
		$this->setFactory('metadataCache', function (ServiceProvider $c) {
274 196
			$cache = _elgg_get_memcache('metadata');
275 196
			return new \Elgg\Cache\MetadataCache($cache);
276 196
		});
277
278
		$this->setFactory('memcacheStashPool', function(ServiceProvider $c) {
279 196
			if (!$c->config->getVolatile('memcache')) {
280 196
				return null;
281
			}
282
283
			$servers = $c->config->getVolatile('memcache_servers');
284
			if (!$servers) {
285
				return null;
286
			}
287
			$driver = new \Stash\Driver\Memcache([
288
				'servers' => $servers,
289
			]);
290
			return new \Stash\Pool($driver);
291 196
		});
292
293
		$this->setFactory('metadataTable', function(ServiceProvider $c) {
294
			// TODO(ewinslow): Use Pool instead of MetadataCache for caching
295
			return new \Elgg\Database\MetadataTable(
296
				$c->metadataCache, $c->db, $c->entityTable, $c->events, $c->session);
297 196
		});
298
299
		$this->setFactory('mutex', function(ServiceProvider $c) {
300 1
			return new \Elgg\Database\Mutex(
301 1
				$c->db,
302 1
				$c->logger
303
			);
304 196
		});
305
306
		$this->setFactory('notifications', function(ServiceProvider $c) {
307
			// @todo move queue in service provider
308 2
			$queue_name = \Elgg\Notifications\NotificationsService::QUEUE_NAME;
309 2
			$queue = new \Elgg\Queue\DatabaseQueue($queue_name, $c->db);
310 2
			$sub = new \Elgg\Notifications\SubscriptionsService($c->db);
311 2
			return new \Elgg\Notifications\NotificationsService($sub, $queue, $c->hooks, $c->session, $c->translator, $c->entityTable, $c->logger);
312 196
		});
313
314 196
		$this->setClassName('nullCache', \Elgg\Cache\NullCache::class);
315
316
		$this->setFactory('persistentLogin', function(ServiceProvider $c) {
317 1
			$global_cookies_config = $c->config->getCookieConfig();
318 1
			$cookie_config = $global_cookies_config['remember_me'];
319 1
			$cookie_name = $cookie_config['name'];
320 1
			$cookie_token = $c->request->cookies->get($cookie_name, '');
321 1
			return new \Elgg\PersistentLoginService(
322 1
				$c->db, $c->session, $c->crypto, $cookie_config, $cookie_token);
323 196
		});
324
325 196
		$this->setClassName('passwords', \Elgg\PasswordService::class);
326
327 View Code Duplication
		$this->setFactory('plugins', function(ServiceProvider $c) {
1 ignored issue
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
328
			$pool = new Pool\InMemory();
329
			$plugins = new \Elgg\Database\Plugins($pool, $c->pluginSettingsCache);
330
			if ($c->config->getVolatile('enable_profiling')) {
331
				$plugins->setTimer($c->timer);
332
			}
333
			return $plugins;
334 196
		});
335
336 196
		$this->setClassName('pluginSettingsCache', \Elgg\Cache\PluginSettingsCache::class);
337
338
		$this->setFactory('privateSettings', function(ServiceProvider $c) {
339
			return new \Elgg\Database\PrivateSettingsTable($c->db, $c->entityTable, $c->pluginSettingsCache);
340 196
		});
341
342
		$this->setFactory('publicDb', function(ServiceProvider $c) {
343 1
			return new \Elgg\Application\Database($c->db);
344 196
		});
345
346
		$this->setFactory('queryCounter', function(ServiceProvider $c) {
347 1
			return new \Elgg\Database\QueryCounter($c->db);
348 196
		}, false);
349
350
		$this->setFactory('redirects', function(ServiceProvider $c) {
351 1
			$url = current_page_url();
352 1
			$is_xhr = $c->request->isXmlHttpRequest();
353 1
			return new \Elgg\RedirectService($c->session, $is_xhr, $c->config->wwwroot, $url);
354 196
		});
355
356
		$this->setFactory('relationshipsTable', function(ServiceProvider $c) {
357
			return new \Elgg\Database\RelationshipsTable($c->db, $c->entityTable, $c->metadataTable, $c->events);
358 196
		});
359
360 196
		$this->setFactory('request', [\Elgg\Http\Request::class, 'createFromGlobals']);
361
362
		$this->setFactory('responseFactory', function(ServiceProvider $c) {
363 1
			if (PHP_SAPI === 'cli') {
364 1
				$transport = new \Elgg\Http\OutputBufferTransport();
365
			} else {
366
				$transport = new \Elgg\Http\HttpProtocolTransport();
367
			}
368 1
			return new \Elgg\Http\ResponseFactory($c->request, $c->hooks, $c->ajax, $transport);
369 196
		});
370
371
		$this->setFactory('router', function(ServiceProvider $c) {
372
			// TODO(evan): Init routes from plugins or cache
373 5
			$router = new \Elgg\Router($c->hooks);
374 5
			if ($c->config->getVolatile('enable_profiling')) {
375
				$router->setTimer($c->timer);
376
			}
377 5
			return $router;
378 196
		});
379
380
		$this->setFactory('serveFileHandler', function(ServiceProvider $c) {
381 2
			return new \Elgg\Application\ServeFileHandler($c->hmac, $c->config);
382 196
		});
383
384
		$this->setFactory('session', function(ServiceProvider $c) {
385
			$params = $c->config->getCookieConfig()['session'];
386
			$options = [
387
				// session.cache_limiter is unfortunately set to "" by the NativeSessionStorage
388
				// constructor, so we must capture and inject it directly.
389
				'cache_limiter' => session_cache_limiter(),
390
391
				'name' => $params['name'],
392
				'cookie_path' => $params['path'],
393
				'cookie_domain' => $params['domain'],
394
				'cookie_secure' => $params['secure'],
395
				'cookie_httponly' => $params['httponly'],
396
				'cookie_lifetime' => $params['lifetime'],
397
			];
398
399
			$handler = new \Elgg\Http\DatabaseSessionHandler($c->db);
400
			$storage = new NativeSessionStorage($options, $handler);
401
			$session = new SymfonySession($storage);
402
			return new \ElggSession($session);
403 196
		});
404
405 196
		$this->setClassName('urlSigner', \Elgg\Security\UrlSigner::class);
406
407
		$this->setFactory('simpleCache', function(ServiceProvider $c) {
408 3
			return new \Elgg\Cache\SimpleCache($c->config, $c->views);
409 196
		});
410
411
		$this->setFactory('siteSecret', function(ServiceProvider $c) {
412 196
			$c->config->setConfigTable($c->configTable);
413 196
			return new \Elgg\Database\SiteSecret($c->config);
414 196
		});
415
416 196
		$this->setClassName('stickyForms', \Elgg\Forms\StickyForms::class);
417
418
		$this->setFactory('subtypeTable', function(ServiceProvider $c) {
419
			return new \Elgg\Database\SubtypeTable($c->db);
420 196
		});
421
422 View Code Duplication
		$this->setFactory('systemCache', function (ServiceProvider $c) {
1 ignored issue
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
423 1
			$cache = new \Elgg\Cache\SystemCache($c->fileCache, $c->config);
424 1
			if ($c->config->getVolatile('enable_profiling')) {
425
				$cache->setTimer($c->timer);
426
			}
427 1
			return $cache;
428 196
		});
429
430
		$this->setFactory('systemMessages', function(ServiceProvider $c) {
431 1
			return new \Elgg\SystemMessagesService($c->session);
432 196
		});
433
434 196
		$this->setClassName('table_columns', \Elgg\Views\TableColumn\ColumnFactory::class);
435
436 196
		$this->setClassName('timer', \Elgg\Timer::class);
437
438
		$this->setFactory('translator', function(ServiceProvider $c) {
439 196
			return new \Elgg\I18n\Translator($c->config);
440 196
		});
441
442
		$this->setFactory('uploads', function(ServiceProvider $c) {
443 1
			return new \Elgg\UploadService($c->request);
444 196
		});
445
446
		$this->setFactory('upgrades', function(ServiceProvider $c) {
447 1
			return new \Elgg\UpgradeService(
448 1
				$c->translator,
449 1
				$c->events,
450 1
				$c->hooks,
451 1
				$c->config,
452 1
				$c->logger,
453 1
				$c->mutex
454
			);
455 196
		});
456
457
		$this->setFactory('userCapabilities', function(ServiceProvider $c) {
458 43
			return new \Elgg\UserCapabilities($c->hooks, $c->entityTable, $c->session);
459 196
		});
460
461
		$this->setFactory('usersTable', function(ServiceProvider $c) {
462 196
			return new \Elgg\Database\UsersTable(
463 196
				$c->config,
464 196
				$c->db,
465 196
				$c->entityTable,
466 196
				$c->entityCache,
467 196
				$c->events
468
			);
469 196
		});
470
471
		$this->setFactory('upgradeLocator', function(ServiceProvider $c) {
472 8
			return new \Elgg\Upgrade\Locator(
473 8
				$c->plugins,
474 8
				$c->logger,
475 8
				$c->privateSettings
476
			);
477 196
		});
478
479 196
		$this->setFactory('views', function(ServiceProvider $c) {
480 5
			return new \Elgg\ViewsService($c->hooks, $c->logger, $c->input);
481 196
		});
482
483 196
		$this->setClassName('widgets', \Elgg\WidgetsService::class);
484 196
	}
485
}
486