Passed
Push — master ( 3ac048...a915b4 )
by Roeland
11:41 queued 13s
created

Coordinator   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 101
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 47
c 2
b 0
f 0
dl 0
loc 101
rs 10
wmc 13

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A bootApp() 0 31 5
B runRegistration() 0 49 7
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @copyright 2020 Christoph Wurst <[email protected]>
7
 *
8
 * @author 2020 Christoph Wurst <[email protected]>
9
 *
10
 * @license GNU AGPL version 3 or any later version
11
 *
12
 * This program is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License as
14
 * published by the Free Software Foundation, either version 3 of the
15
 * License, or (at your option) any later version.
16
 *
17
 * This program is distributed in the hope that it will be useful,
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 * GNU Affero General Public License for more details.
21
 *
22
 * You should have received a copy of the GNU Affero General Public License
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
 */
25
26
namespace OC\AppFramework\Bootstrap;
27
28
use OC_App;
29
use OCP\AppFramework\App;
30
use OCP\AppFramework\Bootstrap\IBootstrap;
31
use OCP\AppFramework\QueryException;
32
use OCP\EventDispatcher\IEventDispatcher;
33
use OCP\ILogger;
34
use OCP\IServerContainer;
35
use Throwable;
36
use function class_exists;
37
use function class_implements;
38
use function in_array;
39
40
class Coordinator {
41
42
	/** @var IServerContainer */
43
	private $serverContainer;
44
45
	/** @var IEventDispatcher */
46
	private $eventDispatcher;
47
48
	/** @var ILogger */
49
	private $logger;
50
51
	public function __construct(IServerContainer $container,
52
								IEventDispatcher $eventListener,
53
								ILogger $logger) {
54
		$this->serverContainer = $container;
55
		$this->eventDispatcher = $eventListener;
56
		$this->logger = $logger;
57
	}
58
59
	public function runRegistration(): void {
60
		$context = new RegistrationContext($this->logger);
61
		$apps = [];
62
		foreach (OC_App::getEnabledApps() as $appId) {
63
			/*
64
			 * First, we have to enable the app's autoloader
65
			 *
66
			 * @todo use $this->appManager->getAppPath($appId) here
67
			 */
68
			$path = OC_App::getAppPath($appId);
0 ignored issues
show
Deprecated Code introduced by
The function OC_App::getAppPath() has been deprecated: 11.0.0 use \OC::$server->getAppManager()->getAppPath() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

68
			$path = /** @scrutinizer ignore-deprecated */ OC_App::getAppPath($appId);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
69
			if ($path === false) {
70
				// Ignore
71
				continue;
72
			}
73
			OC_App::registerAutoloading($appId, $path);
74
75
			/*
76
			 * Next we check if there is an application class and it implements
77
			 * the \OCP\AppFramework\Bootstrap\IBootstrap interface
78
			 */
79
			$appNameSpace = App::buildAppNamespace($appId);
80
			$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
81
			if (class_exists($applicationClassName) && in_array(IBootstrap::class, class_implements($applicationClassName), true)) {
82
				try {
83
					/** @var IBootstrap|App $application */
84
					$apps[$appId] = $application = $this->serverContainer->query($applicationClassName);
85
				} catch (QueryException $e) {
86
					// Weird, but ok
87
					return;
88
				}
89
				try {
90
					$application->register($context->for($appId));
0 ignored issues
show
Bug introduced by
The method register() does not exist on OCP\AppFramework\App. Did you maybe mean registerRoutes()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

90
					$application->/** @scrutinizer ignore-call */ 
91
                   register($context->for($appId));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
91
				} catch (Throwable $e) {
92
					$this->logger->logException($e, [
93
						'message' => 'Error during app service registration: ' . $e->getMessage(),
94
						'level' => ILogger::FATAL,
95
					]);
96
				}
97
			}
98
		}
99
100
		/**
101
		 * Now that all register methods have been called, we can delegate the registrations
102
		 * to the actual services
103
		 */
104
		$context->delegateCapabilityRegistrations($apps);
105
		$context->delegateEventListenerRegistrations($this->eventDispatcher);
106
		$context->delegateContainerRegistrations($apps);
107
		$context->delegateMiddlewareRegistrations($apps);
108
	}
109
110
	public function bootApp(string $appId): void {
111
		$appNameSpace = App::buildAppNamespace($appId);
112
		$applicationClassName = $appNameSpace . '\\AppInfo\\Application';
113
		if (!class_exists($applicationClassName)) {
114
			// Nothing to boot
115
			return;
116
		}
117
118
		/*
119
		 * Now it is time to fetch an instance of the App class. For classes
120
		 * that implement \OCP\AppFramework\Bootstrap\IBootstrap this means
121
		 * the instance was already created for register, but any other
122
		 * (legacy) code will now do their magic via the constructor.
123
		 */
124
		try {
125
			/** @var App $application */
126
			$application = $this->serverContainer->query($applicationClassName);
127
			if ($application instanceof IBootstrap) {
128
				/** @var BootContext $context */
129
				$context = new BootContext($application->getContainer());
130
				$application->boot($context);
131
			}
132
		} catch (QueryException $e) {
133
			$this->logger->logException($e, [
134
				'message' => "Could not boot $appId" . $e->getMessage(),
135
			]);
136
			return;
137
		} catch (Throwable $e) {
138
			$this->logger->logException($e, [
139
				'message' => "Could not boot $appId" . $e->getMessage(),
140
				'level' => ILogger::FATAL,
141
			]);
142
		}
143
	}
144
}
145