Skip to content

Commit e1a7611

Browse files
add a list of reserved page IDs containing 'media' and 'assets'. close #503
refactor: Modelpage::add() throws exceptions instead of returning a bool avoid infinite loop by deactivating Apache trailing slash in .htaccess
1 parent c5f83fd commit e1a7611

File tree

5 files changed

+70
-26
lines changed

5 files changed

+70
-26
lines changed

.htaccess

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1+
# prevent Apache from adding trailing slash for names that match folder
2+
# in order to avoid conflict with Controllerpage::pagepermanentredirect()
3+
# and 'assets' and 'media' folder
4+
DirectorySlash off
15
RewriteEngine on
26
# everything that does not contain asssets|media
37
RewriteCond %{REQUEST_URI} !^(.*)/(assets|media)/ [OR]
48
# or that isn't a file
59
RewriteCond %{REQUEST_FILENAME} !-f
610
# is redirect to index
711
RewriteRule . index.php [L]
12+

MANUAL.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ This will print a HTML list of every [authors](#authors) of the page. If they ha
291291

292292
%PAGEID% | %ID%
293293

294-
You have two options to print the page ID.
294+
You have two options to print the [page ID](#page-id).
295295

296296
This is powerfull when combined with [URL commands](#url-based-command-interface) and [BODY templating](#body-template).
297297

@@ -954,6 +954,8 @@ Page metadatas can be set through the page [edition interface](#edition-interfac
954954
##### Page ID
955955

956956
__The unique identifier of a page__. It can only contain lowercases characters from `a-z`, numbers `0-9`, underscore `_` and hyphen `-`.
957+
Also, `assets` and `media` are reserved paths, therefore cannot be used as page ID.
958+
957959
Normaly W will take care of cleaning your pages's ID, by lowering uppercases, removing some accents, and remplacing special characters or spaces with hyphens.
958960

959961

app/class/Controllerapipage.php

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ public function update(string $page)
9797
}
9898
}
9999

100+
/**
101+
* @throws RuntimeException when saving page fails
102+
*/
100103
public function add(string $page)
101104
{
102105
if (!Model::idcheck($page)) {
@@ -111,13 +114,12 @@ public function add(string $page)
111114

112115
$this->page = $this->pagemanager->newpage(array_merge($this->recievejson(), ['id' => $page]));
113116
$this->page->addauthor($this->user->id());
114-
if ($this->pagemanager->add($this->page)) {
115-
http_response_code(200);
116-
} else {
117-
http_response_code(500);
118-
}
117+
$this->pagemanager->add($this->page);
119118
}
120119

120+
/**
121+
* @throws RuntimeException when saving page fails
122+
*/
121123
public function put(string $page)
122124
{
123125
if (!Model::idcheck($page)) {
@@ -134,11 +136,8 @@ public function put(string $page)
134136
if (!$exist) { // If it's a page creation, add the user as an author
135137
$this->page->addauthor($this->user->id());
136138
}
137-
if ($this->pagemanager->add($this->page)) {
138-
http_response_code($exist ? 200 : 201);
139-
} else {
140-
$this->shortresponse(500, "Error while trying to save page in database");
141-
}
139+
$this->pagemanager->add($this->page);
140+
http_response_code($exist ? 200 : 201);
142141
}
143142

144143
public function delete(string $page)

app/class/Controllerpage.php

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ public function __construct($router)
2020
$this->mediamanager = new Modelmedia();
2121
}
2222

23+
/**
24+
* Check a given page ID. If it's not a valid ID, then redirect to the clean ID version.
25+
* If it's valid, setup $this->page` with a new empty Page using given ID.
26+
*
27+
* @param $id The id received by the router
28+
* @param $route The route that was used
29+
*/
2330
protected function setpage(string $id, string $route): void
2431
{
2532
$cleanid = Model::idclean($id);
@@ -318,25 +325,39 @@ public function log($page): void
318325
}
319326
}
320327

328+
/**
329+
* When a client want to add a page.
330+
* Match domain.com/PAGE_ID/add
331+
*
332+
* @throws RuntimeException if page creation failed
333+
*/
321334
public function add(string $page): void
322335
{
323336
$this->setpage($page, 'pageadd');
324337

325338
$this->pageconnect('pageadd');
326339

327-
if ($this->user->iseditor() && !$this->importpage()) {
328-
$this->page->reset();
329-
if (isset($_SESSION['dirtyid'])) {
330-
$this->page->settitle($_SESSION['dirtyid'][$page]);
331-
unset($_SESSION['dirtyid']);
332-
}
333-
$this->page->addauthor($this->user->id());
334-
$this->pagemanager->add($this->page);
335-
$this->routedirect('pageedit', ['page' => $this->page->id()]);
336-
} else {
340+
if (!$this->user->iseditor()) {
337341
http_response_code(403);
338342
$this->showtemplate('forbidden', ['route' => 'pageedit', 'id' => $this->page->id()]);
343+
exit;
339344
}
345+
346+
if ($this->importpage()) {
347+
http_response_code(403);
348+
$message = 'page already exist with this ID';
349+
$this->showtemplate('forbidden', ['route' => 'pageedit', 'id' => $this->page->id(), 'message' => $message]);
350+
exit;
351+
}
352+
353+
$this->page->reset();
354+
if (isset($_SESSION['dirtyid'])) {
355+
$this->page->settitle($_SESSION['dirtyid'][$page]);
356+
unset($_SESSION['dirtyid']);
357+
}
358+
$this->page->addauthor($this->user->id());
359+
$this->pagemanager->add($this->page);
360+
$this->routedirect('pageedit', ['page' => $this->page->id()]);
340361
}
341362

342363
public function addascopy(string $page, string $copy): void
@@ -403,8 +424,12 @@ public function upload(): void
403424
$page->setdaterender($page->datecreation('date'));
404425

405426
if ($_POST['erase'] || !$this->pagemanager->exist($page)) {
406-
if ($this->pagemanager->add($page)) {
427+
try {
428+
$this->pagemanager->add($page);
407429
$this->sendflashmessage('Page successfully uploaded', self::FLASH_SUCCESS);
430+
} catch (RuntimeException $e) {
431+
$this->sendflashmessage($e->getMessage(), self::FLASH_ERROR);
432+
Logger::errorex($e);
408433
}
409434
} else {
410435
$this->sendflashmessage(

app/class/Modelpage.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@
1010
use InvalidArgumentException;
1111
use RangeException;
1212
use RuntimeException;
13+
use Wcms\Exception\Databaseexception;
1314
use Wcms\Exception\Filesystemexception;
1415
use Wcms\Exception\Filesystemexception\Notfoundexception;
1516

1617
class Modelpage extends Modeldb
1718
{
19+
public const RESERVED_IDS = [
20+
'media',
21+
'assets',
22+
];
23+
1824
public const SECURE_LEVELS = [
1925
0 => 'public',
2026
1 => 'private',
@@ -82,14 +88,21 @@ public function pagelistbyid(array $idlist = []): array
8288
* Store new page in the database
8389
*
8490
* @param Page $page Page object
85-
* @return bool depending on database storing
91+
*
92+
* @throws RuntimeException if page ID is illegal
93+
* @throws Databaseexception if error occured whiling saving document
8694
*/
87-
public function add(Page $page): bool
95+
public function add(Page $page): void
8896
{
89-
97+
if (in_array($page->id(), self::RESERVED_IDS)) {
98+
$id = $page->id();
99+
throw new RuntimeException("'$id' is a reserved page ID");
100+
}
90101
$pagedata = new Document($page->dry());
91102
$pagedata->setId($page->id());
92-
return $this->storedoc($pagedata);
103+
if (!$this->storedoc($pagedata)) {
104+
throw new Databaseexception('Error wile trying to save document to database. Check logs for more info');
105+
}
93106
}
94107

95108
/**

0 commit comments

Comments
 (0)