Completed
Push — master ( a11acf...bff0db )
by Justin
06:24
created

PageEditPage::getFooterScripts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 21
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 2
Metric Value
cc 1
eloc 4
c 3
b 0
f 2
nc 1
nop 0
dl 0
loc 21
rs 10
1
<?php
2
3
/**
4
 * Copyright (c) 2018 Justin Kuenzel (jukusoft.com)
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
20
/**
21
 * Project: RocketCMS
22
 * License: Apache 2.0 license
23
 * User: Justin
24
 * Date: 03.09.2018
25
 * Time: 14:36
26
 */
27
28
class PageEditPage extends PageType {
29
30
	protected $sitemap_change_frequencies = array(
31
		"AlWAYS", "HOURLY", "DAILY", "WEEKLY", "MONTHLY", "YEARLY", "NEVER"
32
	);
33
34
	public function getContent(): string {
35
		$template = new DwooTemplate("pages/editpage");
36
37
		//check, if pageID is set
38
		if (!isset($_REQUEST['edit']) || empty($_REQUEST['edit'])) {
39
			//show error
40
			return $this->showError("No pageID was set!");
41
		}
42
43
		$pageID = (int) $_REQUEST['edit'];
44
45
		$page = new Page();
46
		$page->loadByID($pageID);
47
48
		//first check permissions
49
		if (!PermissionChecker::current()->hasRight("can_edit_all_pages") && !(PermissionChecker::current()->hasRight("can_edit_own_pages") && $page->getAuthorID() == User::current()->getID())) {
50
			//user doesn't have permissions to edit this page
51
			return $this->showError("You don't have permissions to edit this page!");
52
		}
53
54
		//first, lock page
55
		Page::lockPage($page->getPageID(), User::current()->getID());
56
57
		$success_messages = array();
58
		$error_messages = array();
59
60
		//save page
61
		if (isset($_REQUEST['submit'])) {
62
			if ($_REQUEST['submit'] === "Save") {
63
				//save page
64
				$res = $this->save($page);
65
66
				if ($res === true) {
67
					$success_messages[] = "Saved page successfully!";
68
				} else {
69
					$error_messages[] = $res;
70
				}
71
			} else if ($_REQUEST['submit'] === "SaveUnlock") {
72
				//save page
73
				$res = $this->save($page);
74
75
				if ($res === true) {
76
					//unlock page
77
					Page::unlockPage($page->getPageID());
78
79
					//redirect to admin/pages
80
					header("Location: " . DomainUtils::generateURL("admin/pages"));
81
82
					ob_flush();
83
					ob_end_flush();
84
85
					exit;
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return string. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
86
				} else {
87
					$error_messages[] = $res;
88
				}
89
			} else if ($_REQUEST['submit'] === "Publish") {
90
				//save page
91
				$res = $this->save($page);
92
93
				if ($res === true) {
94
					$success_messages[] = "Saved page successfully!";
95
				} else {
96
					$error_messages[] = $res;
97
				}
98
99
				//publish page
100
				$res = $this->publish($page);
101
102
				if ($res === true) {
103
					$success_messages[] = "Page published successfully!";
104
				} else {
105
					$error_messages[] = $res;
106
				}
107
			}
108
		}
109
110
		$template->assign("action_url", DomainUtils::generateURL($this->getPage()->getAlias(), array("edit" => $pageID)));
111
112
		$template->assign("page", array(
113
			'id' => $page->getPageID(),
114
			'alias' => "/" . $page->getAlias(),
115
			'title' => $page->getTitle(),
116
			'content' => $page->getContent(),
117
			'is_published' => $page->isPublished(),
118
			'can_publish' => (!$page->isPublished() && (PermissionChecker::current()->hasRight("can_publish_all_pages") || (PermissionChecker::current()->hasRight("can_publish_own_pages") && $page->getAuthorID() == User::current()->getID()))),
119
			'can_change_owner' => (PermissionChecker::current()->hasRight("can_change_page_owner") || $page->getAuthorID() == User::current()->getID()),
120
			'folder' => $page->getFolder(),
121
			'preview_url' => DomainUtils::generateURL($page->getAlias(), array("preview" => "true")),
122
			'current_style' => $page->getStyle(),
123
			'template' => $page->getCustomTemplate(),
124
			'has_custom_template' => $page->hasCustomTemplate(),
125
			'parent' => $page->getParentID(),
126
			'meta_description' => $page->getMetaDescription(),
127
			'meta_keywords' => $page->getMetaKeywords(),
128
			'meta_robots' => $page->getMetaRobotsOptions(),
129
			'meta_canonicals' => $page->getMetaCanonicals(),
130
			'has_canoncials' => !empty($page->getMetaCanonicals()),
131
			'sitemap' => $page->isSitemapEnabled(),
132
			'sitemap_changefreq' => $page->getSitemapChangeFreq(),
133
			'sitemap_priority' => $page->getSitemapPriority(),
134
			'og_type' => $page->getOgType(),
135
			'og_title' => $page->getOgTitle(),
136
			'og_description' => $page->getOgDescription()
137
		));
138
139
		//set available styles
140
		$template->assign("styles", StyleController::listAllStyles());
141
142
		//get all pages from database
143
		$pages = array();
144
		$rows = Database::getInstance()->listRows("SELECT `id`, `alias` FROM `{praefix}pages` WHERE `editable` = '1' AND `activated` = '1'; ");
145
146
		foreach ($rows as $row) {
147
			$pages[] = array(
148
				'id' => $row['id'],
149
				'alias' => $row['alias']
150
			);
151
		}
152
153
		$template->assign("parent_pages", $pages);
154
155
		//https://developers.google.com/search/reference/robots_meta_tag?hl=de
156
		$robots_options = array(
157
			"all",
158
			"noindex",
159
			"nofollow",
160
			"none",
161
			"noarchive",
162
			"nosnippet",
163
			"noodp",
164
			"notranslate",
165
			"noimageindex",
166
			"unavailable_after: "
167
		);
168
169
		$template->assign("robots_options", $robots_options);
170
171
		$sitemap_change_frequencies = $this->sitemap_change_frequencies;
172
173
		$template->assign("sitemap_change_frequencies", $sitemap_change_frequencies);
174
175
		//OpenGraph types,https://developers.facebook.com/docs/reference/opengraph/
176
		$og_types = array("website", "article", "book", "profile");
177
178
		$template->assign("og_types", $og_types);
179
180
		//add support to show additional code from plugins
181
		$additional_code_header = "";
182
		$additional_code_footer = "";
183
184
		Events::throwEvent("page_edit_additional_code_header", array(
185
			'page' => &$page,
186
			'code' => &$additional_code_header
187
		));
188
189
		$template->assign("additional_code_header", $additional_code_footer);
190
191
		Events::throwEvent("page_edit_additional_code_footer", array(
192
			'page' => &$page,
193
			'code' => &$additional_code_footer
194
		));
195
196
		$template->assign("additional_code_footer", $additional_code_footer);
197
198
		$template->assign("errors", $error_messages);
199
		$template->assign("success_messages", $success_messages);
200
201
		return $template->getCode();
202
	}
203
204
	protected function save (Page &$page) {
205
		//first check permissions
206
		if (!PermissionChecker::current()->hasRight("can_edit_all_pages") && !(PermissionChecker::current()->hasRight("can_edit_own_pages") && $page->getAuthorID() == User::current()->getID())) {
207
			//user doesn't have permissions to edit this page
208
			return "You don't have permissions to edit this page!";
209
		}
210
211
		if (!isset($_POST['title']) || empty($_POST['title'])) {
212
			return "No title was set";
213
		}
214
215
		//validate title
216
		$title = htmlentities($_POST['title']);
217
218
		if (!isset($_POST['html_code']) || empty($_POST['html_code'])) {
219
			return "No content was set or content is empty!";
220
		}
221
222
		$content = $_POST['html_code'];
223
224
		//TODO: save page attributes
225
		if (!isset($_REQUEST['parent']) || empty($_REQUEST['parent'])) {
226
			return "Parent page wasn't set!";
227
		}
228
229
		$parent = (int) $_REQUEST['parent'];
230
231
		if (!isset($_REQUEST['design']) || empty($_REQUEST['design'])) {
232
			return "Design wasn't set!";
233
		}
234
235
		$design = $_REQUEST['design'];
236
237
		//TODO: check, if style (design) exists
238
239
		$template = "none";
240
241
		if (isset($_REQUEST['has_custom_template']) && isset($_REQUEST['template']) && !empty($_REQUEST['template'])) {
242
			$template = $_REQUEST['template'];
243
		}
244
245
		$keywords = "";
246
247
		if (!isset($_REQUEST['meta_keywords']) || empty($_REQUEST['meta_keywords'])) {
248
			//return "Meta keywords wasn't set!";
249
		} else {
250
			$keywords = htmlentities($_REQUEST['meta_keywords']);
251
		}
252
253
		$robots = "";
254
255
		if (!isset($_REQUEST['meta_robots']) || empty($_REQUEST['meta_robots'])) {
256
			//return "Meta robots wasn't set!";
257
		} else {
258
			$robots = htmlentities($_REQUEST['meta_robots']);
259
		}
260
261
		$canoncials = "";
262
263
		if (isset($_REQUEST['has_canoncials']) && isset($_REQUEST['meta_canoncials']) && !empty($_REQUEST['meta_canoncials'])) {
264
			$canoncials = $_REQUEST['meta_canoncials'];
265
		}
266
267
		$sitemap = 0;
268
		$sitemap_changefreq = "WEEKLY";
269
		$sitemap_priority = 0.5;
270
271
		if (isset($_REQUEST['sitemap'])) {
272
			$sitemap = 1;
273
274
			if (!isset($_REQUEST['sitemap_changefreq']) || empty($_REQUEST['sitemap_changefreq'])) {
275
				return "Sitemap change frequency wasn't set!";
276
			}
277
278
			$sitemap_changefreq = $_REQUEST['sitemap_changefreq'];
279
280
			if (!in_array($sitemap_changefreq, $this->sitemap_change_frequencies)) {
281
				return "Invalide value for sitemap change frequency: " . $sitemap_changefreq;
282
			}
283
284
			if (!isset($_REQUEST['sitemap_priority']) || empty($_REQUEST['sitemap_priority'])) {
285
				return "Sitemap priority wasn't set!";
286
			}
287
288
			$sitemap_priority = (float) str_replace(",", ".", $_REQUEST['sitemap_priority']);
289
290
			if ($sitemap_priority < 0) {
291
				return "Minimum value of sitemap priority is 0.";
292
			}
293
294
			if ($sitemap_priority > 1) {
295
				return "Maximum value of sitemap priority is 1.";
296
			}
297
		}
298
299
		if (!isset($_REQUEST['og_type']) || empty($_REQUEST['og_type'])) {
300
			return "OpenGraph type wasn't set!";
301
		}
302
303
		$og_type = $_REQUEST['og_type'];
304
305
		if (!isset($_REQUEST['og_title']) || empty($_REQUEST['og_title'])) {
306
			return "OpenGraph title wasn't set!";
307
		}
308
309
		$og_title = htmlentities($_REQUEST['og_title']);
310
311
		//update page in database
312
		Database::getInstance()->execute("UPDATE `{praefix}pages` SET `title` = :title, `content` = :content, `parent` = :parent, `design` = :design, `template` = :template, `sitemap` = :sitemap, `sitemap_changefreq` = :sitemap_changefreq, `sitemap_priority` = :sitemap_priority, `meta_keywords` = :keywords, `meta_robots` = :robots, `meta_canonicals` = :canoncials, `og_type` = :og_type, `og_title` = :og_title WHERE `id` = :pageID; ", array(
313
			'title' => $title,
314
			'content' => $content,
315
			'pageID' => $page->getPageID(),
316
			'parent' => $parent,
317
			'design' => $design,
318
			'template' => $template,
319
			'sitemap' => $sitemap,
320
			'sitemap_changefreq' => $sitemap_changefreq,
321
			'sitemap_priority' => $sitemap_priority,
322
			'keywords' => $keywords,
323
			'robots' => $robots,
324
			'canoncials' => $canoncials,
325
			'og_type' => $og_type,
326
			'og_title' => $og_title
327
		));
328
329
		//clear cache
330
		$page->clearCache();
331
332
		//reload page from database
333
		$page->loadByID($page->getPageID(), false);
334
335
		//TODO: remove this line later
336
		Cache::clear("pages");
337
338
		return true;
339
	}
340
341
	protected function publish (Page &$page) {
342
		//check permissions for publishing
343
		if (PermissionChecker::current()->hasRight("can_publish_all_pages") || (PermissionChecker::current()->hasRight("can_publish_own_pages") && $page->getAuthorID() == User::current()->getID())) {
344
			//update page in database
345
			Database::getInstance()->execute("UPDATE `{praefix}pages` SET `published` = '1' WHERE `id` = :pageID; ", array(
346
				'pageID' => $page->getPageID()
347
			));
348
349
			//clear cache
350
			$page->clearCache();
351
352
			//reload page from database
353
			$page->loadByID($page->getPageID(), false);
354
355
			//TODO: remove this line later
356
			Cache::clear("pages");
357
358
			return true;
359
		} else {
360
			return "You don't have the permissions to publish this page!";
361
		}
362
	}
363
364
	protected function showError (string $message) : string {
0 ignored issues
show
Unused Code introduced by
The parameter $message is not used and could be removed. ( Ignorable by Annotation )

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

364
	protected function showError (/** @scrutinizer ignore-unused */ string $message) : string {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
365
		//show error
366
		$template = new DwooTemplate("pages/error");
367
		$template->assign("message", "No pageID was set!");
368
		return $template->getCode();
369
	}
370
371
	public function getFooterScripts(): string {
372
		$style_name = Registry::singleton()->getSetting("current_style_name");
373
		$style_path = DomainUtils::getBaseURL() . "/styles/" . $style_name . "/";
0 ignored issues
show
Unused Code introduced by
The assignment to $style_path is dead and can be removed.
Loading history...
374
375
		$thirdparty_url = Registry::singleton()->getSetting("thirdparty_url");
376
377
		/*return "<!-- CK Editor -->
378
			<script src=\"" . $style_path . "bower_components/ckeditor/ckeditor.js\"></script>
379
			
380
			<script>
381
				$(function () {
382
					// Replace the <textarea id=\"editor1\"> with a CKEditor
383
					// instance, using default configuration.
384
					CKEDITOR.replace('wysiwygEditor', {
385
						height: '500px',
386
						enterMode: CKEDITOR.ENTER_BR
387
					});
388
				});
389
			</script>";*/
390
391
		return "<script src=\"" . $thirdparty_url . "tinymce_4.8.2/js/tinymce/tinymce.min.js\"></script>
392
  				<script>tinymce.init({
393
					  selector: 'textarea',
394
					  height: 500,
395
					  theme: 'modern',
396
					  removed_menuitems: 'newdocument',
397
					  plugins: 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template codesample table charmap hr pagebreak nonbreaking anchor toc insertdatetime advlist lists textcolor wordcount imagetools contextmenu colorpicker textpattern help',
398
					  toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify  | numlist bullist outdent indent  | removeformat',
399
					  image_advtab: true
400
				});
401
				
402
				document.getElementById('customTplCheckbox').onchange = function() {
403
					document.getElementById('inputTpl').disabled = !this.checked;
404
					
405
					if (!this.checked) {
406
						document.getElementById('inputTpl').value = 'none';
407
					}
408
				};
409
				
410
				document.getElementById('customCanoncialsCheckbox').onchange = function() {
411
					document.getElementById('inputCanoncials').disabled = !this.checked;
412
					
413
					if (!this.checked) {
414
						document.getElementById('inputCanoncials').value = '';
415
					}
416
				};
417
				
418
				document.getElementById('inputSitemap').onchange = function() {
419
					document.getElementById('inputSitemapChangeFrequency').disabled = !this.checked;
420
					document.getElementById('inputSitemapPriority').disabled = !this.checked;
421
				};
422
				</script>";
423
	}
424
425
	public function listRequiredPermissions(): array {
426
		return array("can_edit_all_pages", "can_edit_own_pages");
427
	}
428
429
}
430
431
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
432