Completed
Push — master ( 6e4c54...7cf3e9 )
by Justin
03:37
created

PageEditPage::getContent()   F

Complexity

Conditions 19
Paths 21

Size

Total Lines 162
Code Lines 98

Duplication

Lines 0
Ratio 0 %

Importance

Changes 21
Bugs 1 Features 9
Metric Value
cc 19
eloc 98
nc 21
nop 0
dl 0
loc 162
rs 3.6569
c 21
b 1
f 9

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
	public function getContent(): string {
31
		$template = new DwooTemplate("pages/editpage");
32
33
		//check, if pageID is set
34
		if (!isset($_REQUEST['edit']) || empty($_REQUEST['edit'])) {
35
			//show error
36
			return $this->showError("No pageID was set!");
37
		}
38
39
		$pageID = (int) $_REQUEST['edit'];
40
41
		$page = new Page();
42
		$page->loadByID($pageID);
43
44
		//first check permissions
45
		if (!PermissionChecker::current()->hasRight("can_edit_all_pages") && !(PermissionChecker::current()->hasRight("can_edit_own_pages") && $page->getAuthorID() == User::current()->getID())) {
46
			//user doesn't have permissions to edit this page
47
			return $this->showError("You don't have permissions to edit this page!");
48
		}
49
50
		//first, lock page
51
		Page::lockPage($page->getPageID(), User::current()->getID());
52
53
		$success_messages = array();
54
		$error_messages = array();
55
56
		//save page
57
		if (isset($_REQUEST['submit'])) {
58
			if ($_REQUEST['submit'] === "Save") {
59
				//save page
60
				$res = $this->save($page);
61
62
				if ($res === true) {
63
					$success_messages[] = "Saved page successfully!";
64
				} else {
65
					$error_messages[] = $res;
66
				}
67
			} else if ($_REQUEST['submit'] === "SaveUnlock") {
68
				//save page
69
				$res = $this->save($page);
70
71
				if ($res === true) {
72
					//unlock page
73
					Page::unlockPage($page->getPageID());
74
75
					//redirect to admin/pages
76
					header("Location: " . DomainUtils::generateURL("admin/pages"));
77
78
					ob_flush();
79
					ob_end_flush();
80
81
					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...
82
				} else {
83
					$error_messages[] = $res;
84
				}
85
			} else if ($_REQUEST['submit'] === "Publish") {
86
				//save page
87
				$res = $this->save($page);
88
89
				if ($res === true) {
90
					$success_messages[] = "Saved page successfully!";
91
				} else {
92
					$error_messages[] = $res;
93
				}
94
95
				//publish page
96
				$res = $this->publish($page);
97
98
				if ($res === true) {
99
					$success_messages[] = "Page published successfully!";
100
				} else {
101
					$error_messages[] = $res;
102
				}
103
			}
104
		}
105
106
		$template->assign("action_url", DomainUtils::generateURL($this->getPage()->getAlias(), array("edit" => $pageID)));
107
108
		$template->assign("page", array(
109
			'id' => $page->getPageID(),
110
			'alias' => "/" . $page->getAlias(),
111
			'title' => $page->getTitle(),
112
			'content' => $page->getContent(),
113
			'is_published' => $page->isPublished(),
114
			'can_publish' => (!$page->isPublished() && (PermissionChecker::current()->hasRight("can_publish_all_pages") || (PermissionChecker::current()->hasRight("can_publish_own_pages") && $page->getAuthorID() == User::current()->getID()))),
115
			'can_change_owner' => (PermissionChecker::current()->hasRight("can_change_page_owner") || $page->getAuthorID() == User::current()->getID()),
116
			'folder' => $page->getFolder(),
117
			'preview_url' => DomainUtils::generateURL($page->getAlias(), array("preview" => "true")),
118
			'current_style' => $page->getStyle(),
119
			'template' => $page->getCustomTemplate(),
120
			'has_custom_template' => $page->hasCustomTemplate(),
121
			'parent' => $page->getParentID(),
122
			'meta_description' => $page->getMetaDescription(),
123
			'meta_keywords' => $page->getMetaKeywords(),
124
			'meta_robots' => $page->getMetaRobotsOptions(),
125
			'meta_canonicals' => $page->getMetaCanonicals(),
126
			'has_canoncials' => !empty($page->getMetaCanonicals()),
127
			'sitemap' => $page->isSitemapEnabled(),
128
			'sitemap_changefreq' => $page->getSitemapChangeFreq(),
129
			'sitemap_priority' => $page->getSitemapPriority()
130
		));
131
132
		//set available styles
133
		$template->assign("styles", StyleController::listAllStyles());
134
135
		//get all pages from database
136
		$pages = array();
137
		$rows = Database::getInstance()->listRows("SELECT `id`, `alias` FROM `{praefix}pages` WHERE `editable` = '1' AND `activated` = '1'; ");
138
139
		foreach ($rows as $row) {
140
			$pages[] = array(
141
				'id' => $row['id'],
142
				'alias' => $row['alias']
143
			);
144
		}
145
146
		$template->assign("parent_pages", $pages);
147
148
		//https://developers.google.com/search/reference/robots_meta_tag?hl=de
149
		$robots_options = array(
150
			"all",
151
			"noindex",
152
			"nofollow",
153
			"none",
154
			"noarchive",
155
			"nosnippet",
156
			"noodp",
157
			"notranslate",
158
			"noimageindex",
159
			"unavailable_after: "
160
		);
161
162
		$template->assign("robots_options", $robots_options);
163
164
		$sitemap_change_frequencies = array(
165
			"AlWAYS", "HOURLY", "DAILY", "WEEKLY", "MONTHLY", "YEARLY", "NEVER"
166
		);
167
168
		$template->assign("sitemap_changefreq", $sitemap_change_frequencies);
169
170
		//add support to show additional code from plugins
171
		$additional_code_header = "";
172
		$additional_code_footer = "";
173
174
		Events::throwEvent("page_edit_additional_code_header", array(
175
			'page' => &$page,
176
			'code' => &$additional_code_header
177
		));
178
179
		$template->assign("additional_code_header", $additional_code_footer);
180
181
		Events::throwEvent("page_edit_additional_code_footer", array(
182
			'page' => &$page,
183
			'code' => &$additional_code_footer
184
		));
185
186
		$template->assign("additional_code_footer", $additional_code_footer);
187
188
		$template->assign("errors", $error_messages);
189
		$template->assign("success_messages", $success_messages);
190
191
		return $template->getCode();
192
	}
193
194
	protected function save (Page &$page) {
195
		//first check permissions
196
		if (!PermissionChecker::current()->hasRight("can_edit_all_pages") && !(PermissionChecker::current()->hasRight("can_edit_own_pages") && $page->getAuthorID() == User::current()->getID())) {
197
			//user doesn't have permissions to edit this page
198
			return "You don't have permissions to edit this page!";
199
		}
200
201
		if (!isset($_POST['title']) || empty($_POST['title'])) {
202
			return "No title was set";
203
		}
204
205
		//validate title
206
		$title = htmlentities($_POST['title']);
207
208
		if (!isset($_POST['html_code']) || empty($_POST['html_code'])) {
209
			return "No content was set or content is empty!";
210
		}
211
212
		$content = $_POST['html_code'];
213
214
		//TODO: save page attributes
215
		if (!isset($_REQUEST['parent']) || empty($_REQUEST['parent'])) {
216
			return "Parent page wasn't set!";
217
		}
218
219
		$parent = (int) $_REQUEST['parent'];
220
221
		if (!isset($_REQUEST['design']) || empty($_REQUEST['design'])) {
222
			return "Design wasn't set!";
223
		}
224
225
		$design = $_REQUEST['design'];
226
227
		//TODO: check, if style (design) exists
228
229
		$template = "none";
230
231
		if (isset($_REQUEST['has_custom_template']) && isset($_REQUEST['template']) && !empty($_REQUEST['template'])) {
232
			$template = $_REQUEST['template'];
233
		}
234
235
		//update page in database
236
		Database::getInstance()->execute("UPDATE `{praefix}pages` SET `title` = :title, `content` = :content, `parent` = :parent, `design` = :design, `template` = :template WHERE `id` = :pageID; ", array(
237
			'title' => $title,
238
			'content' => $content,
239
			'pageID' => $page->getPageID(),
240
			'parent' => $parent,
241
			'design' => $design,
242
			'template' => $template
243
		));
244
245
		//clear cache
246
		$page->clearCache();
247
248
		//reload page from database
249
		$page->loadByID($page->getPageID(), false);
250
251
		//TODO: remove this line later
252
		Cache::clear("pages");
253
254
		return true;
255
	}
256
257
	protected function publish (Page &$page) {
258
		//check permissions for publishing
259
		if (PermissionChecker::current()->hasRight("can_publish_all_pages") || (PermissionChecker::current()->hasRight("can_publish_own_pages") && $page->getAuthorID() == User::current()->getID())) {
260
			//update page in database
261
			Database::getInstance()->execute("UPDATE `{praefix}pages` SET `published` = '1' WHERE `id` = :pageID; ", array(
262
				'pageID' => $page->getPageID()
263
			));
264
265
			//clear cache
266
			$page->clearCache();
267
268
			//reload page from database
269
			$page->loadByID($page->getPageID(), false);
270
271
			//TODO: remove this line later
272
			Cache::clear("pages");
273
274
			return true;
275
		} else {
276
			return "You don't have the permissions to publish this page!";
277
		}
278
	}
279
280
	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

280
	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...
281
		//show error
282
		$template = new DwooTemplate("pages/error");
283
		$template->assign("message", "No pageID was set!");
284
		return $template->getCode();
285
	}
286
287
	public function getFooterScripts(): string {
288
		$style_name = Registry::singleton()->getSetting("current_style_name");
289
		$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...
290
291
		$thirdparty_url = Registry::singleton()->getSetting("thirdparty_url");
292
293
		/*return "<!-- CK Editor -->
294
			<script src=\"" . $style_path . "bower_components/ckeditor/ckeditor.js\"></script>
295
			
296
			<script>
297
				$(function () {
298
					// Replace the <textarea id=\"editor1\"> with a CKEditor
299
					// instance, using default configuration.
300
					CKEDITOR.replace('wysiwygEditor', {
301
						height: '500px',
302
						enterMode: CKEDITOR.ENTER_BR
303
					});
304
				});
305
			</script>";*/
306
307
		return "<script src=\"" . $thirdparty_url . "tinymce_4.8.2/js/tinymce/tinymce.min.js\"></script>
308
  				<script>tinymce.init({
309
					  selector: 'textarea',
310
					  height: 500,
311
					  theme: 'modern',
312
					  removed_menuitems: 'newdocument',
313
					  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',
314
					  toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify  | numlist bullist outdent indent  | removeformat',
315
					  image_advtab: true
316
				});
317
				
318
				document.getElementById('customTplCheckbox').onchange = function() {
319
					document.getElementById('inputTpl').disabled = !this.checked;
320
					
321
					if (!this.checked) {
322
						document.getElementById('inputTpl').value = 'none';
323
					}
324
				};
325
				
326
				document.getElementById('customCanoncialsCheckbox').onchange = function() {
327
					document.getElementById('inputCanoncials').disabled = !this.checked;
328
					
329
					if (!this.checked) {
330
						document.getElementById('inputCanoncials').value = '';
331
					}
332
				};
333
				</script>";
334
	}
335
336
	public function listRequiredPermissions(): array {
337
		return array("can_edit_all_pages", "can_edit_own_pages");
338
	}
339
340
}
341
342
?>
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...
343