Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
88.57% |
31 / 35 |
CRAP | |
95.27% |
443 / 465 |
| Page | |
0.00% |
0 / 1 |
|
88.57% |
31 / 35 |
124 | |
95.27% |
443 / 465 |
| __construct(\Scrivo\Context $context=null) | |
100.00% |
1 / 1 |
2 | |
100.00% |
23 / 23 |
|||
| __get($name) | |
100.00% |
1 / 1 |
25 | |
100.00% |
27 / 27 |
|||
| __set($name, $value) | |
100.00% |
1 / 1 |
14 | |
100.00% |
14 / 14 |
|||
| setFields(\Scrivo\Context $context, array $rd) | |
100.00% |
1 / 1 |
3 | |
100.00% |
19 / 19 |
|||
| getProperties() | |
0.00% |
0 / 1 |
2.15 | |
66.67% |
4 / 6 |
|||
| getChildren() | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
| getNavigableChildren() | |
0.00% |
0 / 1 |
14.72 | |
12.50% |
1 / 8 |
|||
| getPath() | |
100.00% |
1 / 1 |
2 | |
100.00% |
5 / 5 |
|||
| getIsOnline() | |
0.00% |
0 / 1 |
20 | |
0.00% |
0 / 11 |
|||
| setHasStaging($hasStaging) | |
100.00% |
1 / 1 |
1 | |
100.00% |
5 / 5 |
|||
| setParentPageId($parentId) | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
| setType($type) | |
100.00% |
1 / 1 |
1 | |
100.00% |
8 / 8 |
|||
| setDefinitionId($definitionId) | |
100.00% |
1 / 1 |
2 | |
100.00% |
8 / 8 |
|||
| setLanguageId($languageId) | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
| setTitle(\Scrivo\String $title) | |
100.00% |
1 / 1 |
1 | |
100.00% |
3 / 3 |
|||
| setDescription(\Scrivo\String $description) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| setKeywords(\Scrivo\String $keywords) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| setJavascript(\Scrivo\String $javascript) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| setStylesheet(\Scrivo\String $stylesheet) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| setDateOnline(\DateTime $dateOnline) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| setDateOffline(\DateTime $dateOffline=null) | |
100.00% |
1 / 1 |
1 | |
100.00% |
2 / 2 |
|||
| setContext(\Scrivo\Context $context) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 2 |
|||
| selectProperties($context, array $pages) | |
100.00% |
1 / 1 |
4 | |
100.00% |
19 / 19 |
|||
| selectRoles($context, array $pages) | |
100.00% |
1 / 1 |
2 | |
100.00% |
10 / 10 |
|||
| validateInsert() | |
100.00% |
1 / 1 |
4 | |
100.00% |
18 / 18 |
|||
| insert() | |
100.00% |
1 / 1 |
5 | |
100.00% |
38 / 38 |
|||
| validateUpdate() | |
100.00% |
1 / 1 |
2 | |
100.00% |
7 / 7 |
|||
| update() | |
100.00% |
1 / 1 |
6 | |
100.00% |
43 / 43 |
|||
| validateDelete(\Scrivo\Context $context, $id) | |
100.00% |
1 / 1 |
4 | |
100.00% |
23 / 23 |
|||
| touch(\Scrivo\Context $context, $id) | |
100.00% |
1 / 1 |
2 | |
100.00% |
13 / 13 |
|||
| delete(\Scrivo\Context $context, $id) | |
100.00% |
1 / 1 |
3 | |
100.00% |
25 / 25 |
|||
| move($dir=\Scrivo\SequenceNo::MOVE_DOWN) | |
100.00% |
1 / 1 |
2 | |
100.00% |
8 / 8 |
|||
| fetch(\Scrivo\Context $context, $id=null) | |
100.00% |
1 / 1 |
4 | |
100.00% |
27 / 27 |
|||
| selectChildren(\Scrivo\Page $page) | |
100.00% |
1 / 1 |
6 | |
100.00% |
30 / 30 |
|||
| selectPath(\Scrivo\Page $page) | |
100.00% |
1 / 1 |
8 | |
100.00% |
36 / 36 |
|||
| <?php | |
| /* Copyright (c) 2012, Geert Bergman (geert@scrivo.nl) | |
| * All rights reserved. | |
| * | |
| * Redistribution and use in source and binary forms, with or without | |
| * modification, are permitted provided that the following conditions are met: | |
| * | |
| * 1. Redistributions of source code must retain the above copyright notice, | |
| * this list of conditions and the following disclaimer. | |
| * 2. Redistributions in binary form must reproduce the above copyright notice, | |
| * this list of conditions and the following disclaimer in the documentation | |
| * and/or other materials provided with the distribution. | |
| * 3. Neither the name of "Scrivo" nor the names of its contributors may be | |
| * used to endorse or promote products derived from this software without | |
| * specific prior written permission. | |
| * | |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| * POSSIBILITY OF SUCH DAMAGE. | |
| * | |
| * $Id: Page.php 866 2013-08-25 16:22:35Z geert $ | |
| */ | |
| /** | |
| * Implementation of the \Scrivo\Page class. | |
| */ | |
| namespace Scrivo; | |
| /** | |
| * A Scrivo Page is most essential Scrivo entity. A Scrivo page models a HTML | |
| * Page (most of the times). The idea is that a Web site is a set of pages. The | |
| * dynamic content that should be presented on these web pages is contained by | |
| * Scrivo Page objects. | |
| * | |
| * Therefore a Scrivo page contains some of the standard fields that are | |
| * typical for a HTML page suchs as the page title, description and keywords | |
| * along with some managerial (CMS) information as online and ofline date. | |
| * | |
| * What other content should be displayed on the page is determined by its | |
| * page defintion. Each page is constructed using a a page defintion and this | |
| * defintion holds the defintions for all other data (properties, texts, | |
| * lists, applications) that can added to the page. | |
| * | |
| * The Scrivo editor interface provides the means to the editor to create | |
| * pages and fill in the page properties. | |
| * | |
| * How the content that is assigned to the page should be displayed on the | |
| * page is determined by the page template. The page defintion has a member | |
| * that refers to the page template: a user defined script that renders the | |
| * actual page. | |
| * | |
| * @property-read int $id The page id (DB key). | |
| * @property-read \Scrivo\PageDefinition $definition The page definition of | |
| * this page. | |
| * @property-read booleand $isOnline If this page is online or not. | |
| * @property-read \Scrivo\Language $language The main language for the | |
| * page (<html lang>). | |
| * @property-read \Scrivo\PropertySet $properties The page properties as a | |
| * PHP object in which the members correspond with the PHP selector names. | |
| * @property-read \Scrivo\RoleSet $roles The attached roles. | |
| * @property-read \Scrivo\PageSet $children The child pages of this page. | |
| * @property-read \Scrivo\PageSet $navigableChildren The navigable child | |
| * pages of this page. | |
| * @property-read \Scrivo\PageSet $path The parent pages of this page. | |
| * @property-read \DateTime $dateCreated The date/time that this page was | |
| * created. | |
| * @property-read \DateTime $dateModified The last date/time that this page | |
| * was modified. | |
| * @property \Scrivo\Context $context A Scrivo context of this page. | |
| * @property boolean $hasStaging Setting to indicate if the page can be staged. | |
| * @property int $parentId The id of the parent page. | |
| * @property int $type The page type: one out of the Page::TYPE_* constant | |
| * values. | |
| * @property \Scrivo\String $title The page title (<title>). | |
| * @property \Scrivo\String $description The page description | |
| * (<description>). | |
| * @property \Scrivo\String $keywords The keywords for this page | |
| * (<keywords>). | |
| * @property \Scrivo\String $javascript A javascript script for this page | |
| * (<script>). | |
| * @property \Scrivo\String $stylesheet Additional CSS syle rules for this | |
| * page (<stylesheet>). | |
| * @property \DateTime $dateOnline The date/time this page need to go online. | |
| * @property \DateTime $dateOffline The date/time this page need to go offline. | |
| * @property-write int $definitionId The id of the page template. | |
| * @property-write int $languageId The id of the main language for the page | |
| * (<html lang>). | |
| */ | |
| class Page { | |
| /** | |
| * Value indicating a navigation item (page that only functions as a node). | |
| */ | |
| const TYPE_NAVIGATION_ITEM = 0; | |
| /** | |
| * Value indicating a page that should be shown in the site menu. | |
| */ | |
| const TYPE_NAVIGABLE_PAGE = 1; | |
| /** | |
| * Value indicating a page that should not be shown in the site menu. | |
| */ | |
| const TYPE_NON_NAVIGABLE_PAGE = 2; | |
| /** | |
| * Value indicating an extra node to hold automatically generated pages | |
| * that are linked to list items. | |
| */ | |
| const TYPE_SUB_FOLDER = 4; | |
| /** | |
| * Value indicating an application: a page that has no functionality as | |
| * a page but hosts an application in the scrivo user interface. | |
| */ | |
| const TYPE_APPLICATION = 5; | |
| /** | |
| * The page id (DB key). | |
| * @var int | |
| */ | |
| private $id = 0; | |
| /** | |
| * The current version of the page: -1: scratch version, 0 live version, | |
| * 1 and up versions. | |
| * @var int | |
| */ | |
| private $version = 0; | |
| /** | |
| * Setting to indicate if the page can be staged. | |
| * @var boolean | |
| */ | |
| private $hasStaging = 0; | |
| /** | |
| * The id of the parent page. | |
| * @var int | |
| */ | |
| private $parentId = 0; | |
| /** | |
| * The page type: one out of the Page::TYPE_* constant values. | |
| * @var int | |
| */ | |
| private $type = 0; | |
| /** | |
| * The id of the page template. | |
| * @var int | |
| */ | |
| private $definitionId = 0; | |
| /** | |
| * The id the main language for the page (<html lang>). | |
| * @var int | |
| */ | |
| private $languageId = 0; | |
| /** | |
| * The page title (<title>). | |
| * @var \Scrivo\String | |
| */ | |
| private $title = null; | |
| /** | |
| * The page description (<description>). | |
| * @var \Scrivo\String | |
| */ | |
| private $description = null; | |
| /** | |
| * The keywords for this page (<keywords>). | |
| * @var \Scrivo\String | |
| */ | |
| private $keywords = null; | |
| /** | |
| * A javascript script for this page (<script>). | |
| * @var \Scrivo\String | |
| */ | |
| private $javascript = null; | |
| /** | |
| * Additional CSS syle rules for this page (<stylesheet>). | |
| * @var \Scrivo\String | |
| */ | |
| private $stylesheet = null; | |
| /** | |
| * The date/time that this page was created. | |
| * @var \DateTime | |
| */ | |
| private $dateCreated = null; | |
| /** | |
| * The last date/time that this page was modified. | |
| * @var \DateTime | |
| */ | |
| private $dateModified = null; | |
| /** | |
| * The date/time this page need to go online. | |
| * @var \DateTime | |
| */ | |
| private $dateOnline = null; | |
| /** | |
| * The date/time this page need to go offline. | |
| * @var \DateTime | |
| */ | |
| private $dateOffline = null; | |
| /** | |
| * The page properties as a PHP object in which the members correspond | |
| * with the PHP selector names. | |
| * @var \Scrivo\PropertySet | |
| */ | |
| private $properties = null; | |
| /** | |
| * The child pages of this page. | |
| * @var \Scrivo\PageSet | |
| */ | |
| private $children = null; | |
| /** | |
| * The parent pages of this page. | |
| * @var \Scrivo\PageSet | |
| */ | |
| private $path = null; | |
| /** | |
| * The attached roles. | |
| * @var \Scrivo\RoleSet | |
| */ | |
| private $roles = null; | |
| /** | |
| * A Scrivo context. | |
| * @var \Scrivo\Context | |
| */ | |
| private $context = null; | |
| /** | |
| * Create an empty page object. | |
| * | |
| * @param \Scrivo\Context $context A Scrivo context. | |
| */ | |
| public function __construct(\Scrivo\Context $context=null) { | |
| \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null), 0); | |
| if ($context) { | |
| $this->id = 0; | |
| $this->version = 0; | |
| $this->hasStaging = false; | |
| $this->parentId = 0; | |
| $this->type = 0; | |
| $this->definitionId = 0; | |
| $this->languageId = 0; | |
| $this->title = new \Scrivo\String(); | |
| $this->description = new \Scrivo\String(); | |
| $this->keywords = new \Scrivo\String(); | |
| $this->javascript = new \Scrivo\String(); | |
| $this->stylesheet = new \Scrivo\String(); | |
| $this->dateCreated = new \DateTime("now"); | |
| $this->dateModified = new \DateTime("now"); | |
| $this->dateOnline = new \DateTime("now"); | |
| $this->dateOffline = null; | |
| $this->properties = null; | |
| $this->roles = new \Scrivo\RoleSet(); | |
| $this->context = $context; | |
| } | |
| } | |
| /** | |
| * Implementation of the readable properties using the PHP magic | |
| * method __get(). | |
| * | |
| * @param string $name The name of the property to get. | |
| * | |
| * @return mixed The value of the requested property. | |
| */ | |
| public function __get($name) { | |
| switch($name) { | |
| case "id": return $this->id; | |
| case "hasStaging": return $this->hasStaging; | |
| case "parentId": return $this->parentId; | |
| case "type": return $this->type; | |
| case "definition": return $this->definitionId ? | |
| \Scrivo\PageDefinition::fetch($this->context, $this->definitionId) | |
| : new \Scrivo\PageDefinition($this->context); | |
| case "language": return $this->languageId ? | |
| \Scrivo\Language::fetch($this->context, $this->languageId) | |
| : new \Scrivo\Language($this->context); | |
| case "title": return $this->title; | |
| case "description": return $this->description; | |
| case "keywords": return $this->keywords; | |
| case "javascript": return $this->javascript; | |
| case "stylesheet": return $this->stylesheet; | |
| case "dateCreated": return $this->dateCreated; | |
| case "dateModified": return $this->dateModified; | |
| case "dateOnline": return $this->dateOnline; | |
| case "dateOffline": return $this->dateOffline; | |
| case "isOnline": return $this->getIsOnline(); | |
| case "properties": return $this->getProperties(); | |
| case "roles": return $this->roles; | |
| case "children": return $this->getChildren(); | |
| case "navigableChildren": return $this->getNavigableChildren(); | |
| case "path": return $this->getPath(); | |
| case "context": return $this->context; | |
| } | |
| throw new \Scrivo\SystemException("No such property-get '$name'."); | |
| } | |
| /** | |
| * Implementation of the writable properties using the PHP magic | |
| * method __set(). | |
| * | |
| * @param string $name The name of the property to set. | |
| * @param mixed $value The value of the property to set. | |
| */ | |
| public function __set($name, $value) { | |
| switch($name) { | |
| case "hasStaging": $this->setHasStaging($value); return; | |
| case "parentId": $this->setParentPageId($value); return; | |
| case "type": $this->setType($value); return; | |
| case "definitionId": $this->setDefinitionId($value); return; | |
| case "languageId": $this->setLanguageId($value); return; | |
| case "title": $this->setTitle($value); return; | |
| case "description": $this->setDescription($value); return; | |
| case "keywords": $this->setKeywords($value); return; | |
| case "javascript": $this->setJavascript($value); return; | |
| case "stylesheet": $this->setStylesheet($value); return; | |
| case "dateOnline": $this->setDateOnline($value); return; | |
| case "dateOffline": $this->setDateOffline($value); return; | |
| case "context": $this->setContext($value); return; | |
| } | |
| throw new \Scrivo\SystemException("No such property-set '$name'."); | |
| } | |
| /** | |
| * Convenience method to set the fields of a page definition object from | |
| * an array (result set row). | |
| * | |
| * @param \Scrivo\Context $context A Scrivo context. | |
| * @param array $rd An array containing the field data using the database | |
| * field names as keys. | |
| */ | |
| private function setFields(\Scrivo\Context $context, array $rd) { | |
| $this->id = intval($rd["page_id"]); | |
| $this->version = intval($rd["version"]); | |
| $this->hasStaging = intval($rd["has_staging"]) == 1 ? true : false; | |
| $this->parentId = intval($rd["parent_id"]); | |
| $this->type = intval($rd["type"]); | |
| $this->definitionId = intval($rd["page_definition_id"]); | |
| $this->languageId = intval($rd["language_id"]); | |
| $this->title = new \Scrivo\String($rd["title"]); | |
| $this->description = new \Scrivo\String($rd["description"]); | |
| $this->keywords = new \Scrivo\String($rd["keywords"]); | |
| $this->javascript = new \Scrivo\String($rd["javascript"]); | |
| $this->stylesheet = new \Scrivo\String($rd["stylesheet"]); | |
| $this->dateCreated = new \DateTime($rd["date_created"]); | |
| $this->dateModified = new \DateTime($rd["date_modified"]); | |
| $this->dateOnline = new \DateTime($rd["date_online"]); | |
| $this->dateOffline = $rd["date_offline"] == null | |
| ? null : new \DateTime($rd["date_offline"]); | |
| $this->context = $context; | |
| } | |
| /** | |
| * Get this pages's property list. | |
| * | |
| * @return object This pages's property list. | |
| */ | |
| private function getProperties() { | |
| if ($this->properties === null) { | |
| self::selectProperties($this->context, array($this->id => $this)); | |
| $this->context->cache[$this->id] = $this; | |
| } | |
| return $this->properties; | |
| } | |
| /** | |
| * Get the child pages of this page. | |
| * | |
| * @return \Scrivo\PageSet The child pages of the page. | |
| */ | |
| private function getChildren() { | |
| if ($this->children === null) { | |
| $this->children = self::selectChildren($this); | |
| $this->context->cache[$this->id] = $this; | |
| } | |
| return $this->children; | |
| } | |
| /** | |
| * Get the navigable child pages of this page. | |
| * | |
| * @return \Scrivo\PageSet The navigable child pages of the page. | |
| */ | |
| private function getNavigableChildren() { | |
| $res = array(); | |
| foreach ($this->getChildren() as $chld) { | |
| if ($chld->type === self::TYPE_NAVIGABLE_PAGE | |
| || $chld->type === self::TYPE_NAVIGATION_ITEM) { | |
| $res[] = $chld; | |
| } | |
| } | |
| return $res; | |
| } | |
| /** | |
| * Get the child pages of this page. | |
| * | |
| * @return \Scrivo\PageSet All pages above the current page. | |
| */ | |
| private function getPath() { | |
| if ($this->path === null) { | |
| $this->path = self::selectPath($this); | |
| $this->context->cache[$this->id] = $this; | |
| } | |
| return $this->path; | |
| } | |
| /** | |
| * Check if this page is online. | |
| * | |
| * @return boolean True if this page is online else false. | |
| */ | |
| private function getIsOnline() { | |
| $n = new \DateTime(); | |
| $online = true; | |
| if ($n < $this->dateOnline) { | |
| $online = false; | |
| } else { | |
| if ($this->dateOffline) { | |
| if ($n > $this->dateOffline) { | |
| $online = false; | |
| } | |
| } | |
| } | |
| return $online; | |
| } | |
| /** | |
| * Set the setting to indicate if a page can be staged. | |
| * | |
| * @param boolean $hasStaging Setting to indicate if a page can be staged. | |
| */ | |
| private function setHasStaging($hasStaging) { | |
| \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
| array(\Scrivo\ArgumentCheck::TYPE_BOOLEAN) | |
| )); | |
| $this->hasStaging = $hasStaging; | |
| } | |
| /** | |
| * Set the id of the parent page. | |
| * | |
| * @param int $parentId The id of the parent page. | |
| */ | |
| private function setParentPageId($parentId) { | |
| \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
| array(\Scrivo\ArgumentCheck::TYPE_INTEGER) | |
| )); | |
| $this->parentId = $parentId; | |
| } | |
| /** | |
| * Set the page type: one out of the Page::TYPE_* constant values. | |
| * | |
| * @param int $type The page type: one out of the Page::TYPE_* constant | |
| * values. | |
| */ | |
| private function setType($type) { | |
| \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
| array(\Scrivo\ArgumentCheck::TYPE_INTEGER, array( | |
| self::TYPE_NAVIGATION_ITEM, self::TYPE_NAVIGABLE_PAGE, | |
| self::TYPE_NON_NAVIGABLE_PAGE, self::TYPE_SUB_FOLDER, | |
| self::TYPE_APPLICATION)) | |
| )); | |
| $this->type = $type; | |
| } | |
| /** | |
| * Set the id of the page template. | |
| * | |
| * @param int $definitionId The id ot the page template. | |
| */ | |
| private function setDefinitionId($definitionId) { | |
| \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
| array(\Scrivo\ArgumentCheck::TYPE_INTEGER) | |
| )); | |
| if (!$this->definitionId) { | |
| $this->definitionId = $definitionId; | |
| } else { | |
| throw new \Scrivo\SystemException("Can't reset the page template"); | |
| } | |
| } | |
| /** | |
| * Set the id the main language for the page (<html lang>). | |
| * | |
| * @param int $languageId The id the main language for the page | |
| * (<html lang>). | |
| */ | |
| private function setLanguageId($languageId) { | |
| \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
| array(\Scrivo\ArgumentCheck::TYPE_INTEGER) | |
| )); | |
| $this->languageId = $languageId; | |
| } | |
| /** | |
| * Set The page title (<title>). | |
| * | |
| * @param \Scrivo\String $title The page title (<title>). | |
| */ | |
| private function setTitle(\Scrivo\String $title) { | |
| $this->title = $title; | |
| } | |
| /** | |
| * Set the page description (<description>). | |
| * | |
| * @param \Scrivo\String $description The page description | |
| * (<description>). | |
| */ | |
| private function setDescription(\Scrivo\String $description) { | |
| $this->description = $description; | |
| } | |
| /** | |
| * Set the keywords for this page (<keywords>). | |
| * | |
| * @param \Scrivo\String $keywords The keywords for this page | |
| * (<keywords>). | |
| */ | |
| private function setKeywords(\Scrivo\String $keywords) { | |
| $this->keywords = $keywords; | |
| } | |
| /** | |
| * Set a javascript script for this page (<script>). | |
| * | |
| * @param \Scrivo\String $javascript A javascript script for this | |
| * page (<script>). | |
| */ | |
| private function setJavascript(\Scrivo\String $javascript) { | |
| $this->javascript = $javascript; | |
| } | |
| /** | |
| * Set additional CSS syle rules for this page (<stylesheet>). | |
| * | |
| * @param \Scrivo\String $stylesheet Additional CSS syle rules for this | |
| * page (<stylesheet>). | |
| */ | |
| private function setStylesheet(\Scrivo\String $stylesheet) { | |
| $this->stylesheet = $stylesheet; | |
| } | |
| /** | |
| * Set the date/time this page needs to go online. | |
| * | |
| * @param \DateTime $dateOnline The date/time this page needs to go online. | |
| */ | |
| private function setDateOnline(\DateTime $dateOnline) { | |
| $this->dateOnline = $dateOnline; | |
| } | |
| /** | |
| * Set the date/time this page need to go offline. | |
| * | |
| * @param \DateTime $dateOffline The date/time this page need to go offline. | |
| */ | |
| private function setDateOffline(\DateTime $dateOffline=null) { | |
| $this->dateOffline = $dateOffline; | |
| } | |
| /** | |
| * Set the page context. | |
| * | |
| * @param \Scrivo\Context $context A Scrivo context. | |
| */ | |
| private function setContext(\Scrivo\Context $context) { | |
| $this->context = $context; | |
| } | |
| /** | |
| * Select the page properties from the database. | |
| * | |
| * @param \Scrivo\Context $context A valid Scrivo context. | |
| * @param array $pages the set of pages for which to retrieve the | |
| * properties. | |
| */ | |
| private static function selectProperties($context, array $pages) { | |
| $ids = implode(",", array_keys($pages)); | |
| $sth = $context->connection->prepare( | |
| "SELECT P.page_id PAGE_ID, T.type, T.php_key, | |
| IFNULL(D.value, '') value, '' VALUE2, | |
| T.page_property_definition_id ID_DEF | |
| FROM page P, page_property_definition T | |
| LEFT JOIN page_property D ON ( | |
| D.instance_id = :instId AND T.instance_id = :instId | |
| AND T.page_property_definition_id = D.page_property_definition_id | |
| AND D.page_id in ($ids) AND D.version = 0) | |
| WHERE T.instance_id = :instId AND P.instance_id = :instId AND | |
| P.page_definition_id = T.page_definition_id AND P.page_id in ($ids) | |
| AND P.version = 0 | |
| UNION | |
| SELECT P.page_id PAGE_ID, 'html_text_tab' type, | |
| T.php_key, IFNULL(D.html, '') value, | |
| IFNULL(D.raw_html, '') VALUE2, | |
| T.page_definition_tab_id ID_DEF | |
| FROM page P, page_definition_tab T | |
| LEFT JOIN page_property_html D ON ( | |
| D.instance_id = :instId AND T.instance_id = :instId | |
| AND T.page_definition_tab_id = D.page_definition_tab_id | |
| AND D.page_id in ($ids) AND D.version = 0) | |
| WHERE T.instance_id = :instId AND P.instance_id = :instId AND | |
| P.page_definition_id = T.page_definition_id AND P.page_id in ($ids) | |
| AND P.version = 0 AND T.application_definition_id = 0 | |
| UNION | |
| SELECT D.page_id PAGE_ID, 'application_tab' type, | |
| T.php_key, A.type value, A.application_definition_id VALUE2, | |
| T.page_definition_tab_id ID_DEF | |
| FROM page D, page_definition_tab T, application_definition A | |
| WHERE D.instance_id = :instId AND T.instance_id = :instId | |
| AND A.instance_id = :instId | |
| AND T.page_definition_id = D.page_definition_id | |
| AND A.application_definition_id = T.application_definition_id | |
| AND T.application_definition_id <> 0 | |
| AND D.page_id in ($ids) AND D.version = 0"); | |
| $context->connection->bindInstance($sth); | |
| $sth->execute(); | |
| foreach (array_keys($pages) as $id) { | |
| $pages[$id]->properties = new \Scrivo\PropertySet(); | |
| } | |
| while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { | |
| $pageId = intval($rd["PAGE_ID"]); | |
| $li = PageProperty::create($pages[$pageId], $rd); | |
| if (!$li->phpSelector->equals(new \Scrivo\String(""))) { | |
| $pages[$pageId]->properties->{$li->phpSelector} = $li; | |
| } | |
| } | |
| } | |
| /** | |
| * Select the roles for this page. | |
| * | |
| * @param \Scrivo\Context $context A valid Scrivo context. | |
| * @param array $pages the set of pages for which to retrieve the | |
| * properties. | |
| */ | |
| private static function selectRoles($context, array $pages) { | |
| $ids = implode(",", array_keys($pages)); | |
| $sth = $context->connection->prepare( | |
| "SELECT page_id, role_id FROM object_role | |
| WHERE instance_id = :instId AND page_id in ($ids)"); | |
| $context->connection->bindInstance($sth); | |
| $sth->execute(); | |
| while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { | |
| $pages[intval($rd["page_id"])]->roles[] = | |
| intval($rd["role_id"]); | |
| } | |
| } | |
| /** | |
| * Check if the page data can be inserted into the database. | |
| * | |
| * @throws \Scrivo\ApplicationException If the data is not accessible, | |
| * one or more of the fields contain invalid data or some other business | |
| * rule is not met. | |
| */ | |
| private function validateInsert() { | |
| if ($this->parentId) { | |
| // If there is parent page copy relevant properties for the parent | |
| // page. | |
| $parent = \Scrivo\Page::fetch($this->context, $this->parentId); | |
| $this->context->checkPermission( | |
| \Scrivo\AccessController::WRITE_ACCESS, $this->parentId); | |
| if ($this->languageId === 0) { | |
| $this->languageId = $parent->languageId; | |
| } | |
| $this->hasStaging == $parent->hasStaging; | |
| } else { | |
| // If we're trying to insert a new root, check if there there is | |
| // none yet. | |
| $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS); | |
| $sth = $this->context->connection->prepare( | |
| "SELECT COUNT(*) FROM page | |
| WHERE instance_id = :instId AND parent_id = 0"); | |
| $this->context->connection->bindInstance($sth); | |
| $sth->execute(); | |
| if ($sth->fetchColumn(0) > 0) { | |
| throw new \Scrivo\SystemException( | |
| "Trying to create a new root page"); | |
| } | |
| } | |
| } | |
| /** | |
| * Insert a new page into the database. | |
| * | |
| * First the data fields of this page will be validated. If no id | |
| * is set a new object id is generated. Then the data is inserted into to | |
| * database. | |
| * | |
| * @throws \Scrivo\ApplicationException If one or more of the fields | |
| * contain invalid data. | |
| */ | |
| public function insert() { | |
| try { | |
| $this->validateInsert(); | |
| if (!$this->id) { | |
| $this->id = $this->context->connection->generateId(); | |
| } | |
| $sth = $this->context->connection->prepare( | |
| "INSERT INTO page ( | |
| instance_id, page_id, version, has_staging, parent_id, | |
| sequence_no, type, page_definition_id, language_id, title, | |
| description, keywords, javascript, stylesheet, | |
| date_created, date_modified, date_online, date_offline | |
| ) VALUES ( | |
| :instId, :id, :version, :hasStaging, :parentId, | |
| 0, :type, :definitionId, :languageId, :title, | |
| :description, :keywords, :javascript, :stylesheet, | |
| now(), now(), :dateOnline, :dateOffline | |
| )"); | |
| $this->context->connection->bindInstance($sth); | |
| $sth->bindValue(":id", $this->id, \PDO::PARAM_INT); | |
| $sth->bindValue(":version", $this->version, \PDO::PARAM_INT); | |
| $sth->bindValue(":hasStaging", $this->hasStaging, \PDO::PARAM_INT); | |
| $sth->bindValue( | |
| ":parentId", $this->parentId, \PDO::PARAM_INT); | |
| $sth->bindValue(":type", $this->type, \PDO::PARAM_INT); | |
| $sth->bindValue( | |
| ":definitionId", $this->definitionId, \PDO::PARAM_INT); | |
| $sth->bindValue(":languageId", $this->languageId, \PDO::PARAM_INT); | |
| $sth->bindValue(":title", $this->title, \PDO::PARAM_STR); | |
| $sth->bindValue( | |
| ":description", $this->description, \PDO::PARAM_STR); | |
| $sth->bindValue(":keywords", $this->keywords, \PDO::PARAM_STR); | |
| $sth->bindValue(":javascript", $this->javascript, \PDO::PARAM_STR); | |
| $sth->bindValue(":stylesheet", $this->stylesheet, \PDO::PARAM_STR); | |
| $sth->bindValue(":dateOnline", | |
| $this->dateOnline->format("Y-m-d H:i:s"), \PDO::PARAM_STR); | |
| $sth->bindValue(":dateOffline", $this->dateOffline | |
| ? $this->dateOffline->format("Y-m-d H:i:s") | |
| : null, \PDO::PARAM_STR); | |
| $sth->execute(); | |
| if ($this->type != \Scrivo\Page::TYPE_SUB_FOLDER) { | |
| \Scrivo\SequenceNo::position($this->context, "page", | |
| "parent_id", $this->id, \Scrivo\SequenceNo::MOVE_LAST); | |
| } | |
| ObjectRole::set($this->context, $this->id, | |
| ObjectRole::select($this->context, $this->parentId)); | |
| // TODO ************** | |
| // $this->_commit_subfolder(); | |
| // $this->set_pretty_path(); | |
| unset($this->context->cache[$this->parentId]); | |
| } catch(\PDOException $e) { | |
| throw new \Scrivo\ResourceException($e); | |
| } | |
| } | |
| /** | |
| * Check if the page data can be updated in the database. | |
| * | |
| * @throws \Scrivo\ApplicationException If the data is not accessible, | |
| * one or more of the fields contain invalid data or some other business | |
| * rule is not met. | |
| */ | |
| private function validateUpdate() { | |
| $this->context->checkPermission( | |
| \Scrivo\AccessController::WRITE_ACCESS, $this->id); | |
| try { | |
| $newPath = self::selectPath($this); | |
| } catch (\Scrivo\SystemException $e) { | |
| throw new \Scrivo\ApplicationException( | |
| "Can't move a page underneath itself"); | |
| } | |
| } | |
| /** | |
| * Update an existing page in the database. | |
| * | |
| * First the data fields of this user will be validated, then the data | |
| * is updated in to database. | |
| * | |
| * @throws \Scrivo\ApplicationException If one or more of the fields | |
| * contain invalid data. | |
| */ | |
| public function update() { | |
| try { | |
| $this->validateUpdate(); | |
| $isParentWritable = false; | |
| if ($this->parentId) { | |
| try { | |
| $this->context->checkPermission( | |
| \Scrivo\AccessController::WRITE_ACCESS, | |
| $this->parentId); | |
| $isParentWritable = true; | |
| } catch (\Scrivo\ApplicationException $e) {} | |
| } | |
| $sth = $this->context->connection->prepare( | |
| "UPDATE page SET | |
| version = :version, has_staging = :hasStaging, | |
| parent_id = :parentId, | |
| type = :type, page_definition_id = :definitionId, | |
| language_id = :languageId, title = :title, | |
| description = :description, keywords = :keywords, | |
| javascript = :javascript, stylesheet = :stylesheet, | |
| date_online = :dateOnline, date_offline = :dateOffline | |
| WHERE instance_id = :instId AND page_id = :id"); | |
| $this->context->connection->bindInstance($sth); | |
| $sth->bindValue(":id", $this->id, \PDO::PARAM_INT); | |
| $sth->bindValue(":version", $this->version, \PDO::PARAM_INT); | |
| $sth->bindValue(":hasStaging", $this->hasStaging, \PDO::PARAM_INT); | |
| $sth->bindValue( | |
| ":parentId", $this->parentId, \PDO::PARAM_INT); | |
| $sth->bindValue(":type", $this->type, \PDO::PARAM_INT); | |
| $sth->bindValue( | |
| ":definitionId", $this->definitionId, \PDO::PARAM_INT); | |
| $sth->bindValue(":languageId", $this->languageId, \PDO::PARAM_INT); | |
| $sth->bindValue(":title", $this->title, \PDO::PARAM_STR); | |
| $sth->bindValue( | |
| ":description", $this->description, \PDO::PARAM_STR); | |
| $sth->bindValue(":keywords", $this->keywords, \PDO::PARAM_STR); | |
| $sth->bindValue(":javascript", $this->javascript, \PDO::PARAM_STR); | |
| $sth->bindValue(":stylesheet", $this->stylesheet, \PDO::PARAM_STR); | |
| $sth->bindValue(":dateOnline", | |
| $this->dateOnline->format("Y-m-d H:i:s"), \PDO::PARAM_STR); | |
| $sth->bindValue(":dateOffline", $this->dateOffline | |
| ? $this->dateOffline->format("Y-m-d H:i:s") | |
| : null, \PDO::PARAM_STR); | |
| $sth->execute(); | |
| self::touch($this->context, $this->id); | |
| if ($this->type == \Scrivo\Page::TYPE_SUB_FOLDER) { | |
| \Scrivo\SequenceNo::position($this->context, "page", | |
| "parent_id", $this->id, 0); | |
| } | |
| // TODO ************** | |
| // $this->_commit_subfolder(); | |
| // $this->set_pretty_path(); | |
| unset($this->context->cache[$this->id]); | |
| unset($this->context->cache[$this->parentId]); | |
| } catch(\PDOException $e) { | |
| throw new \Scrivo\ResourceException($e); | |
| } | |
| } | |
| /** | |
| * Check if deletion of page object data does not violate any | |
| * business rules. | |
| * | |
| * @param \Scrivo\Context $context A Scrivo context. | |
| * @param int $id The object id of the page definition to select. | |
| * | |
| * @throws \Scrivo\ApplicationException If the data is not accessible or | |
| * if it is not possible to delete the language data. | |
| */ | |
| private static function validateDelete(\Scrivo\Context $context, $id) { | |
| $context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS, $id); | |
| // Is it a labeled page? | |
| $sth = $context->connection->prepare( | |
| "SELECT COUNT(*) FROM id_label | |
| WHERE instance_id = :instId AND id = :id"); | |
| $context->connection->bindInstance($sth); | |
| $sth->bindValue(":id", $id, \PDO::PARAM_INT); | |
| $sth->execute(); | |
| if ($sth->fetchColumn(0) > 0) { | |
| throw new \Scrivo\ApplicationException( | |
| "Trying to delete a labelled page"); | |
| } | |
| // Check the child pages. | |
| $sth = $context->connection->prepare( | |
| "SELECT page_id, type FROM page WHERE instance_id = :instId | |
| AND parent_id = :id AND (has_staging+version) = 0"); | |
| $context->connection->bindInstance($sth); | |
| $sth->bindValue(":id", $id, \PDO::PARAM_INT); | |
| $sth->execute(); | |
| $folders = array(); | |
| while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { | |
| if ($rd["type"] == \Scrivo\Page::TYPE_SUB_FOLDER) { | |
| // Try to delete it: will generate an exception if not empty. | |
| \Scrivo\Page::delete($context, intval($rd["page_id"])); | |
| } else { | |
| // Throw up on first 'normal' child page found. | |
| throw new \Scrivo\ApplicationException( | |
| "Trying to delete a page with child pages"); | |
| } | |
| } | |
| } | |
| /** | |
| * Touch (update modification time) a page. | |
| * | |
| * @param \Scrivo\Context $context A Scrivo context. | |
| * @param int $id The id of the page to touch. | |
| */ | |
| public static function touch(\Scrivo\Context $context, $id) { | |
| \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
| null, | |
| array(\Scrivo\ArgumentCheck::TYPE_INTEGER) | |
| )); | |
| try { | |
| $sth = $context->connection->prepare( | |
| "UPDATE page SET date_modified = NOW() | |
| WHERE instance_id = :instId AND page_id = :id"); | |
| $context->connection->bindInstance($sth); | |
| $sth->bindValue(":id", $id, \PDO::PARAM_INT); | |
| $sth->execute(); | |
| unset($context->cache[$id]); | |
| } catch(\PDOException $e) { | |
| throw new \Scrivo\ResourceException($e); | |
| } | |
| } | |
| /** | |
| * Delete an existing page from the database. | |
| * | |
| * First it is is checked if it's possible to delete this page | |
| * then the page data including its dependecies is deleted from | |
| * the database. | |
| * | |
| * @param \Scrivo\Context $context A Scrivo context. | |
| * @param int $id The id of the page to delete. | |
| * | |
| * @throws \Scrivo\ApplicationException If it is not possible to delete | |
| * this page. | |
| */ | |
| public static function delete(\Scrivo\Context $context, $id) { | |
| \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
| null, | |
| array(\Scrivo\ArgumentCheck::TYPE_INTEGER) | |
| )); | |
| try { | |
| self::validateDelete($context, $id); | |
| $p = \Scrivo\Page::fetch($context, $id); | |
| foreach (array("object_role" => "page_id", | |
| "page_property" => "page_id", | |
| "page_property_html" => "page_id", | |
| "item_list" => "page_id", | |
| "list_item" => "page_id", | |
| "list_item_property" => "page_id", | |
| "id_label" => "id", | |
| "page" => "page_id") as $table => $keyFld) { | |
| $sth = $context->connection->prepare( | |
| "DELETE FROM $table | |
| WHERE instance_id = :instId AND $keyFld = :id"); | |
| $context->connection->bindInstance($sth); | |
| $sth->bindValue(":id", $id, \PDO::PARAM_INT); | |
| $sth->execute(); | |
| } | |
| unset($context->cache[$id]); | |
| unset($context->cache[$p->parentId]); | |
| } catch(\PDOException $e) { | |
| throw new \Scrivo\ResourceException($e); | |
| } | |
| } | |
| /** | |
| * Move a page one position up or down amongst its siblings. | |
| * | |
| * @param int $dir Direction of the move, see \Scrivo\SequenceNo:::MOVE_* | |
| */ | |
| function move($dir=\Scrivo\SequenceNo::MOVE_DOWN) { | |
| if ($this->type == \Scrivo\Page::TYPE_SUB_FOLDER) { | |
| throw new \Scrivo\SystemException("Can't move subfolders"); | |
| } | |
| $this->context->checkPermission( | |
| \Scrivo\AccessController::WRITE_ACCESS, $this->id); | |
| \Scrivo\SequenceNo::position($this->context, "page", | |
| "parent_id", $this->id, $dir); | |
| unset($this->context->cache[$this->parentId]); | |
| } | |
| /** | |
| * Retrieve a page from the database or cache. | |
| * | |
| * @param \Scrivo\Context $context A Scrivo context. | |
| * @param int $id An object id of a page. | |
| * | |
| * @throws \Scrivo\ApplicationException if the page was not readable for | |
| * the user defined in the context. | |
| */ | |
| public static function fetch(\Scrivo\Context $context, $id=null) { | |
| \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
| null, | |
| array(\Scrivo\ArgumentCheck::TYPE_INTEGER) | |
| ), 1); | |
| try { | |
| // Try to retieve form cache | |
| $p = null; | |
| if (isset($context->cache[$id])) { | |
| // Set the page from cache and set the context. | |
| $p = $context->cache[$id]; | |
| $p->context = $context; | |
| } else { | |
| $sth = $context->connection->prepare( | |
| "SELECT page_id, version, has_staging, | |
| parent_id, sequence_no, type, | |
| page_definition_id, language_id, title, description, keywords, | |
| javascript, stylesheet, date_created, date_modified, date_online, | |
| date_offline | |
| FROM page | |
| WHERE instance_id = :instId AND page_id = :id"); | |
| $context->connection->bindInstance($sth); | |
| $sth->bindValue(":id", $id, \PDO::PARAM_INT); | |
| $sth->execute(); | |
| $rd = $sth->fetch(\PDO::FETCH_ASSOC); | |
| if ($sth->rowCount() != 1) { | |
| throw new \Scrivo\SystemException("Failed to load page"); | |
| } | |
| $p = new \Scrivo\Page(); | |
| $p->setFields($context, $rd); | |
| self::selectProperties($p->context, array($p->id => $p)); | |
| $p->roles = new \Scrivo\RoleSet(); | |
| self::selectRoles($p->context, array($p->id => $p)); | |
| $context->cache[$id] = $p; | |
| } | |
| $p->roles->checkReadPermission($context->principal); | |
| return $p; | |
| } catch(\PDOException $e) { | |
| throw new \Scrivo\ResourceException($e); | |
| } | |
| } | |
| /** | |
| * Select child pages from the database. | |
| * | |
| * @param \Scrivo\Page $page A Scrivo page. | |
| * | |
| * @return \Scrivo\PageSet An array containing the selected pages. | |
| */ | |
| private static function selectChildren(\Scrivo\Page $page) { | |
| try { | |
| $sth = $page->context->connection->prepare( | |
| "SELECT D.page_id, D.version, D.has_staging, D.parent_id, | |
| D.sequence_no, D.type, D.page_definition_id, D.language_id, | |
| D.title, D.description, D.keywords, D.javascript, | |
| D.stylesheet, D.date_created, D.date_modified, D.date_online, | |
| D.date_offline, R.role_id | |
| FROM page D LEFT JOIN object_role R ON | |
| (D.instance_id = R.instance_id AND D.page_id = R.page_id) | |
| WHERE D.instance_id = :instId | |
| AND D.parent_id = :parentId | |
| ORDER BY sequence_no"); | |
| $page->context->connection->bindInstance($sth); | |
| $sth->bindValue(":parentId", $page->id, \PDO::PARAM_INT); | |
| $sth->execute(); | |
| $res = new \Scrivo\PageSet($page); | |
| $p = null; | |
| $lid = 0; | |
| $id = 0; | |
| while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { | |
| $id = intval($rd["page_id"]); | |
| if ($lid != $id) { | |
| if ($lid !== 0) { | |
| $page->context->cache[$lid] = $p; | |
| $res[$lid] = $p; | |
| } | |
| $lid = $id; | |
| $p = new \Scrivo\Page(); | |
| $p->setFields($page->context, $rd); | |
| $p->roles = new \Scrivo\RoleSet(); | |
| } | |
| // Add the roles to the role set | |
| $p->roles[] = intval($rd["role_id"]); | |
| } | |
| if ($id) { | |
| $page->context->cache[$id] = $p; | |
| $res[$id] = $p; | |
| } | |
| return $res; | |
| } catch(\PDOException $e) { | |
| throw new \Scrivo\ResourceException($e); | |
| } | |
| } | |
| /** | |
| * Select the page path. | |
| * | |
| * @param \Scrivo\Page $page A Scrivo page. | |
| * | |
| * @return \Scrivo\PageSet An array containing the selected pages. | |
| */ | |
| private static function selectPath(\Scrivo\Page $page) { | |
| try { | |
| $res = new \Scrivo\PageSet($page); | |
| $res->prepend($page); | |
| $target = $page->parentId; | |
| $i = 0; | |
| while ($target) { | |
| if ($target == $page->id) { | |
| throw new \Scrivo\SystemException("Path loop"); | |
| } | |
| if (isset($page->context->cache[$target])) { | |
| $p = $page->context->cache[$target]; | |
| } else { | |
| $sth = $page->context->connection->prepare( | |
| "SELECT D.page_id, D.version, D.has_staging, | |
| D.parent_id, D.sequence_no, D.type, | |
| D.page_definition_id, D.language_id, | |
| D.title, D.description, D.keywords, D.javascript, | |
| D.stylesheet, D.date_created, D.date_modified, | |
| D.date_online, D.date_offline, R.role_id | |
| FROM page D LEFT JOIN object_role R ON | |
| (D.instance_id = R.instance_id AND | |
| D.page_id = R.page_id) | |
| WHERE D.instance_id = :instId AND | |
| D.page_id = :parentId AND | |
| (D.has_staging+D.version) = 0"); | |
| $page->context->connection->bindInstance($sth); | |
| $sth->bindValue(":parentId", $target, \PDO::PARAM_INT); | |
| $sth->execute(); | |
| $p = null; | |
| while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { | |
| if (!$p) { | |
| $p = new \Scrivo\Page(); | |
| $p->setFields($page->context, $rd); | |
| $p->roles = new \Scrivo\RoleSet(); | |
| $target = intval($rd["parent_id"]); | |
| } | |
| // Add the roles to the role set | |
| $p->roles[] = intval($rd["role_id"]); | |
| } | |
| if ($p) { | |
| $page->context->cache[$p->id] = $p; | |
| } else { | |
| throw new \Scrivo\SystemException( | |
| "Failed to load page"); | |
| } | |
| } | |
| $res->prepend($p); | |
| $target = $p->parentId; | |
| } | |
| return $res; | |
| } catch(\PDOException $e) { | |
| throw new \Scrivo\ResourceException($e); | |
| } | |
| } | |
| } | |