Completed
Push — master ( 38c7f6...20a216 )
by Justin
04:34
created

PageEditPage::save()   C

Complexity

Conditions 15
Paths 7

Size

Total Lines 61
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 1
Metric Value
cc 15
eloc 28
c 6
b 0
f 1
nc 7
nop 1
dl 0
loc 61
rs 5.9166

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
		));
123
124
		//set available styles
125
		$template->assign("styles", StyleController::listAllStyles());
126
127
		//get all pages from database
128
		$pages = array();
129
		$rows = Database::getInstance()->listRows("SELECT `id`, `alias` FROM `{praefix}pages` WHERE `editable` = '1' AND `activated` = '1'; ");
130
131
		foreach ($rows as $row) {
132
			$pages[] = array(
133
				'id' => $row['id'],
134
				'alias' => $row['alias']
135
			);
136
		}
137
138
		$template->assign("parent_pages", $pages);
139
140
		//add support to show additional code from plugins
141
		$additional_code_header = "";
142
		$additional_code_footer = "";
143
144
		Events::throwEvent("page_edit_additional_code_header", array(
145
			'page' => &$page,
146
			'code' => &$additional_code_header
147
		));
148
149
		$template->assign("additional_code_header", $additional_code_footer);
150
151
		Events::throwEvent("page_edit_additional_code_footer", array(
152
			'page' => &$page,
153
			'code' => &$additional_code_footer
154
		));
155
156
		$template->assign("additional_code_footer", $additional_code_footer);
157
158
		$template->assign("errors", $error_messages);
159
		$template->assign("success_messages", $success_messages);
160
161
		return $template->getCode();
162
	}
163
164
	protected function save (Page &$page) {
165
		//first check permissions
166
		if (!PermissionChecker::current()->hasRight("can_edit_all_pages") && !(PermissionChecker::current()->hasRight("can_edit_own_pages") && $page->getAuthorID() == User::current()->getID())) {
167
			//user doesn't have permissions to edit this page
168
			return "You don't have permissions to edit this page!";
169
		}
170
171
		if (!isset($_POST['title']) || empty($_POST['title'])) {
172
			return "No title was set";
173
		}
174
175
		//validate title
176
		$title = htmlentities($_POST['title']);
177
178
		if (!isset($_POST['html_code']) || empty($_POST['html_code'])) {
179
			return "No content was set or content is empty!";
180
		}
181
182
		$content = $_POST['html_code'];
183
184
		//TODO: save page attributes
185
		if (!isset($_REQUEST['parent']) || empty($_REQUEST['parent'])) {
186
			return "Parent page wasn't set!";
187
		}
188
189
		$parent = (int) $_REQUEST['parent'];
190
191
		if (!isset($_REQUEST['design']) || empty($_REQUEST['design'])) {
192
			return "Design wasn't set!";
193
		}
194
195
		$design = $_REQUEST['design'];
196
197
		//TODO: check, if style (design) exists
198
199
		$template = "none";
200
201
		if (isset($_REQUEST['has_custom_template']) && isset($_REQUEST['template']) && !empty($_REQUEST['template'])) {
202
			$template = $_REQUEST['template'];
203
		}
204
205
		//update page in database
206
		Database::getInstance()->execute("UPDATE `{praefix}pages` SET `title` = :title, `content` = :content, `parent` => :parent, `design` = :design, `template` = :template WHERE `id` = :pageID; ", array(
207
			'title' => $title,
208
			'content' => $content,
209
			'pageID' => $page->getPageID(),
210
			'parent' => $parent,
211
			'design' => $design,
212
			'template' => $template
213
		));
214
215
		//clear cache
216
		$page->clearCache();
217
218
		//reload page from database
219
		$page->loadByID($page->getPageID(), false);
220
221
		//TODO: remove this line later
222
		Cache::clear("pages");
223
224
		return true;
225
	}
226
227
	protected function publish (Page &$page) {
228
		//check permissions for publishing
229
		if (PermissionChecker::current()->hasRight("can_publish_all_pages") || (PermissionChecker::current()->hasRight("can_publish_own_pages") && $page->getAuthorID() == User::current()->getID())) {
230
			//update page in database
231
			Database::getInstance()->execute("UPDATE `{praefix}pages` SET `published` = '1' WHERE `id` = :pageID; ", array(
232
				'pageID' => $page->getPageID()
233
			));
234
235
			//clear cache
236
			$page->clearCache();
237
238
			//reload page from database
239
			$page->loadByID($page->getPageID(), false);
240
241
			//TODO: remove this line later
242
			Cache::clear("pages");
243
244
			return true;
245
		} else {
246
			return "You don't have the permissions to publish this page!";
247
		}
248
	}
249
250
	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

250
	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...
251
		//show error
252
		$template = new DwooTemplate("pages/error");
253
		$template->assign("message", "No pageID was set!");
254
		return $template->getCode();
255
	}
256
257
	public function getFooterScripts(): string {
258
		$style_name = Registry::singleton()->getSetting("current_style_name");
259
		$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...
260
261
		$thirdparty_url = Registry::singleton()->getSetting("thirdparty_url");
262
263
		/*return "<!-- CK Editor -->
264
			<script src=\"" . $style_path . "bower_components/ckeditor/ckeditor.js\"></script>
265
			
266
			<script>
267
				$(function () {
268
					// Replace the <textarea id=\"editor1\"> with a CKEditor
269
					// instance, using default configuration.
270
					CKEDITOR.replace('wysiwygEditor', {
271
						height: '500px',
272
						enterMode: CKEDITOR.ENTER_BR
273
					});
274
				});
275
			</script>";*/
276
277
		return "<script src=\"" . $thirdparty_url . "tinymce_4.8.2/js/tinymce/tinymce.min.js\"></script>
278
  				<script>tinymce.init({
279
					  selector: 'textarea',
280
					  height: 500,
281
					  theme: 'modern',
282
					  removed_menuitems: 'newdocument',
283
					  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',
284
					  toolbar1: 'formatselect | bold italic strikethrough forecolor backcolor | link | alignleft aligncenter alignright alignjustify  | numlist bullist outdent indent  | removeformat',
285
					  image_advtab: true
286
				});
287
				
288
				document.getElementById('customTplCheckbox').onchange = function() {
289
					document.getElementById('inputTpl').disabled = !this.checked;
290
					
291
					if (!this.checked) {
292
						document.getElementById('inputTpl').value = 'none';
293
					}
294
				};
295
				</script>";
296
	}
297
298
	public function listRequiredPermissions(): array {
299
		return array("can_edit_all_pages", "can_edit_own_pages");
300
	}
301
302
}
303
304
?>
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...
305