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: AssetSet.php 841 2013-08-19 22:19:47Z geert $ 30 */ 31 32 /** 33 * Implementation of the \Scrivo\AssetSet class. 34 */ 35 36 namespace Scrivo; 37 38 /** 39 * A Scrivo Asset set is a group of Scrivo assets with a common parent id. A 40 * asset set is actually a simple array of (child) assets but it does a 41 * couple of things extra: 42 * 43 * - When serialized only the ids are stored. 44 * - When iteratering, counting or getting assets from the array only the 45 * readable assets in the array will be taken into account. 46 * 47 * Asset sets are a part of a Scrivo asset and are used to retrieve and iterate 48 * through the child assets (or path) of an asset. 49 */ 50 class AssetSet implements \ArrayAccess, \Iterator, \Countable { 51 52 /** 53 * The array containing the assets or asset ids. 54 * @var \Scrivo\Asset[id]|int[id] 55 */ 56 private $items = array(); 57 58 /** 59 * The parent asset of the set. 60 * @var \Scrivo\Asset 61 */ 62 private $asset = 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 asset. If not, get that asset and store it in the 73 * items array. 74 * 75 * @param int $id The asset 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\Asset::fetch($this->asset->context, $this->items[$id]); 81 } 82 return $this->items[$id]; 83 } 84 85 /** 86 * Construct an asset set. 87 * 88 * @param \Scrivo\Asset $asset The parent asset of the asset set. 89 */ 90 public function __construct(\Scrivo\Asset $asset) { 91 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null)); 92 93 $this->items = array(); 94 $this->asset = $asset; 95 } 96 97 /** 98 * Set an asset in the asset set. 99 * 100 * @param int $id A Scrivo asset id. 101 * @param \Scrivo\Asset $asset The parent asset of the asset set. 102 */ 103 public function offsetSet($id, $asset) { 104 $this->items[$id] = $asset; 105 } 106 107 /** 108 * Add an asset to the beginning of the set. 109 * 110 * @param \Scrivo\Asset $asset The parent asset of the asset set. 111 */ 112 public function prepend($asset) { 113 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null)); 114 115 $this->items = array($asset->id => $asset) + $this->items; 116 } 117 118 /** 119 * Test if asset is set in the asset set. 120 * 121 * @param int $id A Scrivo asset id to test. 122 * 123 * @return boolean True of the asset 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->asset->context->principal)); 128 } 129 130 /** 131 * It is not possible to unset assets in an asset set. Calling this method 132 * will raise a system exception. 133 * 134 * @param int $id A Scrivo asset id to unset. 135 */ 136 public function offsetUnset($id) { 137 throw new \Scrivo\SystemException("Illegal method"); 138 } 139 140 /** 141 * Get an asset with a specific id from the asset set. 142 * 143 * @param int $id A Scrivo asset id to test. 144 * 145 * @return \Scrivo\Asset The asset 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 asset set so that iterating will start at the beginning. 156 */ 157 function rewind() { 158 reset($this->items); 159 } 160 161 /** 162 * Get the current asset from the asset set when iterating. 163 * 164 * @return \Scrivo\Asset The current asset in the asset set. 165 */ 166 function current() { 167 return current($this->items); 168 } 169 170 /** 171 * Get the key(id) of the current asset from the asset set when iterating. 172 * 173 * @return \Scrivo\Asset The key (id) of the current asset in the asset set. 174 */ 175 function key() { 176 return key($this->items); 177 } 178 179 /** 180 * Get the current asset from the asset set and move the internal pointer 181 * to the next asset in the set. 182 * 183 * @return \Scrivo\Asset The current asset in the asset set. 184 */ 185 function next() { 186 return next($this->items); 187 } 188 189 /** 190 * Test if the current asset is valid. 191 * 192 * @return boolean True if the current asset is valid. 193 */ 194 function valid() { 195 196 $k = key($this->items); 197 $pr = $this->asset->context->principal; 198 199 // Get the current asset ... 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 asset 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 asset count of assets in the set. Note that returned asset count 218 * depends on whether the assets 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 assets in the items array. 221 * 222 * @return int The number of assets 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->asset->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 asset sets always will be serialized as a part of the 247 // parent asset. Therefore the asset member will be serialized as a 248 // reference value. 249 return array("ids", "asset"); 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