Completed
Push — master ( 253f1a...26f42a )
by Justin
04:08
created

Page::setTitle()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 2
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 3
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
class Page {
20
21
	protected $pageID = -1;
22
	protected $alias = null;
23
	protected $row = null;
24
	protected $pagetype = "";
25
26
	protected $author = null;
27
28
	//changed columns to save with save()
29
	protected $changes = array();
30
31
	public function __construct() {
32
		//
33
	}
34
35
	public function load ($alias = null) {
36
		if ($alias == null) {
37
			if (isset($_REQUEST['page']) && !empty($_REQUEST['page'])) {
38
				$alias = Validator_String::get($_REQUEST['page']);
39
			} else {
40
				$alias = $this->getDomain()->getHomePage();
41
			}
42
		} else {
43
			//$alias = Database::getInstance()->escape($alias);
44
		}
45
46
		Events::throwEvent("get_alias", array(
47
			'alias' => &$alias,
48
			'page' => &$this,
49
			'domain' => $this->getDomain()
50
		));
51
52
		$this->alias = $alias;
53
54
		if (Cache::contains("pages", "page_" . $alias)) {
55
			$this->row = Cache::get("pages", "page_" . $alias);
56
		} else {
57
			$row = Database::getInstance()->getRow("SELECT * FROM `{praefix}pages` WHERE `alias` = :alias AND `activated` = '1'; ", array('alias' => $alias));
58
59
			if (!$row) {
60
				if (PHPUtils::strEqs("error404", $alias)) {
61
					throw new IllegalStateException("No page with alias 'error404' exists (requested alias: " . $alias . ").");
62
				}
63
64
				//page not found
65
				$new_alias = "error404";
66
67
				Events::throwEvent("load_page_error404", array(
68
					'alias' => &$new_alias,
69
					'original_alias' => $alias,
70
					'page' => &$this,
71
					'domain' => $this->getDomain()
72
				));
73
74
				$this->load($new_alias);
75
				return null;
76
			}
77
78
			$this->row = $row;
79
80
			//cache result
81
			Cache::put("pages", "page_" . $alias, $row);
82
		}
83
84
		//get pageID
85
		$this->pageID = $this->row['id'];
86
87
		//get name of page type (class name)
88
		$this->pagetype = $this->row['page_type'];
89
	}
90
91
	public function loadByID (int $pageID) {
92
		if (Cache::contains("pages", "pageID_" . $pageID)) {
93
			$this->row = Cache::get("pages", "pageID_" . $pageID);
94
		} else {
95
			$row = Database::getInstance()->getRow("SELECT * FROM `{praefix}pages` WHERE `id` = :pageID; ", array('pageID' => $pageID));
96
97
			if (!$row) {
98
				throw new IllegalStateException("Page with pageID " . $pageID . " doesnt exists!");
99
			}
100
101
			$this->row = $row;
102
103
			//cache result
104
			Cache::put("pages", "pageID_" . $pageID, $row);
105
		}
106
107
		$this->pageID = $this->row['id'];
108
		$this->alias = $this->row['alias'];
109
110
		//get name of page type (class name)
111
		$this->pagetype = $this->row['page_type'];
112
	}
113
114
	protected function getDomain () : Domain {
115
		return Registry::singleton()->getObject("domain");
116
	}
117
118
	public function reloadCache () {
119
		Cache::clear("pages");
120
	}
121
122
	public function getPageID () : int {
123
		return $this->row['id'];
124
	}
125
126
	public function getAlias () : string {
127
		return $this->alias;
128
	}
129
130
	public function getPageType () : string {
131
		return $this->pagetype;
132
	}
133
134
	public function getTitle () : string {
135
		return $this->row['title'];
136
	}
137
138
	public function setTitle (string $title) : string {
139
		$this->row['title'] = $title;
140
		$this->changes[] = "title";
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...
141
	}
142
143
	public function getContent () : string {
144
		return $this->row['content'];
145
	}
146
147
	public function setContent (string $content) : string {
148
		$this->row['content'] = $content;
149
		$this->changes[] = "content";
150
		$this->changes[] = "content";
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...
151
	}
152
153
	public function getGlobalMenuID () : int {
154
		return $this->row['global_menu'];
155
	}
156
157
	public function getLocalMenuID () : int {
158
		return $this->row['local_menu'];
159
	}
160
161
	public function getStyle () : string {
162
		return $this->row['design'];
163
	}
164
165
	public function getFolder () : string {
166
		return $this->row['folder'];
167
	}
168
169
	public function getLastEdit () {
170
		return $this->row['lastUpdate'];
171
	}
172
173
	public function hasCustomTemplate () : bool {
174
		return $this->row['template'] !== "none";
175
	}
176
177
	public function getCustomTemplate () : string {
178
		return $this->row['template'];
179
	}
180
181
	public function hasCustomPermissions () : bool {
182
		return $this->row['can_see_permissions'] !== "none";
183
	}
184
185
	public function listCustomPermissions () : array {
186
		return explode("|", $this->row['can_see_permissions']);
187
	}
188
189
	public function isPublished () : bool {
190
		return $this->row['published'] == 1;
191
	}
192
193
	public function publish () {
194
		$this->row['published'] = 1;
195
	}
196
197
	public function getContentType () : string {
198
		return $this->row['content_type'];
199
	}
200
201
	public function getLeftSidebarID () : int {
202
		return $this->row['sidebar_left'];
203
	}
204
205
	public function getRightSidebarID () : int {
206
		return $this->row['sidebar_right'];
207
	}
208
209
	public function getMetaDescription () : string {
210
		return $this->row['meta_description'];
211
	}
212
213
	public function getMetaKeywords () : string {
214
		return $this->row['meta_keywords'];
215
	}
216
217
	public function getMetaRobotsOptions () : string {
218
		return $this->row['meta_robots'];
219
	}
220
221
	public function getMetaCanonicals () : string {
222
		return $this->row['meta_canonicals'];
223
	}
224
225
	public function getAuthorID () : int {
226
		return $this->row['author'];
227
	}
228
229
	public function getAuthor () : User {
230
		if ($this->author == null) {
231
			//load author
232
			$this->author = new User();
233
234
			if ($this->getAuthorID() <= 0) {
235
				throw new IllegalArgumentException("authorID has to be > 0.");
236
			}
237
238
			$this->author->load($this->getAuthorID());
239
		}
240
241
		return $this->author;
242
	}
243
244
	public function activate (bool $bool = true) {
245
		$this->row['activated'] = ($bool ? 1 : 0);
246
	}
247
248
	public function isTrash () : bool {
249
		return $this->row['activated'] == 2;
250
	}
251
252
	public function isEditable () : bool {
253
		return $this->row['editable'] == 1;
254
	}
255
256
	public function isDeletable () : bool {
257
		return $this->row['deletable'] == 1;
258
	}
259
260
	public function isActivated () : bool {
261
		return $this->row['activated'] == 1;
262
	}
263
264
	public function moveToTrash () {
265
		self::movePageToTrash($this->pageID);
266
267
		//clear cache
268
		Cache::clear("pages", "pageID_" . $this->pageID);
269
		Cache::clear("pages", "page_" . $this->alias);
270
	}
271
272
	/**
273
	 * restore page from trash
274
	 */
275
	public function restore () {
276
		self::restorePage($this->pageID);
277
278
		//clear cache
279
		Cache::clear("pages", "pageID_" . $this->pageID);
280
		Cache::clear("pages", "page_" . $this->alias);
281
	}
282
283
	/**
284
	 * save changes into database
285
	 */
286
	public function save () {
287
		//TODO: add code here
288
	}
289
290
	public static function createIfAbsent (string $alias, string $title, string $page_type, string $content = "", string $folder = "/", int $globalMenu = -1, int $localMenu = -1, int $parentID = -1, bool $sitemap = true, bool $published = true, bool $editable = true, bool $deletable = true, string $author = "system") : int {
291
		//throw event
292
		Events::throwEvent("create_page", array(
293
			'alias' => &$alias,
294
			'title' => &$title,
295
			'page_type' => &$page_type,
296
			'content' => &$content,
297
			'folder' => &$folder,
298
			'global_menu' => &$globalMenu,
299
			'local_menu' => &$localMenu,
300
			'parentID' => &$parentID,
301
			'sitemap' => &$sitemap,
302
			'published' => &$published,
303
			'editable' => &$editable,
304
			'author' => &$author
305
		));
306
307
		if (!is_int($author)) {
0 ignored issues
show
introduced by
The condition is_int($author) is always false.
Loading history...
308
			//get userID of author
309
			$author = User::getIDByUsernameFromDB($author);
310
311
			if ($author == -1) {
312
				//username doesnt exists, so choose first user
313
				$author = 1;
314
			}
315
		} else {
316
			$author = (int) $author;
317
		}
318
319
		Database::getInstance()->execute("INSERT INTO `{praefix}pages` (
320
			`id`, `alias`, `title`, `content`, `parent`, `folder`, `global_menu`, `local_menu`, `page_type`, `design`, `sitemap`, `published`, `version`, `last_update`, `created`, `editable`, `deletable`, `author`, `activated`
321
		) VALUES (
322
			NULL, :alias, :title, :content, :parent, :folder, :globalMenu, :localMenu, :pageType, 'none', :sitemap, :published, '1', '0000-00-00 00:00:00', CURRENT_TIMESTAMP, :editable, :deletable, :author, '1'
323
		) ON DUPLICATE KEY UPDATE `alias` = :alias, `editable` = :editable, `deletable` = :deletable; ", array(
324
			'alias' => $alias,
325
			'title' => $title,
326
			'content' => $content,
327
			'parent' => $parentID,
328
			'folder' => $folder,
329
			'globalMenu' => $globalMenu,
330
			'localMenu' => $localMenu,
331
			'pageType' => $page_type,
332
			'sitemap' => ($sitemap ? 1 : 0),
333
			'published' => ($published ? 1 : 0),
334
			'editable' => ($editable ? 1 : 0),
335
			'deletable' => ($deletable ? 1 : 0),
336
			'author' => $author
337
		));
338
339
		Cache::clear("pages");
340
341
		//return page id
342
		$insertID = Database::getInstance()->lastInsertId();
343
344
		//throw event
345
		Events::throwEvent("created_page", array(
346
			'alias' => $alias,
347
			'title' => $title,
348
			'insertID' => $insertID
349
		));
350
351
		//get pageID by alias
352
		$pageID = Page::getPageIDByAlias($alias);
353
354
		//set default rights, allow page for administrators, registered users, guests and bots
355
		PageRights::setDefaultAllowedGroups($pageID, array(1, 2, 3, 4));
356
357
		return $pageID;
358
	}
359
360
	public static function delete (string $alias) {
361
		$delete = true;
362
363
		//plugins can avoid deletion or change alias
364
		Events::throwEvent("delete_page_alias", array(
365
			'alias' => &$alias,
366
			'delete' => &$delete
367
		));
368
369
		if ($delete) {
0 ignored issues
show
introduced by
The condition $delete is always true.
Loading history...
370
			//remove page from database
371
			Database::getInstance()->execute("DELETE FROM `{praefix}pages` WHERE `alias` = :alias; ", array('alias' => $alias));
372
373
			Cache::clear("pages");
374
		}
375
	}
376
377
	public static function deleteByID (int $id) {
378
		$delete = true;
379
380
		//plugins can avoid deletion or change alias
381
		Events::throwEvent("delete_page_id", array(
382
			'alias' => &$id,
383
			'delete' => &$delete
384
		));
385
386
		if ($delete) {
0 ignored issues
show
introduced by
The condition $delete is always true.
Loading history...
387
			//remove page from database
388
			Database::getInstance()->execute("DELETE FROM `{praefix}pages` WHERE `id` = :id; ", array('id' => $id));
389
390
			Cache::clear("pages");
391
		}
392
	}
393
394
	public static function get (string $alias) : Page {
395
		$page = new Page();
396
		$page->load($alias);
397
398
		return $page;
399
	}
400
401
	public static function setPageType (string $alias, string $page_type) {
402
		Events::throwEvent("set_pagetype", array(
403
			'alias' => &$alias,
404
			'page_type' => &$page_type
405
		));
406
407
		Database::getInstance()->execute("UPDATE `{praefix}pages` SET `page_type` = :page_type WHERE `alias` = :alias; ", array(
408
			'alias' => $alias,
409
			'page_type' => $page_type
410
		));
411
412
		Cache::clear("pages");
413
	}
414
415
	/**
416
	 * get id of page by alias
417
	 *
418
	 * only use this method for database upgrade, because their is no caching for this method!
419
	 *
420
	 * @param string $alias alias of page
421
	 *
422
	 * @throws IllegalStateException if alias doesnt exists
423
	 *
424
	 * @return int pageID
425
	 */
426
	public static function getPageIDByAlias (string $alias) : int {
427
		$row = Database::getInstance()->getRow("SELECT * FROM `{praefix}pages` WHERE `alias` = :alias; ", array('alias' => $alias));
428
429
		if (!$row) {
430
			throw new IllegalStateException("page with alias '" . $alias . "' doesnt exists.");
431
		}
432
433
		return $row['id'];
434
	}
435
436
	public static function lockPage (int $pageID, int $userID) {
437
		Database::getInstance()->execute("UPDATE `{praefix}pages` SET `locked_by` = :userID, `locked_timestamp` = CURRENT_TIMESTAMP WHERE `id` = :pageID; ", array(
438
			'userID' => $userID,
439
			'pageID' => $pageID
440
		));
441
	}
442
443
	public static function unlockPage (int $pageID) {
444
		Database::getInstance()->execute("UPDATE `{praefix}pages` SET `locked_by` WHERE `id` = :pageID; ", array(
445
			'pageID' => $pageID
446
		));
447
	}
448
449
	protected static function movePageToTrash (int $pageID) {
450
		Database::getInstance()->execute("UPDATE `{praefix}pages` SET `activated` = 2 WHERE `id` = :pageID; ", array(
451
			'pageID' => $pageID
452
		));
453
454
		//clear cache
455
		Cache::clear("pages", "pageID_" . $pageID);
456
	}
457
458
	protected static function restorePage (int $pageID) {
459
		Database::getInstance()->execute("UPDATE `{praefix}pages` SET `activated` = 1 WHERE `id` = :pageID; ", array(
460
			'pageID' => $pageID
461
		));
462
463
		//clear cache
464
		Cache::clear("pages", "pageID_" . $pageID);
465
	}
466
467
	public static function exists (string $alias) : bool {
468
		$row = Database::getInstance()->getRow("SELECT * FROM `{praefix}pages` WHERE `alias` = :alias; ", array(
469
			'alias' => $alias
470
		));
471
472
		return $row !== false;
473
	}
474
475
}
476
477
?>
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...
478