1 <?php 2 /* Copyright (c) 2013, Geert Bergman (geert@scrivo.nl) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. Neither the name of "Scrivo" nor the names of its contributors may be 14 * used to endorse or promote products derived from this software without 15 * specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * $Id: RoleSet.php 547 2013-03-04 12:06:51Z geert $ 30 */ 31 32 /** 33 * Implementation of the \Scrivo\PageSet class. 34 */ 35 36 namespace Scrivo; 37 38 /** 39 * A Scrivo Page set is a group of Scrivo pages with a common parent id. A 40 * page set is actually a simple array of (child) pages but it does a 41 * couple of things extra: 42 * 43 * - When serialized only the ids are stored. 44 * - When iteratering, counting or getting pages from the array only the 45 * readable pages in the array will be taken into account. 46 * 47 * Page sets are a part of a Scrivo page and are used to retrieve and iterate 48 * through the child pages (or path) of a page. 49 */ 50 class PageSet implements \ArrayAccess, \Iterator, \Countable { 51 52 /** 53 * The array containing the pages or page ids. 54 * @var \Scrivo\Page[id]|int[id] 55 */ 56 private $items = array(); 57 58 /** 59 * The parent page of the set. 60 * @var \Scrivo\Page 61 */ 62 private $page = null; 63 64 /** 65 * An array containing the keys of the items array, used when serializing. 66 * @var int[id] 67 */ 68 private $ids = null; 69 70 /** 71 * When reading the items array always check of the actual entry is an 72 * instantiated Scrivo page. If not, get that page and store it in the 73 * items array. 74 * 75 * @param int $id The page id of the entry to check. 76 */ 77 private function check($id) { 78 if (is_int($this->items[$id])) { 79 $this->items[$id] = 80 \Scrivo\Page::fetch($this->page->context, $this->items[$id]); 81 } 82 return $this->items[$id]; 83 } 84 85 /** 86 * Construct a page set. 87 * 88 * @param \Scrivo\Page $page The parent page of the page set. 89 */ 90 public function __construct(\Scrivo\Page $page) { 91 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null)); 92 93 $this->items = array(); 94 $this->page = $page; 95 } 96 97 /** 98 * Set a page in the page set. 99 * 100 * @param int $id A Scrivo page id. 101 * @param \Scrivo\Page $page The parent page of the page set. 102 */ 103 public function offsetSet($id, $page) { 104 $this->items[$id] = $page; 105 } 106 107 /** 108 * Add a page to the beginning of the set. 109 * 110 * @param \Scrivo\Page $page The parent page of the page set. 111 */ 112 public function prepend($page) { 113 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null)); 114 115 array_unshift($this->items, $page); 116 } 117 118 /** 119 * Test if page is set in the page set. 120 * 121 * @param int $id A Scrivo page id to test. 122 * 123 * @return boolean True of the page with the given id exists in the set. 124 */ 125 public function offsetExists($id) { 126 return (isset($this->items[$id]) && 127 $this->check($id)->roles->canRead($this->page->context->principal)); 128 } 129 130 /** 131 * It is not possible to unset pages in a page set. Calling this method 132 * will raise a system exception. 133 * 134 * @param int $id A Scrivo page id to unset. 135 */ 136 public function offsetUnset($id) { 137 throw new \Scrivo\SystemException("Illegal method"); 138 } 139 140 /** 141 * Get a page with a specific id from the page set. 142 * 143 * @param int $id A Scrivo page id to test. 144 * 145 * @return \Scrivo\Page The page with the given id. 146 */ 147 public function offsetGet($id) { 148 if (!$this->offsetExists($id)) { 149 throw new \Scrivo\SystemException("Not set"); 150 } 151 return $this->items[$id]; 152 } 153 154 /** 155 * Rewind the page set so that iterating will start at the beginning. 156 */ 157 function rewind() { 158 reset($this->items); 159 } 160 161 /** 162 * Get the current page from the page set when iterating. 163 * 164 * @return \Scrivo\Page The current page in the page set. 165 */ 166 function current() { 167 return current($this->items); 168 } 169 170 /** 171 * Get the key(id) of the current page from the page set when iterating. 172 * 173 * @return \Scrivo\Page The key (id) of the current page in the page set. 174 */ 175 function key() { 176 return key($this->items); 177 } 178 179 /** 180 * Get the current page from the page set and move the internal pointer 181 * to the next page in the set. 182 * 183 * @return \Scrivo\Page The current page in the page set. 184 */ 185 function next() { 186 return next($this->items); 187 } 188 189 /** 190 * Test if the current page is valid. 191 * 192 * @return boolean True if the current page is valid. 193 */ 194 function valid() { 195 196 $k = key($this->items); 197 $pr = $this->page->context->principal; 198 199 // Get the current page ... 200 if (isset($this->items[$k]) && $c = $this->check($k)) { 201 // ... and check if it is readable ... 202 if ($c->roles->canRead($pr)) { 203 return true; 204 } 205 // ... and if not move to the next until a readable page is found. 206 while (next($this->items)) { 207 if ($this->check(key($this->items))->roles->canRead($pr)) { 208 return true; 209 } 210 } 211 } 212 213 return false; 214 } 215 216 /** 217 * The page count of pages in the set. Note that returned page count 218 * depends on whether the pages are readable for the user defined in the 219 * Scrivo context. So the returned count is always equeal or less that the 220 * actual count of pages in the items array. 221 * 222 * @return int The number of pages in the set that are readable for the 223 * users defined in the Scrivo context. 224 */ 225 public function count() { 226 // Start counting 227 $count = 0; 228 foreach($this as $i) { 229 if ($i->roles->canRead($this->page->context->principal)) { 230 $count++; 231 } 232 } 233 return $count; 234 } 235 236 /** 237 * When serializing retrieve the don't store the items array but just the 238 * keys. 239 * 240 * return array An array with the names of the serializable members. 241 */ 242 public function __sleep() { 243 244 $this->ids = array_keys($this->items); 245 246 // Note that page sets always will be serialized as a part of the 247 // parent page. Therefore the page member will be serialized as a 248 // reference value. 249 return array("ids", "page"); 250 } 251 252 /** 253 * When unserializing restore the items array only the id. 254 */ 255 public function __wakeup() { 256 $this->items = array_combine($this->ids, $this->ids); 257 unset($this->ids); 258 } 259 260 } 261 262 ?>
Documentation generated by phpDocumentor 2.0.0a12 and ScrivoDocumentor on August 29, 2013