Passed
Push — develop ( 7ee7eb...278ae4 )
by Jens
02:44
created

Application::getComponentObject()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 5
nop 4
dl 0
loc 19
rs 9.2
c 0
b 0
f 0
1
<?php
2
namespace library\cc
3
{
4
5
	use library\components\Component;
6
	use library\storage\JsonStorage;
7
8
	/**
9
	 * Class Application
10
	 * @package library\cc
11
	 */
12
	class Application
13
	{
14
		/**
15
		 * @var \stdClass
16
		 */
17
		private $config;
18
		/**
19
		 * @var \library\storage\Storage $config
20
		 */
21
		private $storage;
22
23
		/**
24
		 * @var Request
25
		 */
26
		private $request;
27
28
		/**
29
		 * @var array
30
		 */
31
		private $matchedSitemapItems = array();
32
33
		/**
34
		 * @var array
35
		 */
36
		private $applicationComponents = array();
37
38
		/**
39
		 * Application constructor.
40
		 */
41
		public function __construct()
42
		{
43
			$this->config();
44
			$this->storage();
45
			
46
			$this->request = new Request();
47
			
48
			$this->sitemapMatching($this->request);
49
			
50
			$this->getApplicationComponents();
51
			
52
			$this->runApplicationComponents();
53
			$this->runSitemapComponents();
54
55
			$this->renderApplicationComponents();
56
			$this->renderSitemapComponents();
57
		}
58
59
		/**
60
		 * Initialize the config
61
		 *
62
		 * @throws \Exception
63
		 */
64
		private function config()
65
		{
66
			$configPath = __DIR__ . '/../../config.json';
67
			if (realpath($configPath) !== false) {
68
				$json = file_get_contents($configPath);
69
				$this->config = json_decode($json);
70
			} else {
71
				initFramework("/../../storage.json");
72
				$this->config();
73
			}
74
		}
75
76
		/**
77
		 * Initialize the storage
78
		 */
79
		private function storage()
80
		{
81
			if ($this->getStorageType() == 'json') {
82
				$this->storage = new JsonStorage($this->getStorageDir());
83
			}
84
		}
85
86
		/**
87
		 * Loop through sitemap items and see if one matches the requestUri.
88
		 * If it does, add it tot the matchedSitemapItems array
89
		 *
90
		 * @param $request
91
		 */
92
		private function sitemapMatching($request)
93
		{
94
			$sitemap = $this->storage->getSitemap();
95
			$relativeUri = '/' . $request::$relativeUri;
96
97
			foreach ($sitemap as $sitemapItem) {
98
				if ($sitemapItem->regex) {
99
					$matches = array();
100
					if (preg_match_all($sitemapItem->url, $relativeUri, $matches)) {
101
						// Make a clone, so it doesnt add the matches to the original
102
						$matchedClone = clone $sitemapItem;
103
						$matchedClone->matches = $matches;
104
						$this->matchedSitemapItems[] = $matchedClone;
105
						return;
106
					}
107
				} else {
108
					if ($sitemapItem->url == $relativeUri) {
109
						$this->matchedSitemapItems[] = $sitemapItem;
110
						return;
111
					}
112
				}
113
			}
114
		}
115
116
		/**
117
		 * Loop through all application components and run them
118
		 *
119
		 * @throws \Exception
120
		 */
121
		private function runApplicationComponents()
122
		{
123
			foreach ($this->applicationComponents as $key => $applicationComponent) {
124
				$class = $applicationComponent->component;
125
				$parameters = $applicationComponent->parameters;
126
				$this->applicationComponents[$key]->{'object'} = $this->getComponentObject($class, null, $parameters, null);
127
				$this->applicationComponents[$key]->{'object'}->run($this->storage);
128
			}
129
		}
130
131
		/**
132
		 * Loop through all (matched) sitemap components and run them
133
		 *
134
		 * @throws \Exception
135
		 */
136
		private function runSitemapComponents()
137
		{
138
			foreach ($this->matchedSitemapItems as $key => $sitemapItem) {
139
				$class = $sitemapItem->component;
140
				$template = $sitemapItem->template;
141
				$parameters = $sitemapItem->parameters;
142
				
143
				$this->matchedSitemapItems[$key]->object = $this->getComponentObject($class, $template, $parameters, $sitemapItem);
144
				
145
				$this->matchedSitemapItems[$key]->object->run($this->storage);
146
			}
147
		}
148
149
		/**
150
		 * @param string $class
151
		 * @param string $template
152
		 * @param array  $parameters
153
		 * @param \stdClass|null  $matchedSitemapItem
154
		 *
155
		 * @return mixed
156
		 * @throws \Exception
157
		 */
158
		private function getComponentObject($class='', $template='', $parameters=array(), $matchedSitemapItem)
159
		{
160
			$libraryComponentName = '\\library\\components\\' . $class;
161
			$userComponentName = '\\components\\' . $class;
162
			
163
			if (\autoLoad($libraryComponentName, false)) {
164
				$component = new $libraryComponentName($template, $this->request, $parameters, $matchedSitemapItem);
165
			} elseif (\autoLoad($userComponentName, false)) {
166
				$component = new $userComponentName($template, $this->request, $parameters, $matchedSitemapItem);
167
			} else {
168
				throw new \Exception('Could not load component ' . $class);
169
			}
170
			
171
			if (!$component instanceof Component) {
172
				throw new \Exception('Component not of type Component. Must inherit \library\components\Component');
173
			}
174
			
175
			return $component;
176
		}
177
178
		/**
179
		 * Loop through all application components and render them
180
		 */
181
		private function renderApplicationComponents()
182
		{
183
			foreach ($this->applicationComponents as $applicationComponent) {
184
				$applicationComponent->{'object'}->render();
185
			}
186
		}
187
188
		/**
189
		 * Loop through all (matched) sitemap components and render them
190
		 */
191
		private function renderSitemapComponents()
192
		{
193
			foreach ($this->matchedSitemapItems as $sitemapItem) {
194
				$this->setCachingHeaders();
195
				$sitemapItem->object->render($this);
196
				ob_clean();
197
				echo $sitemapItem->object->get();
198
				ob_end_flush();
199
				exit;
200
			}
201
		}
202
203
		public function getAllApplicationComponentParameters()
204
		{
205
			$allParameters = array();
206
			foreach ($this->applicationComponents as $applicationComponent) {
207
				$parameters = $applicationComponent->{'object'}->getParameters();
208
				$allParameters[] = $parameters;
209
			}
210
			return $allParameters;
211
		}
212
213
		public function unlockApplicationComponentParameters()
214
		{
215
			foreach ($this->applicationComponents as $applicationComponent) {
216
				$parameters = $applicationComponent->{'object'}->getParameters();
217
				extract($parameters);
218
			}
219
		}
220
221
		/**
222
		 * Set the default caching of pages to 2 days
223
		 */
224
		public function setCachingHeaders()
225
		{
226
			header('Expires: '.gmdate('D, d M Y H:i:s \G\M\T', time() + (60 * 60 * 24 * 2))); // 2 days
227
			header("Cache-Control: max-age=" . (60 * 60 * 24 * 2));
228
		}
229
230
		/**
231
		 * @return string
232
		 */
233
		public function getStorageType()
234
		{
235
			return $this->config->storageType;
236
		}
237
238
		/**
239
		 * @return string
240
		 */
241
		public function getStoragePath()
242
		{
243
			return $this->config->storagePath;
244
		}
245
246
		public function getStorageDir()
247
		{
248
			return $this->config->storageDir;
249
		}
250
251
		public function getApplicationComponents()
252
		{
253
			$this->applicationComponents = $this->storage->getApplicationComponents();
254
		}
255
256
	}
257
}