Test Setup Failed
Push — master ( 30143f...eda994 )
by Georgi
03:20
created

UI::enablePjax()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 32
rs 10
c 0
b 0
f 0
1
<?php 
2
3
namespace Epesi\Core;
4
5
use Epesi\Core\System\Modules\Concerns\HasLinks;
6
use Epesi\Core\System\Modules\ModuleManager;
7
use Illuminate\Session\TokenMismatchException;
8
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
9
10
class UI extends \atk4\ui\App
11
{
12
	use HasLinks;
13
	
14
	public $version = '2.0.0-alpha1';
15
	
16
	public $cdn = [
17
			'semantic-ui'      => 'https://cdn.jsdelivr.net/npm/[email protected]/dist',
18
	];
19
	
20
	public $always_run = false;
21
	
22
	protected $url_building_ext = '';
23
	
24
	public function __construct($defaults = [])
25
	{
26
		parent::__construct([
27
				'title' => config('epesi.ui.title', 'EPESI'),
28
		        'cdn' => array_merge($this->cdn, (array) config('epesi.ui.cdn')),
29
				//TODO: set the skin from admin / user selection
30
		        'skin' => config('epesi.ui.skin', $this->skin),
31
		        'template_dir' => array_merge(ModuleManager::collect('templates', [$this->skin]), (array) $this->template_dir),
32
// 		        'catch_error_types' => config('app.debug') ? 
33
// 		                  // debug mode
34
// 		                  E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_USER_DEPRECATED : 
35
// 		                  // production mode
36
// 		                  E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR
37
		]);
38
	}
39
	
40
	final public static function module()
41
	{
42
	    return System\SystemCore::class;
43
	}
44
	
45
	public function response()
46
	{
47
		return response($this->render());
48
	}
49
	
50
// 	public function getViewJS($actions)
51
// 	{
52
// 		$ready = new jsFunction($actions);
53
		
54
// 		return "<script page-pjax>\n".
55
// 				(new jQuery($ready))->jsRender().
56
// 				'</script>';
57
// 	}
58
	
59
	public function render()
60
	{			
61
	    System\SystemCore::requireCSS('epesi.css');
62
	    
63
		$this->addCsrfToken();
64
		
65
		$this->addFavIcon();
66
		
67
// 		$this->enablePjax();
68
		
69
		ob_start();
70
		
71
		$this->run();
72
		
73
		return ob_get_clean();
74
	}
75
	
76
	/**
77
	 * Handles / renders exceptions
78
	 * 
79
	 * @param \Exception $exception
80
	 * @return string
81
	 */
82
	public function renderException($exception)
83
	{
84
	    ob_start();
85
	    if ($exception instanceof TokenMismatchException) {
86
	        $this->jsRedirectHomepage(__('Session expired! Redirecting to login screen ...'));
0 ignored issues
show
Bug introduced by
It seems like __('Session expired! Red...g to login screen ...') can also be of type array; however, parameter $message of Epesi\Core\UI::jsRedirectHomepage() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

86
	        $this->jsRedirectHomepage(/** @scrutinizer ignore-type */ __('Session expired! Redirecting to login screen ...'));
Loading history...
87
	    }
88
	    elseif ($exception instanceof NotFoundHttpException) {
89
	        $this->jsRedirectHomepage(__('Requested page not found! Redirecting to your home page ...'));
90
	    }	    
91
	    else {
92
	        $this->caughtException($exception);
93
	    }
94
	    
95
	    return ob_get_clean();
96
	}
97
	
98
	/**
99
	 * Redirects to epesi homepage
100
	 * 
101
	 * @param string $message
102
	 */
103
	public function jsRedirectHomepage($message)
104
	{
105
	    $homepageUrl = url(HomePage\Model\HomePage::pathOfUser());
106
	    
107
	    $redirectJs = $this->jsRedirectConfirm($homepageUrl, $message)->jsRender();
108
	    
109
	    if ($this->isJsonRequest()) {
0 ignored issues
show
Bug introduced by
The method isJsonRequest() does not exist on Epesi\Core\UI. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

109
	    if ($this->/** @scrutinizer ignore-call */ isJsonRequest()) {
Loading history...
110
	        $this->outputResponseJSON([
111
	                'success'   => true,
112
	                'message'   => $message,
113
	                'atkjs'   => $redirectJs
114
	        ]);
115
	    }
116
	    else {
117
	        $this->outputResponseHTML($this->getTag('script', $redirectJs));
118
	    }
119
	}
120
	
121
	/**
122
	 * Displays confirmation dialog and redirects to $page
123
	 * 
124
	 * @param string $page
125
	 * @param string $message
126
	 * @return \atk4\ui\JsExpression
127
	 */
128
	public function jsRedirectConfirm($page, $message)
129
	{
130
	    $redirectJs = $this->jsRedirect($page)->jsRender();
131
	    
132
	    return new \atk4\ui\JsExpression("if (confirm([])) { $redirectJs }", [$message]);
133
	}
134
	
135
	/**
136
	 * Initialize JS and CSS includes.
137
	 */
138
	public function initIncludes()
139
	{
140
// 		$this->requireJS(asset('js/app.js'));
141
// 		$this->requireCSS(asset('css/app.css'));
142
				
143
		//TODO: include below in app.js and app.css
144
		
145
		$localJs = url('storage/system/js');
146
		$localCss = url('storage/system/css');
147
		
148
		// jQuery
149
		$urlJs = $this->cdn['jquery']?? $localJs;
150
		$this->requireJS($urlJs.'/jquery.min.js');
151
		
152
		// Semantic UI
153
		$urlJs = $this->cdn['semantic-ui']?? $localJs;
154
		$urlCss = $this->cdn['semantic-ui']?? $localCss;
155
		$this->requireJS($urlJs.'/semantic.min.js');
156
		$this->requireCSS($urlCss.'/semantic.min.css');
157
		
158
		// Serialize Object
159
		$urlJs = $this->cdn['serialize-object']?? $localJs;
160
		$this->requireJS($urlJs.'/jquery.serialize-object.min.js');
161
		
162
		// Agile UI
163
		$urlJs = $this->cdn['atk']?? $localJs;
164
		$urlCss = $this->cdn['atk']?? $localCss;
165
		$this->requireJS($urlJs.'/atkjs-ui.min.js');
166
		$this->requireCSS($urlCss.'/agileui.css');
167
		
168
		// Draggable
169
		$urlJs = $this->cdn['draggable']?? $localJs;
170
		$this->requireJS($urlJs.'/draggable.bundle.js');
171
		
172
		// jQuery niceScroll	
173
		$urlJs = $this->cdn['jquery-nicescroll']?? $localJs;
174
		$this->requireJS($urlJs.'/jquery.nicescroll.js');
175
		
176
		// clipboard.js
177
		$urlJs = $this->cdn['clipboardjs']?? $localJs;
178
		$this->requireJS($urlJs.'/clipboard.js');
179
	}
180
	
181
	/**
182
	 * Add Laravel required csrf token to the page
183
	 */
184
	public function addCsrfToken()
185
	{
186
		$this->html->template->appendHTML('meta', $this->getTag('meta', ['name' => 'csrf-token', 'content' => csrf_token()]));
0 ignored issues
show
Deprecated Code introduced by
The function atk4\ui\HtmlTemplate::appendHtml() has been deprecated: use "dangerouslyAppendHtml" method instead - will be removed in v2.5 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

186
		/** @scrutinizer ignore-deprecated */ $this->html->template->appendHTML('meta', $this->getTag('meta', ['name' => 'csrf-token', 'content' => csrf_token()]));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
Bug introduced by
array('name' => 'csrf-to...ntent' => csrf_token()) of type array<string,string> is incompatible with the type string expected by parameter $attr of atk4\ui\App::getTag(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

186
		$this->html->template->appendHTML('meta', $this->getTag('meta', /** @scrutinizer ignore-type */ ['name' => 'csrf-token', 'content' => csrf_token()]));
Loading history...
187
188
		$this->addJS('$.ajaxSetup({
189
			headers: {
190
				\'X-CSRF-TOKEN\': $(\'meta[name="csrf-token"]\').attr(\'content\')
191
			}
192
		})');
193
	}
194
	
195
	/**
196
	 * Adds the favicon set in config
197
	 */
198
	public function addFavIcon()
199
	{
200
		$this->html->template->appendHTML('HEAD', $this->getTag('link', ['rel' => 'shortcut icon', 'href' => config('epesi.ui.favicon', url('favicon.png'))]));
0 ignored issues
show
Bug introduced by
array('rel' => 'shortcut...', url('favicon.png'))) of type array<string,mixed|string> is incompatible with the type string expected by parameter $attr of atk4\ui\App::getTag(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

200
		$this->html->template->appendHTML('HEAD', $this->getTag('link', /** @scrutinizer ignore-type */ ['rel' => 'shortcut icon', 'href' => config('epesi.ui.favicon', url('favicon.png'))]));
Loading history...
Deprecated Code introduced by
The function atk4\ui\HtmlTemplate::appendHtml() has been deprecated: use "dangerouslyAppendHtml" method instead - will be removed in v2.5 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

200
		/** @scrutinizer ignore-deprecated */ $this->html->template->appendHTML('HEAD', $this->getTag('link', ['rel' => 'shortcut icon', 'href' => config('epesi.ui.favicon', url('favicon.png'))]));

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
201
	}
202
	
203
	public function enablePjax()
204
	{
205
		// pjax library
206
// 		$this->requireJS('https://cdn.jsdelivr.net/npm/pjax/pjax.js');
207
		
208
// 		$this->html->template->appendHTML('HEAD', '<script>
209
// 			$(function(){
210
// 				var pjax = new Pjax({
211
// 						"elements": ".pjax", 
212
// 						"selectors": [".atk-layout", "head > script[page-pjax]", "head > title"]
213
// 				});
214
// 			});
215
			
216
// 		</script>');
217
		
218
		// pjax-api library
219
		$this->requireJS('https://cdn.jsdelivr.net/npm/pjax-api@latest');
220
221
		$this->html->template->appendHTML('HEAD', '<script>
0 ignored issues
show
Deprecated Code introduced by
The function atk4\ui\HtmlTemplate::appendHtml() has been deprecated: use "dangerouslyAppendHtml" method instead - will be removed in v2.5 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

221
		/** @scrutinizer ignore-deprecated */ $this->html->template->appendHTML('HEAD', '<script>

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
222
223
			$(function(){		
224
				const { Pjax } = require("pjax-api");		
225
				new Pjax({
226
						"links": ".pjax", 
227
						"areas": [".atk-layout", "head > script[page-pjax]", "head > title"]
228
				});
229
			});
230
			
231
		</script>');
232
233
		// common
234
		$this->addJs('$(".pjax").click(function(e) {
235
				window.onbeforeunload(e);
236
				
237
				if (e.returnValue == "unsaved" && ! confirm("Unsaved data. Continue?")) {
238
 					e.stopImmediatePropagation();
239
					window.stop();
240
 				}
241
		});');		
242
	}
243
	
244
	public function addJs($js, $args = [])
245
	{
246
		$this->html->js(true, new \atk4\ui\JsExpression($js, $args));
247
	}
248
249
	/**
250
	 * Override default method to make sure js script is included only once
251
	 * 
252
	 * {@inheritDoc}
253
	 * @see \atk4\ui\App::requireJS()
254
	 */
255
	public function requireJs($url, $isAsync = false, $isDefer = false)
256
	{
257
		static $cache;
258
		
259
		$key = md5(serialize(func_get_args()));
260
		
261
		if (! isset($cache[$key])) {
262
			$cache[$key] = true;
263
			
264
			parent::requireJS($url, $isAsync, $isDefer);
265
		}
266
				
267
		return $this;
268
	}
269
		
270
	/**
271
	 * Set the breadcrumb location
272
	 * 
273
	 * @param array|string $location
274
	 * @return null
275
	 */
276
	public function setLocation($location)
277
	{
278
		$this->layout->setLocation($location);
0 ignored issues
show
Bug introduced by
The method setLocation() does not exist on atk4\ui\Layout. It seems like you code against a sub-type of atk4\ui\Layout such as Epesi\Core\Layout\LayoutView. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

278
		$this->layout->/** @scrutinizer ignore-call */ 
279
                 setLocation($location);
Loading history...
279
		
280
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Epesi\Core\UI which is incompatible with the documented return type null.
Loading history...
281
	}
282
	
283
	public function packageInfo()
284
	{
285
		$content = file_get_contents(__DIR__ . '/../composer.json');
286
		
287
		return json_decode($content, true);
288
	}
289
}