Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
84.21% |
16 / 19 |
CRAP | |
96.17% |
301 / 313 |
ItemList | |
0.00% |
0 / 1 |
|
84.21% |
16 / 19 |
52 | |
96.17% |
301 / 313 |
__construct( \Scrivo\Context $context, $pageId, $pagePropertyDefinitionId) | |
100.00% |
1 / 1 |
5 | |
100.00% |
36 / 36 |
|||
__get($name) | |
100.00% |
1 / 1 |
2 | |
100.00% |
2 / 2 |
|||
insert() | |
100.00% |
1 / 1 |
1 | |
100.00% |
11 / 11 |
|||
update() | |
100.00% |
1 / 1 |
1 | |
100.00% |
7 / 7 |
|||
fetch(\Scrivo\Context $context, $pageId, $defintionId) | |
100.00% |
1 / 1 |
2 | |
100.00% |
15 / 15 |
|||
getItems($parentId) | |
100.00% |
1 / 1 |
1 | |
100.00% |
6 / 6 |
|||
select($parentId=0) | |
100.00% |
1 / 1 |
7 | |
100.00% |
31 / 31 |
|||
selectProperties(\Scrivo\Context $context, $listId) | |
100.00% |
1 / 1 |
5 | |
100.00% |
22 / 22 |
|||
createLinkedPage( \Scrivo\ListItem $item, \Scrivo\ListItemDefinition $def) | |
100.00% |
1 / 1 |
2 | |
100.00% |
21 / 21 |
|||
getDefinitionId(\Scrivo\String $phpSelector) | |
100.00% |
1 / 1 |
1 | |
100.00% |
8 / 8 |
|||
selectEmptyProperties($definitionId) | |
100.00% |
1 / 1 |
4 | |
100.00% |
14 / 14 |
|||
updateProperty(\Scrivo\ListItemProperty $prp, $itemId) | |
100.00% |
1 / 1 |
1 | |
100.00% |
15 / 15 |
|||
insertItem(\Scrivo\ListItem $item) | |
100.00% |
1 / 1 |
4 | |
100.00% |
32 / 32 |
|||
updateItem(\Scrivo\ListItem $item) | |
0.00% |
0 / 1 |
5 | |
95.83% |
23 / 24 |
|||
newItem(\Scrivo\String $phpSelector) | |
100.00% |
1 / 1 |
2 | |
100.00% |
20 / 20 |
|||
saveItem(\Scrivo\ListItem $item) | |
0.00% |
0 / 1 |
3.01 | |
90.91% |
10 / 11 |
|||
deleteItem($id) | |
100.00% |
1 / 1 |
2 | |
100.00% |
19 / 19 |
|||
moveItem($id, $dir=\Scrivo\SequenceNo::MOVE_DOWN) | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 10 |
|||
removeFromCache() | |
100.00% |
1 / 1 |
3 | |
100.00% |
9 / 9 |
<?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: ItemList.php 866 2013-08-25 16:22:35Z geert $ | |
*/ | |
/** | |
* Implementation of the \Scrivo\ItemList class. | |
*/ | |
namespace Scrivo; | |
/** | |
* Item lists (or Scrivo list) are a very versitle way of adding list like | |
* data to a page (faq, comments, news and even a forurm like) | |
*/ | |
class ItemList { | |
/** | |
* The list/application id (DB key). | |
* @var int | |
*/ | |
private $id = 0; | |
/** | |
* Id of the list definition. | |
* @var int | |
*/ | |
private $pagePropertyDefinitionId = 0; | |
/** | |
* Id of the application definition. | |
* @var int | |
*/ | |
private $applicationDefinitionId = 0; | |
/** | |
* Id of the page where this list instance is associated with. | |
* @var int | |
*/ | |
private $pageId = 0; | |
/** | |
* Optional reference to a page that is parent for pages linked to | |
* list items. | |
* @var int | |
*/ | |
private $folderId = 0; | |
/** | |
* A list of list item pids. | |
* @var array[] | |
*/ | |
private $listPids = null; | |
/** | |
* The attached roles. | |
* @var \Scrivo\RoleSet | |
*/ | |
private $roles; | |
/** | |
* A Scrivo context. | |
* @var \Scrivo\Context | |
*/ | |
private $context = null; | |
/** | |
* Construct an item list. Item lists are Scrivo application and therefore | |
* linked to a page and an application definition. | |
* | |
* Scrivo lists are never created as explicitly, but assumed to exist if | |
* a page with a list type application definition does exist. If not the | |
* list is created on the fly based upon its defintion. Because actual | |
* list creation is an internal issue and not ment to do expicitly the | |
* constructor is not public. | |
* | |
* To create a list see 'fetch'. | |
* | |
* @param \Scrivo\Context $context A valid Scrivo context | |
* @param string $pageId The id of the page that hosts the application. | |
* @param string $pagePropertyDefinitionId The page property definition id. | |
*/ | |
protected function __construct( | |
\Scrivo\Context $context, $pageId, $pagePropertyDefinitionId) { | |
try { | |
$this->context = $context; | |
// Check if the list was create before (the list record exists). | |
$sth = $context->connection->prepare( | |
"SELECT L.item_list_id, L.page_definition_tab_id, L.page_id, | |
L.folder_id, T.application_definition_id | |
FROM item_list L, page_definition_tab T, page D | |
WHERE L.instance_id = :instId AND D.instance_id = :instId AND | |
T.instance_id = :instId AND D.page_definition_id = T.page_definition_id AND | |
T.page_definition_tab_id = L.page_definition_tab_id AND | |
L.version = D.version AND L.page_id = D.page_id AND | |
(D.has_staging + D.version) = 0 AND | |
L.page_definition_tab_id = :ppDefId AND | |
L.page_id = :pageId"); | |
$context->connection->bindInstance($sth); | |
$sth->bindValue(":pageId", $pageId, \PDO::PARAM_INT); | |
$sth->bindValue( | |
":ppDefId", $pagePropertyDefinitionId, \PDO::PARAM_INT); | |
$sth->execute(); | |
if ($sth->rowCount() > 1) { | |
throw new \Scrivo\SystemException( | |
"Data corruption: failed to load list"); | |
} else if ($sth->rowCount() === 0) { | |
// If not create it | |
// Is it a valid page and application definition | |
// Yes create the list | |
// else throw up | |
$this->pageId = $pageId; | |
$this->pagePropertyDefinitionId = $pagePropertyDefinitionId; | |
$this->insert(); | |
} else { | |
$rd = $sth->fetch(\PDO::FETCH_ASSOC); | |
$this->id = intval($rd["item_list_id"]); | |
$this->pagePropertyDefinitionId = | |
intval($rd["page_definition_tab_id"]); | |
$this->pageId = intval($rd["page_id"]); | |
$this->folderId = intval($rd["folder_id"]); | |
$this->applicationDefinitionId = intval($rd["application_definition_id"]); | |
} | |
// Select it | |
// TODO: when the list definition chances and a sub-folder is | |
// required mark this in the list item definition (HAS_FOLDER or | |
// something like that). Then is it is easliy decided if the sub | |
// folder needs to be created at this point. | |
// Or delegate it to list item creation. | |
// "Borrow" the read access roles form the host page. | |
$this->roles = new \Scrivo\RoleSet(); | |
$sth = $context->connection->prepare( | |
"SELECT role_id FROM object_role | |
WHERE instance_id = :instId AND page_id = :pageId"); | |
$context->connection->bindInstance($sth); | |
$sth->bindValue(":pageId", $pageId, \PDO::PARAM_INT); | |
$sth->execute(); | |
while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { | |
$this->roles[] = intval($rd["role_id"]); | |
} | |
$this->listPids = array(); | |
} catch(\PDOException $e) { | |
throw new \Scrivo\ResourceException($e); | |
} | |
} | |
/** | |
* 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 "items": return $this->getItems(0); | |
} | |
throw new \Scrivo\SystemException("No such get-property '$name'."); | |
} | |
/** | |
* Insert new list object data into the database. A list record is assumed | |
* to exists if page exists and is created silently. | |
* | |
* @throws \Scrivo\ApplicationException If the data is not accessible or | |
* one or more of the fields contain invalid data. | |
*/ | |
private function insert() { | |
$this->id = $this->context->connection->generateId(); | |
$sth = $this->context->connection->prepare( | |
"INSERT INTO item_list ( | |
instance_id, item_list_id, page_definition_tab_id, page_id, | |
version, folder_id | |
) VALUES ( | |
:instId, :id, :pagePropDefId, :pageId, | |
0, :folderId | |
)"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":id", $this->id, \PDO::PARAM_INT); | |
$sth->bindValue( | |
":pagePropDefId", $this->pagePropertyDefinitionId, \PDO::PARAM_INT); | |
$sth->bindValue(":pageId", $this->pageId, \PDO::PARAM_INT); | |
$sth->bindValue(":folderId", $this->folderId, \PDO::PARAM_INT); | |
$sth->execute(); | |
} | |
/** | |
* Update list object data in the database. Only used to set the subfolder | |
* id. | |
* | |
* @throws \Scrivo\ApplicationException If the data is not accessible or | |
* one or more of the fields contain invalid data. | |
*/ | |
private function update() { | |
$sth = $this->context->connection->prepare( | |
"UPDATE item_list SET folder_id = :folderId | |
WHERE instance_id = :instId AND item_list_id = :listId"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":folderId", $this->folderId, \PDO::PARAM_INT); | |
$sth->bindValue(":listId", $this->id, \PDO::PARAM_INT); | |
$sth->execute(); | |
} | |
/** | |
* Retrieve an item list from the cache or database. | |
* | |
* @param \Scrivo\Context $context A Scrivo context. | |
* @param int $pageId The id of the page that hosts the list. | |
* @param int $defintionId The id of the page property definition. | |
* | |
* @throws \Scrivo\ApplicationException if the page was not readable for | |
* the user defined in the context. | |
*/ | |
public static function fetch(\Scrivo\Context $context, $pageId, $defintionId) { | |
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
null, | |
array(\Scrivo\ArgumentCheck::TYPE_INTEGER), | |
array(\Scrivo\ArgumentCheck::TYPE_INTEGER), | |
)); | |
// Try to retieve form cache | |
$obj = null; | |
$cId = "$pageId.$defintionId"; | |
if (isset($context->cache[$cId])) { | |
// Get the list from cache and set the context. | |
$obj = $context->cache[$cId]; | |
$obj->context = $context; | |
} else { | |
// Load the list and set it in the cache. | |
$obj = new \Scrivo\ItemList($context, $pageId, $defintionId); | |
$context->cache[$cId] = $obj; | |
} | |
$obj->roles->checkReadPermission($context->principal); | |
return $obj; | |
} | |
/** | |
* Retrieve all list items at root level. | |
* | |
* @return \Scrivo\ListItem[] An array if list items. | |
public function getItems() { | |
$res = $this->list[0]; | |
return $res ? $res : array(); | |
} | |
*/ | |
/** | |
* Retrieve a sub list. | |
* | |
* @param int $parentId The id of the common parent for the list items. | |
* | |
* @return \Scrivo\ListItem[] An array if list items. | |
*/ | |
public function getItems($parentId) { | |
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
array(\Scrivo\ArgumentCheck::TYPE_INTEGER) | |
)); | |
\Scrivo\ArgumentCheck::assert( | |
$parentId, \Scrivo\ArgumentCheck::TYPE_INTEGER); | |
return $this->select($parentId); | |
} | |
/** | |
* Select list items from the database. | |
* | |
* @param int $parentId An optional parent id is case of a sub-list. | |
* | |
* @return \Scrivo\ListItem[id] An array containing the selected list items. | |
*/ | |
private function select($parentId=0) { | |
$cId = $this->pageId . "." . $this->pagePropertyDefinitionId; | |
if (!isset($this->listPids[$parentId])) { | |
$this->listPids[$parentId] = true; | |
$this->context->cache[$cId] = $this; | |
} | |
if (isset($this->context->cache[$cId . "." . $parentId])) { | |
return $this->context->cache[$cId . "." . $parentId]; | |
} | |
try { | |
$sth = $this->context->connection->prepare( | |
"SELECT I.list_item_id, I.item_list_id, I.link_id, | |
I.version, I.parent_id, I.sequence_no, I.list_item_definition_id, | |
I.page_id, I.title, I.date_created, I.date_modified, I.date_online, | |
I.date_offline | |
FROM list_item I, item_list L | |
WHERE I.instance_id = :instId AND L.instance_id = :instId | |
AND L.item_list_id = I.item_list_id | |
AND I.parent_id = :parentId | |
AND L.page_id = :pageId | |
AND L.page_definition_tab_id = :defId | |
AND L.version = 0 AND I.version = 0 | |
ORDER BY parent_id, sequence_no"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":pageId", $this->pageId, \PDO::PARAM_INT); | |
$sth->bindValue(":parentId", $parentId, \PDO::PARAM_INT); | |
$sth->bindValue( | |
":defId", $this->pagePropertyDefinitionId, \PDO::PARAM_INT); | |
$sth->execute(); | |
$res = array(); | |
$prps = null; | |
while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { | |
// TODO: get this out of the loop, its here because of the | |
// list id | |
if ($prps === null) { | |
$prps = self::selectProperties( | |
$this->context, intval($rd["item_list_id"])); | |
} | |
$id = intval($rd["list_item_id"]); | |
$li = new \Scrivo\ListItem($rd, | |
isset($prps[$id]) ? $prps[$id] : new \Scrivo\PropertySet()); | |
$res[$li->id] = $li; | |
} | |
$this->context->cache[$cId . "." . $parentId] = $res; | |
return $res; | |
} catch(\PDOException $e) { | |
throw new \Scrivo\ResourceException($e); | |
} | |
} | |
/** | |
* Select list item properties from the database. | |
* | |
* @param \Scrivo\Context $context A Scrivo context. | |
* @param int $listId The id of the list for which to retrieve the | |
* properties. | |
* | |
* @return ListItemProperty[type] An array containing the selected list | |
* item properties. | |
*/ | |
private static function selectProperties(\Scrivo\Context $context, | |
$listId) { | |
$sth = $context->connection->prepare( | |
"SELECT I.list_item_id, I.page_id, | |
T.list_item_property_definition_id ID_DEF, T.type, T.php_key, | |
IFNULL(V.value, '') value | |
FROM | |
list_item I | |
JOIN list_item_property_definition T ON ( | |
I.instance_id = :instId AND T.instance_id = :instId | |
AND I.list_item_definition_id = T.list_item_definition_id) | |
LEFT JOIN list_item_property V ON ( | |
V.instance_id = :instId AND I.instance_id = :instId | |
AND T.instance_id = :instId | |
AND V.list_item_property_definition_id = T.list_item_property_definition_id | |
AND V.list_item_id = I.list_item_id AND V.version = 0) | |
WHERE | |
I.instance_id = :instId | |
AND I.item_list_id = :listId AND I.version = 0" | |
// .($itemId ? " AND I.list_item_id = :itemId" : "") | |
); | |
$context->connection->bindInstance($sth); | |
$sth->bindValue(":listId", $listId, \PDO::PARAM_INT); | |
/* | |
if ($itemId) { | |
$sth->bindValue(":itemId", $itemId, \PDO::PARAM_INT); | |
} | |
*/ | |
$sth->execute(); | |
$res = array(); | |
$id = -1; | |
while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { | |
$lid = intval($rd["list_item_id"]); | |
if ($lid != $id) { | |
$id = $lid; | |
$res[$id] = new \Scrivo\PropertySet(); | |
} | |
$li = ListItemProperty::create($rd); | |
if ($li && !$li->phpSelector->equals(new \Scrivo\String(""))) { | |
$res[$id]->{$li->phpSelector} = $li; | |
} | |
} | |
return $res; | |
} | |
/** | |
* Create a linked page for a list item. | |
* | |
* @param \Scrivo\ListItem $item The list item for which to create the | |
* linked page. | |
* @param \Scrivo\ListItemDefinition $def The list item defintion of the | |
* list item for which to create the linked page. | |
* | |
* @return int The page id of the page to link. | |
*/ | |
private function createLinkedPage( | |
\Scrivo\ListItem $item, \Scrivo\ListItemDefinition $def) { | |
// Load the reference page to copy the language and role settings. | |
$mp = \Scrivo\Page::fetch($this->context, $this->pageId); | |
// If no subfolder exists yet create one. | |
if (!$this->folderId) { | |
$propDef = \Scrivo\PagePropertyDefinition::fetch( | |
$this->context, $this->pagePropertyDefinitionId); | |
$tab = \Scrivo\PageDefinitionTab::fetch( | |
$this->context, $propDef->pageDefinitionTabId); | |
$folder = new \Scrivo\Page($this->context); | |
$folder->parentId = $this->pageId; | |
$folder->type = \Scrivo\Page::TYPE_SUB_FOLDER; | |
$folder->title = $tab->title; | |
$folder->insert(); | |
$this->folderId = $folder->id; | |
$this->update(); | |
} | |
// Create the sub-page. | |
$sub = new \Scrivo\Page($this->context); | |
$sub->definitionId = $def->pageDefinitionId; | |
$sub->parentId = $this->folderId; | |
$sub->type = \Scrivo\Page::TYPE_NON_NAVIGABLE_PAGE; | |
$sub->title = $item->title; | |
$sub->insert(); | |
return $sub->id; | |
} | |
/** | |
* Get the list item definition id using the phpSelector of the list | |
* item definition. | |
* | |
* @param \Scrivo\String $phpSelector The phpSelector of a list | |
* item definition. | |
* | |
* @return int The list item definition id. | |
*/ | |
private function getDefinitionId(\Scrivo\String $phpSelector) { | |
$sth = $this->context->connection->prepare( | |
"SELECT T.list_item_definition_id FROM list_item_definition T WHERE | |
T.instance_id = :instId AND T.application_definition_id = :appDefId AND | |
T.php_key = :sel"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue( | |
":appDefId", $this->applicationDefinitionId, \PDO::PARAM_INT); | |
$sth->bindValue(":sel", $phpSelector, \PDO::PARAM_STR); | |
$sth->execute(); | |
return intval($sth->fetchColumn()); | |
} | |
/** | |
* Create a set of blank properties for a given list item definition. | |
* | |
* @param int $definitionId | |
* | |
* @return \Scrivo\PropertySet | |
*/ | |
private function selectEmptyProperties($definitionId) { | |
$sth = $this->context->connection->prepare( | |
"SELECT | |
0 list_item_id, null value, :pageId page_id, | |
list_item_property_definition_id ID_DEF, type, php_key | |
FROM list_item_property_definition | |
WHERE instance_id = :instId AND list_item_definition_id = :sel"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":pageId", $this->pageId, \PDO::PARAM_INT); | |
$sth->bindValue(":sel", $definitionId, \PDO::PARAM_INT); | |
$sth->execute(); | |
$res = new \Scrivo\PropertySet(); | |
while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { | |
$li = ListItemProperty::create($rd); | |
if ($li && !$li->phpSelector->equals(new \Scrivo\String(""))) { | |
$res->{$li->phpSelector} = $li; | |
} | |
} | |
return $res; | |
} | |
/** | |
* Update an existing list item property in the database. | |
* | |
* First the data fields of this user will be validated, then the data | |
* is updated in the database. | |
* | |
* @param \Scrivo\ListItemProperty $prp The list item property to update. | |
* @param int $itemId The id of the list item for which to update the | |
* property. | |
* | |
* @throws \Scrivo\ApplicationException If one or more of the fields | |
* contain invalid data. | |
*/ | |
private function updateProperty(\Scrivo\ListItemProperty $prp, $itemId) { | |
$sth = $this->context->connection->prepare( | |
"DELETE FROM list_item_property WHERE instance_id = :instId AND | |
list_item_id = :listItemId AND list_item_property_definition_id = :idDef AND | |
version = 0"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":listItemId", $itemId, \PDO::PARAM_INT); | |
$sth->bindValue(":idDef", $prp->definitionId, \PDO::PARAM_STR); | |
$sth->execute(); | |
$sth = $this->context->connection->prepare( | |
"INSERT INTO list_item_property ( | |
instance_id, list_item_id, version, list_item_property_definition_id, | |
page_id, value | |
) VALUES (:instId, :listItemId, 0, :idDef, :pageId, :data)"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":listItemId", $itemId, \PDO::PARAM_INT); | |
$sth->bindValue(":idDef", $prp->definitionId, \PDO::PARAM_STR); | |
$sth->bindValue(":pageId", $prp->pageId, \PDO::PARAM_STR); | |
$sth->bindValue(":data", $prp->data, \PDO::PARAM_STR); | |
$sth->execute(); | |
} | |
/** | |
* Insert new list item object data into the database. | |
* | |
* First it is checked if the data of this list item object can be inserted | |
* into the database, then the data is inserted into the database. If no id | |
* was set a new object id is generated. | |
* | |
* @param \Scrivo\ListItem $item The list item to insert into the database. | |
* | |
* @throws \Scrivo\ApplicationException If the data is not accessible or | |
* one or more of the fields contain invalid data. | |
*/ | |
private function insertItem(\Scrivo\ListItem $item) { | |
// Create a sub-page if necessary | |
$def = \Scrivo\ListItemDefinition::fetch( | |
$this->context, $item->definitionId); | |
$linkedPageId = 0; | |
if ($def->pageDefinitionId) { | |
$linkedPageId = $this->createLinkedPage($item, $def); | |
} | |
$id = $this->context->connection->generateId(); | |
$sth = $this->context->connection->prepare( | |
"INSERT INTO list_item ( | |
instance_id, list_item_id, item_list_id, link_id, | |
version, parent_id, sequence_no, list_item_definition_id, | |
page_id, title, date_created, date_modified, | |
date_online, date_offline | |
) VALUES ( | |
:instId, :id, :listId, :pageId, | |
:version, :parentId, :sequenceNo, :definitionId, | |
:linkedPageId, :title, now(), now(), | |
:dateOnline, :dateOffline | |
)"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":id", $id, \PDO::PARAM_INT); | |
$sth->bindValue(":listId", $item->listId, \PDO::PARAM_INT); | |
$sth->bindValue(":pageId", $item->pageId, \PDO::PARAM_INT); | |
$sth->bindValue(":version", $item->version, \PDO::PARAM_INT); | |
$sth->bindValue(":parentId", $item->parentId, \PDO::PARAM_INT); | |
$sth->bindValue(":sequenceNo", 0, \PDO::PARAM_INT); | |
$sth->bindValue(":definitionId", | |
$item->definitionId, \PDO::PARAM_INT); | |
// TODO: no item-> ??? | |
$sth->bindValue(":linkedPageId", $linkedPageId, \PDO::PARAM_INT); | |
$sth->bindValue(":title", $item->title, \PDO::PARAM_STR); | |
$sth->bindValue(":dateOnline", | |
$item->dateOnline->format("Y-m-d H:i:s"), \PDO::PARAM_STR); | |
$sth->bindValue(":dateOffline", $item->dateOffline | |
? $item->dateOffline->format("Y-m-d H:i:s") | |
: null, \PDO::PARAM_STR); | |
$sth->execute(); | |
foreach ($item->properties as $prp) { | |
$this->updateProperty($prp, $id); | |
} | |
\Scrivo\SequenceNo::position($this->context, "list_item", | |
array("parent_id", "item_list_id"), $id, \Scrivo\SequenceNo::MOVE_FIRST); | |
} | |
/** | |
* Update existing list item object data in the database. | |
* | |
* First it is checked if the data of this list item object can be updated | |
* in the database, then the data is updated in the database. | |
* | |
* @param \Scrivo\ListItem $item The list item to update in the database. | |
* | |
* @throws \Scrivo\ApplicationException If the data is not accessible or | |
* one or more of the fields contain invalid data. | |
*/ | |
private function updateItem(\Scrivo\ListItem $item) { | |
// Create a sub-page if necessary | |
$def = \Scrivo\ListItemDefinition::fetch( | |
$this->context, $item->definitionId); | |
$linkedPageId = $item->linkedPageId; | |
if (!$linkedPageId && $def->pageDefinitionId) { | |
$linkedPageId = $this->createLinkedPage($item, $def); | |
} | |
$sth = $this->context->connection->prepare( | |
"UPDATE list_item SET | |
parent_id = :parentId, title = :title, link_id = :linkedPage, | |
date_online = :dateOnline, date_offline = :dateOffline | |
WHERE instance_id = :instId AND list_item_id = :id"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":id", $item->id, \PDO::PARAM_INT); | |
$sth->bindValue(":parentId", $item->parentId, \PDO::PARAM_INT); | |
$sth->bindValue(":linkedPage", $linkedPageId, \PDO::PARAM_INT); | |
$sth->bindValue(":title", $item->title, \PDO::PARAM_STR); | |
$sth->bindValue(":dateOnline", | |
$item->dateOnline->format("Y-m-d H:i:s"), \PDO::PARAM_STR); | |
$sth->bindValue(":dateOffline", $item->dateOffline | |
? $item->dateOffline->format("Y-m-d H:i:s") | |
: null, \PDO::PARAM_STR); | |
$sth->execute(); | |
foreach ($item->properties as $prp) { | |
$this->updateProperty($prp, $item->id); | |
} | |
} | |
/** | |
* Create a new list item to insert in the database. | |
* | |
* @param \Scrivo\String $phpSelector The selector of the list item | |
* definition of the list item to create. | |
* | |
* @return \Scrivo\ListItem | |
*/ | |
public function newItem(\Scrivo\String $phpSelector) { | |
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null)); | |
try { | |
$defId = $this->getDefinitionId($phpSelector); | |
return new \Scrivo\ListItem( | |
array( | |
"list_item_id" => 0, | |
"item_list_id" => $this->id, | |
"page_id" => $this->pageId, | |
"version" => 0, | |
"parent_id" => 0, | |
"sequence_no" => 0, | |
"list_item_definition_id" => $defId, | |
"link_id" => 0, | |
"title" => new \Scrivo\String(""), | |
"date_created" => "now", | |
"date_modified" => "now", | |
"date_online" => "now", | |
"date_offline" => null | |
), | |
self::selectEmptyProperties($defId) | |
); | |
} catch(\PDOException $e) { | |
throw new \Scrivo\ResourceException($e); | |
} | |
} | |
/** | |
* Save list item data to the database. | |
* | |
* @param \Scrivo\ListItem $item The list item to save, either an existing | |
* item updated item or a new one craeted with the newItem method. | |
* | |
* @throws \Scrivo\ApplicationException if the data is not accessible or | |
* it is not possible to insert or update the list item data. | |
*/ | |
public function saveItem(\Scrivo\ListItem $item) { | |
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null)); | |
try { | |
$this->context->checkPermission( | |
\Scrivo\AccessController::WRITE_ACCESS, $this->pageId); | |
if ($item->id === 0) { | |
$this->insertItem($item); | |
} else { | |
$this->updateItem($item); | |
} | |
$this->removeFromCache(); | |
} catch(\PDOException $e) { | |
throw new \Scrivo\ResourceException($e); | |
} | |
} | |
/** | |
* Delete existing list item data from the database. | |
* | |
* First it is is checked if it's possible to delete list item data, | |
* then the list item data including its dependencies is deleted from | |
* the database. | |
* | |
* @param int $id The object id of the list item to delete. | |
* | |
* @throws \Scrivo\ApplicationException If the data is not accessible or | |
* if it is not possible to delete the list item data. | |
*/ | |
public function deleteItem($id) { | |
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
array(\Scrivo\ArgumentCheck::TYPE_INTEGER) | |
)); | |
try { | |
// TODO test delete when there are children | |
$this->context->checkPermission( | |
\Scrivo\AccessController::WRITE_ACCESS, $this->pageId); | |
// TODO: delete sub page | |
$sth = $this->context->connection->prepare( | |
"DELETE FROM list_item | |
WHERE instance_id = :instId AND list_item_id = :id"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":id", $id, \PDO::PARAM_INT); | |
$sth->execute(); | |
$sth = $this->context->connection->prepare( | |
"DELETE FROM list_item_property | |
WHERE instance_id = :instId AND list_item_id = :id"); | |
$this->context->connection->bindInstance($sth); | |
$sth->bindValue(":id", $id, \PDO::PARAM_INT); | |
$sth->execute(); | |
$this->removeFromCache(); | |
} catch(\PDOException $e) { | |
throw new \Scrivo\ResourceException($e); | |
} | |
} | |
/** | |
* Move a list item to another position amongst its siblings. | |
* | |
* @param int $id The object id of the list item to move. | |
* @param int $dir Position or direction of the move, | |
* see \Scrivo\SequenceNo:::MOVE_* | |
*/ | |
public function moveItem($id, $dir=\Scrivo\SequenceNo::MOVE_DOWN) { | |
\Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( | |
array(\Scrivo\ArgumentCheck::TYPE_INTEGER), | |
array(\Scrivo\ArgumentCheck::TYPE_INTEGER) | |
)); | |
$this->context->checkPermission( | |
\Scrivo\AccessController::WRITE_ACCESS, $this->pageId); | |
\Scrivo\SequenceNo::position($this->context, "list_item", | |
array("parent_id", "item_list_id"), $id, $dir); | |
$this->removeFromCache(); | |
} | |
/** | |
* Remove this list (including all sub lists from the cache). | |
*/ | |
private function removeFromCache() { | |
$cId = $this->pageId . "." . $this->pagePropertyDefinitionId; | |
if ($this->listPids) { | |
$listIds = array_keys($this->listPids); | |
foreach ($listIds as $id) { | |
unset($this->context->cache[$cId . "." . $id]); | |
} | |
} | |
unset($this->context->cache[$cId]); | |
} | |
} | |