Completed
Push — master ( 125148...6e4e8e )
by Timothy
16:08
created

Controller::set_session_redirect()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 22
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 22
rs 8.9197
cc 4
eloc 10
nc 4
nop 1
1
<?php
2
/**
3
 * Hummingbird Anime Client
4
 *
5
 * An API client for Hummingbird to manage anime and manga watch lists
6
 *
7
 * @package     HummingbirdAnimeClient
8
 * @author      Timothy J. Warren
9
 * @copyright   Copyright (c) 2015
10
 * @link        https://github.com/timw4mail/HummingBirdAnimeClient
11
 * @license     MIT
12
 */
13
namespace Aviat\AnimeClient;
14
15
use Aviat\Ion\Di\ContainerInterface;
16
use Aviat\Ion\View\HttpView;
17
use Aviat\Ion\View\HtmlView;
18
use Aviat\Ion\View\JsonView;
19
use Aviat\AnimeClient\AnimeClient;
20
21
/**
22
 * Controller base, defines output methods
23
 *
24
 * @property Response object $response
25
 * @property Config object $config
26
 */
27
class Controller {
28
29
	use \Aviat\Ion\Di\ContainerAware;
30
31
	/**
32
	 * The global configuration object
33
	 * @var object $config
34
	 */
35
	protected $config;
36
37
	/**
38
	 * Request object
39
	 * @var object $request
40
	 */
41
	protected $request;
42
43
	/**
44
	 * Response object
45
	 * @var object $response
46
	 */
47
	protected $response;
48
49
	/**
50
	 * The api model for the current controller
51
	 * @var object
52
	 */
53
	protected $model;
54
55
	/**
56
	 * Url generatation class
57
	 * @var UrlGenerator
58
	 */
59
	protected $urlGenerator;
60
61
	/**
62
	 * Session segment
63
	 * @var [type]
64
	 */
65
	protected $session;
66
67
	/**
68
	 * Common data to be sent to views
69
	 * @var array
70
	 */
71
	protected $base_data = [
72
		'url_type' => 'anime',
73
		'other_type' => 'manga',
74
		'menu_name' => ''
75
	];
76
77
	/**
78
	 * Constructor
79
	 *
80
	 * @param ContainerInterface $container
81
	 */
82
	public function __construct(ContainerInterface $container)
83
	{
84
		$this->setContainer($container);
85
		$urlGenerator = $container->get('url-generator');
86
		$this->config = $container->get('config');
87
		$this->request = $container->get('request');
88
		$this->response = $container->get('response');
89
		$this->base_data['urlGenerator'] = $urlGenerator;
90
		$this->base_data['auth'] = $container->get('auth');
91
		$this->base_data['config'] = $this->config;
92
		$this->urlGenerator = $urlGenerator;
93
94
		$session = $container->get('session');
95
		$this->session = $session->getSegment(AnimeClient::SESSION_SEGMENT);
96
97
		// Set a 'previous' flash value for better redirects
98
		$this->session->setFlash('previous', $this->request->server->get('HTTP_REFERER'));
99
100
		// Set a message box if available
101
		$this->base_data['message'] = $this->session->getFlash('message');
102
	}
103
104
	/**
105
	 * Redirect to the default controller/url from an empty path
106
	 */
107
	public function redirect_to_default()
108
	{
109
		$default_type = $this->config->get(['routing', 'default_list']);
110
		$this->redirect($this->urlGenerator->default_url($default_type), 303);
111
	}
112
113
	/**
114
	 * Redirect to the previous page
115
	 *
116
	 * @return void
117
	 */
118
	public function redirect_to_previous()
119
	{
120
		$previous = $this->session->getFlash('previous');
121
		$this->redirect($previous, 303);
122
	}
123
124
	/**
125
	 * Set the current url in the session as the target of a future redirect
126
	 *
127
	 * @param string|null $url
128
	 * @return void
129
	 */
130
	public function set_session_redirect($url=NULL)
131
	{
132
		$anime_client = $this->container->get('anime-client');
133
		$double_form_page = $this->request->server->get('HTTP_REFERER') == $this->request->url->get();
134
135
		// Don't attempt to set the redirect url if
136
		// the page is one of the form type pages,
137
		// and the previous page is also a form type page_segments
138
		if ($double_form_page)
139
		{
140
			return;
141
		}
142
143
		if (is_null($url))
144
		{
145
			$url = ($anime_client->is_view_page())
146
				? $this->request->url->get()
147
				: $this->request->server->get('HTTP_REFERER');
148
		}
149
150
		$this->session->set('redirect_url', $url);
151
	}
152
153
	/**
154
	 * Redirect to the url previously set in the  session
155
	 *
156
	 * @return void
157
	 */
158
	public function session_redirect()
159
	{
160
		$target = $this->session->get('redirect_url');
161
		if (empty($target))
162
		{
163
			$this->not_found();
164
		}
165
		else
166
		{
167
			$this->redirect($target, 303);
168
			$this->session->set('redirect_url', NULL);
169
		}
170
	}
171
172
	/**
173
	 * Get a class member
174
	 *
175
	 * @param string $key
176
	 * @return object
177
	 */
178
	public function __get($key)
179
	{
180
		$allowed = ['response', 'config'];
181
182
		if (in_array($key, $allowed))
183
		{
184
			return $this->$key;
185
		}
186
187
		return NULL;
188
	}
189
190
	/**
191
	 * Get the string output of a partial template
192
	 *
193
	 * @param HtmlView $view
194
	 * @param string $template
195
	 * @param array $data
196
	 * @return string
197
	 */
198
	protected function load_partial($view, $template, array $data = [])
199
	{
200
		$errorHandler = $this->container->get('error-handler');
201
		$errorHandler->addDataTable('Template Data', $data);
202
		$router = $this->container->get('dispatcher');
203
204
		if (isset($this->base_data))
205
		{
206
			$data = array_merge($this->base_data, $data);
207
		}
208
209
		$route = $router->get_route();
210
		$data['route_path'] = ($route) ? $router->get_route()->path : "";
211
212
213
		$template_path = _dir($this->config->get('view_path'), "{$template}.php");
214
215
		if ( ! is_file($template_path))
216
		{
217
			throw new \InvalidArgumentException("Invalid template : {$template}");
218
		}
219
220
		return $view->render_template($template_path, (array)$data);
221
	}
222
223
	/**
224
	 * Render a template with header and footer
225
	 *
226
	 * @param HtmlView $view
227
	 * @param string $template
228
	 * @param array $data
229
	 * @return void
230
	 */
231
	protected function render_full_page($view, $template, array $data)
232
	{
233
		$view->appendOutput($this->load_partial($view, 'header', $data));
234
235
		if (array_key_exists('message', $data) && is_array($data['message']))
236
		{
237
			$view->appendOutput($this->load_partial($view, 'message', $data['message']));
238
		}
239
240
		$view->appendOutput($this->load_partial($view, $template, $data));
241
		$view->appendOutput($this->load_partial($view, 'footer', $data));
242
	}
243
244
	/**
245
	 * Show the login form
246
	 *
247
	 * @codeCoverageIgnore
248
	 * @param string $status
249
	 * @return void
250
	 */
251
	public function login($status = "")
252
	{
253
		$message = "";
254
255
		$view = new HtmlView($this->container);
256
257
		if ($status != "")
258
		{
259
			$message = $this->show_message($view, 'error', $status);
260
		}
261
262
		// Set the redirect url
263
		$this->set_session_redirect();
264
265
		$this->outputHTML('login', [
266
			'title' => 'Api login',
267
			'message' => $message
268
		], $view);
269
	}
270
271
	/**
272
	 * Attempt login authentication
273
	 *
274
	 * @return void
275
	 */
276
	public function login_action()
277
	{
278
		$auth = $this->container->get('auth');
279
		if ($auth->authenticate($this->request->post->get('password')))
280
		{
281
			return $this->session_redirect();
282
		}
283
284
		$this->login("Invalid username or password.");
285
	}
286
287
	/**
288
	 * Deauthorize the current user
289
	 *
290
	 * @return void
291
	 */
292
	public function logout()
293
	{
294
		$auth = $this->container->get('auth');
295
		$auth->logout();
296
297
		$this->redirect_to_default();
298
	}
299
300
	/**
301
	 * 404 action
302
	 *
303
	 * @return void
304
	 */
305
	public function not_found()
306
	{
307
		$this->outputHTML('404', [
308
			'title' => 'Sorry, page not found'
309
		]);
310
	}
311
312
	/**
313
	 * Set a session flash variable to display a message on
314
	 * next page load
315
	 *
316
	 * @param string $message
317
	 * @param string $type
318
	 * @return void
319
	 */
320
	public function set_flash_message($message, $type="info")
321
	{
322
		$this->session->setFlash('message', [
323
			'message_type' => $type,
324
			'message' => $message
325
		]);
326
	}
327
328
	/**
329
	 * Add a message box to the page
330
	 *
331
	 * @codeCoverageIgnore
332
	 * @param HtmlView $view
333
	 * @param string $type
334
	 * @param string $message
335
	 * @return string
336
	 */
337
	protected function show_message($view, $type, $message)
338
	{
339
		return $this->load_partial($view, 'message', [
340
			'message_type' => $type,
341
			'message'  => $message
342
		]);
343
	}
344
345
	/**
346
	 * Output a template to HTML, using the provided data
347
	 *
348
	 * @param string $template
349
	 * @param array $data
350
	 * @param HtmlView|null $view
351
	 * @return void
352
	 */
353
	protected function outputHTML($template, array $data = [], $view = NULL)
354
	{
355
		if (is_null($view))
356
		{
357
			$view = new HtmlView($this->container);
358
		}
359
360
		$this->render_full_page($view, $template, $data);
361
	}
362
363
	/**
364
	 * Output a JSON Response
365
	 *
366
	 * @param mixed $data
367
	 * @return void
368
	 */
369
	protected function outputJSON($data = [])
370
	{
371
		$view = new JsonView($this->container);
372
		$view->setOutput($data);
373
	}
374
375
	/**
376
	 * Redirect to the selected page
377
	 *
378
	 * @param string $url
379
	 * @param int $code
380
	 * @return void
381
	 */
382
	protected function redirect($url, $code)
383
	{
384
		$http = new HttpView($this->container);
385
		$http->redirect($url, $code);
386
	}
387
}
388
// End of BaseController.php