Completed
Push — master ( 205443...4952c2 )
by Steve
07:58
created

Application::registerRoutes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2
Metric Value
dl 0
loc 14
ccs 7
cts 7
cp 1
rs 9.4285
cc 2
eloc 6
nc 2
nop 0
crap 2
1
<?php
2
/**
3
 * @package    Fuel\Foundation
4
 * @version    2.0
5
 * @author     Fuel Development Team
6
 * @license    MIT License
7
 * @copyright  2010 - 2016 Fuel Development Team
8
 * @link       http://fuelphp.com
9
 */
10
11
declare(strict_types=1);
12
13
namespace Fuel\Foundation;
14
15
use Fuel\Config\Container as ConfigContainer;
16
use Fuel\Config\Container;
17
use Fuel\Dependency\Container as DependencyContainer;
18
use Fuel\Foundation\Event\AppStarted;
19
use Fuel\Foundation\Request\RequestInterface;
20
use Fuel\Foundation\Response\ResponseInterface;
21
use Fuel\Routing\Router;
22
use League\Container\ContainerInterface;
23
use League\Event\Emitter;
24
use Zend\Diactoros\CallbackStream;
25
use Zend\Diactoros\Stream;
26
27
class Application
28
{
29
	/**
30
	 * @var ContainerInterface
31
	 */
32
	protected $dependencyContainer;
33
34
	/**
35
	 * @var array
36
	 */
37
	protected $config;
38
39 7
	public static function init(array $config) : Application
40
	{
41
		// Ensure the needed config entries exists
42 7
		$config['events'] = $config['events'] ?? [];
43 7
		$config['components'] = $config['components'] ?? [];
44
45 7
		return new static($config);
46
	}
47
48 7
	public function __construct(array $config, ContainerInterface $dependencyContainer = null)
49
	{
50 7
		$this->initDependencyContainer($config, $dependencyContainer);
51
52
		// register any events from the config
53 7
		$this->registerEvents($config['events']);
54
55
		// Load components
56 7
		$this->loadComponents($config['components']);
57
58 7
		$this->registerRoutes();
59
60
		// trigger app created event
61 7
		$this->dependencyContainer
62 7
			->get('fuel.application.event')
63 7
			->emit(new AppStarted($this));
64 7
	}
65
66 7
	protected function registerRoutes()
67
	{
68
		/** @var Router $router */
69 7
		$router = $this->dependencyContainer->get('fuel.application.router');
70
71
		/** @var Container $config */
72 7
		$config = $this->dependencyContainer->get('fuel.config');
73 7
		$config->load('routing', 'routing');
74
75 7
		foreach ($config->get('routing', []) as $uri => $routeConfig)
76
		{
77 2
			$router->all($uri)->filters($routeConfig);
78
		}
79 7
	}
80
81 7
	public function setDependencyContainer(ContainerInterface $dependencyContainer)
82
	{
83 7
		$this->dependencyContainer = $dependencyContainer;
84 7
	}
85
86 7
	public function getDependencyContainer() : ContainerInterface
87
	{
88 7
		return $this->dependencyContainer;
89
	}
90
91
	public function run()
92
	{
93
		$request = $this->dependencyContainer->get('fuel.application.request');
94
		$response = $this->performRequest($request);
95
96
		http_response_code($response->getStatusCode());
97
		echo $response->getBody();
98
99
		// TODO: send shutdown event
100
	}
101
102 1
	public function performRequest(RequestInterface $request) : ResponseInterface
103
	{
104 1
		$this->dependencyContainer->add('fuel.application.request', $request);
105
106
		// TODO: trigger request started event
107
108
		// TODO: route to and call controller
109
		// TODO: Handle 404 and 500?
110
		/** @var Router $router */
111 1
		$router = $this->dependencyContainer->get('fuel.application.router');
112 1
		$match = $router->translate($request->getUri()->getPath(), $request->getMethod());
113
114
		// TODO: Use dependency magic to create the controller instance
115 1
		$controller = new $match->controller();
116
		// TODO: Pass params through?
117 1
		$controller_result = $controller->{$match->action}();
118
119
		// TODO: trigger request ended event
120
121
		// TODO: trigger response started event
122
123
		// generate and send response
124
		// If the controller response is a response object then just pass that back out
125 1
		if ($controller_result instanceof ResponseInterface) {
126
			return $controller_result;
127
		}
128
129
		// Else update the application response with the controller result#
130
		/** @var ResponseInterface $response */
131 1
		$response = $this->dependencyContainer->get('fuel.application.response');
132 1
		$response->withStatus(200);
133
		$response = $response->withBody(new CallbackStream(function() use ($controller_result) {return $controller_result; }));
134
135 1
		return $response;
136
	}
137
138
	/**
139
	 * @param array $events
140
	 */
141 7
	protected function registerEvents(array $events)
142
	{
143
		/** @var Emitter $eventContainer */
144 7
		$eventContainer = $this->dependencyContainer->get('fuel.application.event');
145
146 7
		foreach ($events as $event)
147
		{
148 2
			$eventContainer->addListener(
149 2
				$event['name'],
150 2
				$event['listener'],
151 2
				$event['priority'] ?? $eventContainer::P_NORMAL
152
			);
153
		}
154 7
	}
155
156
	/**
157
	 * @param string[] $components
158
	 */
159 7
	protected function loadComponents(array $components)
160
	{
161
		/** @var ComponentManagerInterface $componentManager */
162 7
		$componentManager = $this->getDependencyContainer()
163 7
			->get('fuel.application.component_manager');
164
165 7
		foreach ($components as $component)
166
		{
167 2
			$componentManager->load($component);
168
		}
169 7
	}
170
171
	/**
172
	 * @param array              $config
173
	 * @param ContainerInterface $dependencyContainer
174
	 */
175 7
	protected function initDependencyContainer(array $config, ContainerInterface $dependencyContainer = null)
176
	{
177 7
		$this->setDependencyContainer($dependencyContainer ?? new DependencyContainer());
178
		// So our application can be fetched
179 7
		$this->dependencyContainer->add('fuel.application', $this);
180
		// And our application config if needed
181 7
		$this->dependencyContainer->add('fuel.application.config', $config);
182
		// Also create a config container for our services
183 7
		$this->dependencyContainer->add('fuel.config', new ConfigContainer());
184
		// Finally add all our application level services
185 7
		$this->dependencyContainer->addServiceProvider(new ApplicationServicesProvider());
186 7
	}
187
188
}
189