Passed
Push — master ( 7c7f0d...380563 )
by Roeland
22:27 queued 10:28
created

App::__construct()   B

Complexity

Conditions 9
Paths 14

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 9
eloc 18
c 1
b 0
f 0
nc 14
nop 2
dl 0
loc 27
rs 8.0555
1
<?php
2
declare(strict_types=1);
3
/**
4
 * @copyright Copyright (c) 2016, ownCloud, Inc.
5
 *
6
 * @author Bernhard Posselt <[email protected]>
7
 * @author Lukas Reschke <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Robin Appelman <[email protected]>
10
 * @author Roeland Jago Douma <[email protected]>
11
 * @author Thomas Müller <[email protected]>
12
 * @author Thomas Tanghus <[email protected]>
13
 *
14
 * @license AGPL-3.0
15
 *
16
 * This code is free software: you can redistribute it and/or modify
17
 * it under the terms of the GNU Affero General Public License, version 3,
18
 * as published by the Free Software Foundation.
19
 *
20
 * This program is distributed in the hope that it will be useful,
21
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
 * GNU Affero General Public License for more details.
24
 *
25
 * You should have received a copy of the GNU Affero General Public License, version 3,
26
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
27
 *
28
 */
29
30
/**
31
 * Public interface of ownCloud for apps to use.
32
 * AppFramework/App class
33
 */
34
35
namespace OCP\AppFramework;
36
use OC\AppFramework\Routing\RouteConfig;
37
use OC\ServerContainer;
38
use OCP\Route\IRouter;
39
40
41
/**
42
 * Class App
43
 * @package OCP\AppFramework
44
 *
45
 * Any application must inherit this call - all controller instances to be used are
46
 * to be registered using IContainer::registerService
47
 * @since 6.0.0
48
 */
49
class App {
50
51
	/** @var IAppContainer */
52
	private $container;
53
54
	/**
55
	 * Turns an app id into a namespace by convention. The id is split at the
56
	 * underscores, all parts are CamelCased and reassembled. e.g.:
57
	 * some_app_id -> OCA\SomeAppId
58
	 * @param string $appId the app id
59
	 * @param string $topNamespace the namespace which should be prepended to
60
	 * the transformed app id, defaults to OCA\
61
	 * @return string the starting namespace for the app
62
	 * @since 8.0.0
63
	 */
64
	public static function buildAppNamespace(string $appId, string $topNamespace='OCA\\'): string {
65
		return \OC\AppFramework\App::buildAppNamespace($appId, $topNamespace);
66
	}
67
68
69
	/**
70
	 * @param string $appName
71
	 * @param array $urlParams an array with variables extracted from the routes
72
	 * @since 6.0.0
73
	 */
74
	public function __construct(string $appName, array $urlParams = []) {
75
		if (\OC::$server->getConfig()->getSystemValueBool('debug')) {
76
			$applicationClassName = get_class($this);
77
			$e = new \RuntimeException('App class ' . $applicationClassName . ' is not setup via query() but directly');
78
			$setUpViaQuery = false;
79
80
			foreach ($e->getTrace() as $step) {
81
				if (isset($step['class'], $step['function'], $step['args'][0]) &&
82
					$step['class'] === ServerContainer::class &&
83
					$step['function'] === 'query' &&
84
					$step['args'][0] === $applicationClassName) {
85
					$setUpViaQuery = true;
86
					break;
87
				}
88
			}
89
90
			if (!$setUpViaQuery) {
91
				\OC::$server->getLogger()->logException($e, [
92
					'app' => $appName,
93
				]);
94
			}
95
		}
96
97
		try {
98
			$this->container = \OC::$server->getRegisteredAppContainer($appName);
99
		} catch (QueryException $e) {
100
			$this->container = new \OC\AppFramework\DependencyInjection\DIContainer($appName, $urlParams);
101
		}
102
	}
103
104
	/**
105
	 * @return IAppContainer
106
	 * @since 6.0.0
107
	 */
108
	public function getContainer(): IAppContainer {
109
		return $this->container;
110
	}
111
112
	/**
113
	 * This function is to be called to create single routes and restful routes based on the given $routes array.
114
	 *
115
	 * Example code in routes.php of tasks app (it will register two restful resources):
116
	 * $routes = array(
117
	 *		'resources' => array(
118
	 *		'lists' => array('url' => '/tasklists'),
119
	 *		'tasks' => array('url' => '/tasklists/{listId}/tasks')
120
	 *	)
121
	 *	);
122
	 *
123
	 * $a = new TasksApp();
124
	 * $a->registerRoutes($this, $routes);
125
	 *
126
	 * @param \OCP\Route\IRouter $router
127
	 * @param array $routes
128
	 * @since 6.0.0
129
	 * @suppress PhanAccessMethodInternal
130
	 */
131
	public function registerRoutes(IRouter $router, array $routes) {
132
		$routeConfig = new RouteConfig($this->container, $router, $routes);
133
		$routeConfig->register();
134
	}
135
136
	/**
137
	 * This function is called by the routing component to fire up the frameworks dispatch mechanism.
138
	 *
139
	 * Example code in routes.php of the task app:
140
	 * $this->create('tasks_index', '/')->get()->action(
141
	 *		function($params){
142
	 *			$app = new TaskApp($params);
143
	 *			$app->dispatch('PageController', 'index');
144
	 *		}
145
	 *	);
146
	 *
147
	 *
148
	 * Example for for TaskApp implementation:
149
	 * class TaskApp extends \OCP\AppFramework\App {
150
	 *
151
	 *		public function __construct($params){
152
	 *			parent::__construct('tasks', $params);
153
	 *
154
	 *			$this->getContainer()->registerService('PageController', function(IAppContainer $c){
155
	 *				$a = $c->query('API');
156
	 *				$r = $c->query('Request');
157
	 *				return new PageController($a, $r);
158
	 *			});
159
	 *		}
160
	 *	}
161
	 *
162
	 * @param string $controllerName the name of the controller under which it is
163
	 *                               stored in the DI container
164
	 * @param string $methodName the method that you want to call
165
	 * @since 6.0.0
166
	 */
167
	public function dispatch(string $controllerName, string $methodName) {
168
		\OC\AppFramework\App::main($controllerName, $methodName, $this->container);
169
	}
170
}
171