Completed
Pull Request — master (#774)
by Roeland
09:39
created

App::main()   D

Complexity

Conditions 13
Paths 432

Size

Total Lines 69
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 47
c 1
b 0
f 0
nc 432
nop 4
dl 0
loc 69
rs 4.0865

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Andreas Fischer <[email protected]>
6
 * @author Bernhard Posselt <[email protected]>
7
 * @author Lukas Reschke <[email protected]>
8
 * @author Morris Jobke <[email protected]>
9
 * @author Thomas Müller <[email protected]>
10
 *
11
 * @license AGPL-3.0
12
 *
13
 * This code is free software: you can redistribute it and/or modify
14
 * it under the terms of the GNU Affero General Public License, version 3,
15
 * as published by the Free Software Foundation.
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, version 3,
23
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
24
 *
25
 */
26
27
28
namespace OC\AppFramework;
29
30
use OC\AppFramework\Http\Dispatcher;
31
use OC_App;
32
use OC\AppFramework\DependencyInjection\DIContainer;
33
use OCP\AppFramework\QueryException;
34
use OCP\AppFramework\Http\ICallbackResponse;
35
36
/**
37
 * Entry point for every request in your app. You can consider this as your
38
 * public static void main() method
39
 *
40
 * Handles all the dependency injection, controllers and output flow
41
 */
42
class App {
43
44
45
	/**
46
	 * Turns an app id into a namespace by either reading the appinfo.xml's
47
	 * namespace tag or uppercasing the appid's first letter
48
	 * @param string $appId the app id
49
	 * @param string $topNamespace the namespace which should be prepended to
50
	 * the transformed app id, defaults to OCA\
51
	 * @return string the starting namespace for the app
52
	 */
53
	public static function buildAppNamespace($appId, $topNamespace='OCA\\') {
54
		// first try to parse the app's appinfo/info.xml <namespace> tag
55
		$appPath = OC_App::getAppPath($appId);
56
		if ($appPath !== false) {
57
			$filePath = "$appPath/appinfo/info.xml";
58
			if (is_file($filePath)) {
59
				$loadEntities = libxml_disable_entity_loader(false);
60
				$xml = @simplexml_load_file($filePath);
61
				libxml_disable_entity_loader($loadEntities);
62
				if ($xml) {
63
					$result = $xml->xpath('/info/namespace');
64
					if ($result && count($result) > 0) {
65
						// take first namespace result
66
						return $topNamespace . trim((string) $result[0]);
67
					}
68
				}
69
			}
70
		}
71
		// if the tag is not found, fall back to uppercasing the first letter
72
		return $topNamespace . ucfirst($appId);
73
	}
74
75
76
	/**
77
	 * Shortcut for calling a controller method and printing the result
78
	 * @param string $controllerName the name of the controller under which it is
79
	 *                               stored in the DI container
80
	 * @param string $methodName the method that you want to call
81
	 * @param DIContainer $container an instance of a pimple container.
82
	 * @param array $urlParams list of URL parameters (optional)
83
	 */
84
	public static function main($controllerName, $methodName, DIContainer $container, array $urlParams = null) {
85
		if (!is_null($urlParams)) {
86
			$container['OCP\\IRequest']->setUrlParameters($urlParams);
87
		} else if (isset($container['urlParams']) && !is_null($container['urlParams'])) {
88
			$container['OCP\\IRequest']->setUrlParameters($container['urlParams']);
89
		}
90
		$appName = $container['AppName'];
91
92
		// first try $controllerName then go for \OCA\AppName\Controller\$controllerName
93
		try {
94
			$controller = $container->query($controllerName);
95
		} catch(QueryException $e) {
96
			if ($appName === 'core') {
97
				$appNameSpace = 'OC\\Core';
98
			} else if ($appName === 'settings') {
99
				$appNameSpace = 'OC\\Settings';
100
			} else {
101
				$appNameSpace = self::buildAppNamespace($appName);
102
			}
103
			$controllerName = $appNameSpace . '\\Controller\\' . $controllerName;
104
			$controller = $container->query($controllerName);
105
		}
106
107
		// initialize the dispatcher and run all the middleware before the controller
108
		/** @var Dispatcher $dispatcher */
109
		$dispatcher = $container['Dispatcher'];
110
111
		list(
112
			$httpHeaders,
113
			$responseHeaders,
114
			$responseCookies,
115
			$output,
116
			$response
117
		) = $dispatcher->dispatch($controller, $methodName);
118
119
		$io = $container['OCP\\AppFramework\\Http\\IOutput'];
120
121
		if(!is_null($httpHeaders)) {
122
			$io->setHeader($httpHeaders);
123
		}
124
125
		foreach($responseHeaders as $name => $value) {
126
			$io->setHeader($name . ': ' . $value);
127
		}
128
129
		foreach($responseCookies as $name => $value) {
130
			$expireDate = null;
131
			if($value['expireDate'] instanceof \DateTime) {
132
				$expireDate = $value['expireDate']->getTimestamp();
133
			}
134
			$io->setCookie(
135
				$name,
136
				$value['value'],
137
				$expireDate,
138
				$container->getServer()->getWebRoot(),
139
				null,
140
				$container->getServer()->getRequest()->getServerProtocol() === 'https',
141
				true
142
			);
143
		}
144
145
		if ($response instanceof ICallbackResponse) {
146
			$response->callback($io);
147
		} else if(!is_null($output)) {
148
			$io->setHeader('Content-Length: ' . strlen($output));
149
			$io->setOutput($output);
150
		}
151
152
	}
153
154
	/**
155
	 * Shortcut for calling a controller method and printing the result.
156
	 * Similar to App:main except that no headers will be sent.
157
	 * This should be used for example when registering sections via
158
	 * \OC\AppFramework\Core\API::registerAdmin()
159
	 *
160
	 * @param string $controllerName the name of the controller under which it is
161
	 *                               stored in the DI container
162
	 * @param string $methodName the method that you want to call
163
	 * @param array $urlParams an array with variables extracted from the routes
164
	 * @param DIContainer $container an instance of a pimple container.
165
	 */
166
	public static function part($controllerName, $methodName, array $urlParams,
167
								DIContainer $container){
168
169
		$container['urlParams'] = $urlParams;
170
		$controller = $container[$controllerName];
171
172
		$dispatcher = $container['Dispatcher'];
173
174
		list(, , $output) =  $dispatcher->dispatch($controller, $methodName);
175
		return $output;
176
	}
177
178
}
179