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: Role.php 866 2013-08-25 16:22:35Z geert $ 30 */ 31 32 /** 33 * Implementation of the \Scrivo\Role class. 34 */ 35 36 namespace Scrivo; 37 38 /** 39 * Class that represents a system role class. 40 * 41 * Access to pages and assets is restricted through roles. Users can be 42 * registered to one or more roles as well as objects (pages and assets). 43 * Do one or more roles of the object and the user match an access level 44 * higher than the default for the user is granted. 45 * 46 * When access is granted, a distiction is made in editor roles and public 47 * roles. A user with User::STATUS_EDITOR can only be registered to one or 48 * more Role::EDITOR_ROLE-s, a user with status User::STATUS_MEMBER only 49 * to one or more User::PUBLIC_ROLE-s. 50 * 51 * For role matching see \Scrivo\AccessController. 52 * 53 * TODO currently object ids 1 and 2 are used for system roles, this is not 54 * in line with the policy for object ids. 55 * 56 * @property-read int $id The role id (DB key). 57 * @property \Scrivo\String $description A descriptive name for this role. 58 * @property \Scrivo\String $title The role title. 59 * @property int $type The role type, \Scrivo\Role::EDITOR_ROLE or 60 * \Scrivo\Role::PUBLIC_ROLE 61 */ 62 class Role { 63 64 /** 65 * Constant to denote a public role. 66 */ 67 const PUBLIC_ROLE = 3; 68 69 /** 70 * Constant to denote an editor role. 71 */ 72 const EDITOR_ROLE = 2; 73 74 /** 75 * The role id (DB key). 76 * @var int 77 */ 78 protected $id = 0; 79 80 /** 81 * The role type, \Scrivo\Role::EDITOR_ROLE or \Scrivo\Role::PUBLIC_ROLE 82 * @var int 83 */ 84 private $type = self::PUBLIC_ROLE; 85 86 /** 87 * The role title. 88 * @var \Scrivo\String 89 */ 90 private $title = null; 91 92 /** 93 * A descriptive name for this role. 94 * @var \Scrivo\String 95 */ 96 private $description = null; 97 98 /** 99 * A Scrivo context. 100 * @var \Scrivo\Context 101 */ 102 private $context = null; 103 104 /** 105 * Create an empty role object. 106 * 107 * @param \Scrivo\Context $context A Scrivo context. 108 */ 109 public function __construct(\Scrivo\Context $context=null) { 110 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null), 0); 111 112 if ($context) { 113 $this->title = new \Scrivo\String(); 114 $this->description = new \Scrivo\String(); 115 116 $this->context = $context; 117 } 118 } 119 120 /** 121 * Implementation of the readable properties using the PHP magic 122 * method __get(). 123 * 124 * @param string $name The name of the property to get. 125 * 126 * @return mixed The value of the requested property. 127 */ 128 public function __get($name) { 129 switch($name) { 130 case "id": return $this->id; 131 case "type": return $this->type; 132 case "title": return $this->title; 133 case "description": return $this->description; 134 } 135 throw new \Scrivo\SystemException("No such get-property '$name'."); 136 } 137 138 /** 139 * Implementation of the writable properties using the PHP magic 140 * method __set(). 141 * 142 * @param string $name The name of the property to set. 143 * @param mixed $value The value of the property to set. 144 */ 145 public function __set($name, $value) { 146 switch($name) { 147 case "type": $this->setType($value); return; 148 case "title": $this->setTitle($value); return; 149 case "description": $this->setDescription($value); return; 150 } 151 throw new \Scrivo\SystemException("No such set-property '$name'."); 152 } 153 154 /** 155 * Convenience method to set the fields of a role object from 156 * an array (result set row). 157 * 158 * @param \Scrivo\Context $context A Scrivo context. 159 * @param array $rd An array containing the field data using the database 160 * field names as keys. 161 */ 162 protected function setFields(\Scrivo\Context $context, array $rd) { 163 164 $this->id = intval($rd["role_id"]); 165 $this->type = intval($rd["type"]); 166 $this->title = new \Scrivo\String($rd["title"]); 167 $this->description = new \Scrivo\String($rd["description"]); 168 169 $this->context = $context; 170 } 171 172 /** 173 * Set the role's type, \Scrivo\Role::EDITOR_ROLE or 174 * \Scrivo\Role::PUBLIC_ROLE. 175 * 176 * @param int $type The role's type, \Scrivo\Role::EDITOR_ROLE or 177 * \Scrivo\Role::PUBLIC_ROLE. 178 */ 179 private function setType($type) { 180 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( 181 array(\Scrivo\ArgumentCheck::TYPE_INTEGER, 182 array(self::EDITOR_ROLE, self::PUBLIC_ROLE)) 183 )); 184 185 $this->type = $type; 186 } 187 188 /** 189 * Set the role title. 190 * 191 * @param \Scrivo\String $title The role's title. 192 */ 193 private function setTitle(\Scrivo\String $title) { 194 $this->title = $title; 195 } 196 197 /** 198 * Set the descriptive name for this role. 199 * 200 * @param \Scrivo\String $description A descriptive name for this role. 201 */ 202 private function setDescription(\Scrivo\String $description) { 203 $this->description = $description; 204 } 205 206 /** 207 * Check if this role object can be inserted into the database. 208 * 209 * @throws \Scrivo\ApplicationException If the data is not accessible or 210 * one or more of the fields contain invalid data. 211 */ 212 private function validateInsert() { 213 $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS); 214 } 215 216 /** 217 * Insert new role object data into the database. 218 * 219 * First it is checked if the data of this role object can be inserted 220 * into the database, then the data is inserted into the database. If no id 221 * was set a new object id is generated. 222 * 223 * @throws \Scrivo\ApplicationException If the data is not accessible or 224 * one or more of the fields contain invalid data. 225 */ 226 public function insert() { 227 try { 228 $this->validateInsert(); 229 230 if (!$this->id) { 231 $this->id = $this->context->connection->generateId(); 232 } 233 234 $sth = $this->context->connection->prepare( 235 "INSERT INTO role (instance_id, role_id, type, title, description) 236 VALUES (:instId, :id, :type, :title, :descr)"); 237 238 $this->context->connection->bindInstance($sth); 239 $sth->bindValue(":id", $this->id, \PDO::PARAM_INT); 240 $sth->bindValue(":type", $this->type, \PDO::PARAM_INT); 241 $sth->bindValue(":title", $this->title, \PDO::PARAM_STR); 242 $sth->bindValue(":descr", $this->description, \PDO::PARAM_STR); 243 244 $sth->execute(); 245 246 } catch(\PDOException $e) { 247 throw new \Scrivo\ResourceException($e); 248 } 249 } 250 251 /** 252 * Check if this role object can be updated in the database. 253 * 254 * @throws \Scrivo\ApplicationException If the data is not accessible or 255 * one or more of the fields contain invalid data. 256 */ 257 private function validateUpdate() { 258 $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS); 259 } 260 261 /** 262 * Update existing role object data in the database. 263 * 264 * First it is checked if the data of this role object can be updated 265 * in the database, then the data is updated in the database. 266 * 267 * @throws \Scrivo\ApplicationException If the data is not accessible or 268 * one or more of the fields contain invalid data. 269 */ 270 public function update() { 271 try { 272 $this->validateUpdate(); 273 274 $sth = $this->context->connection->prepare( 275 "UPDATE role SET 276 type = :type, title = :title, description = :descr 277 WHERE instance_id = :instId AND role_id = :id"); 278 279 $this->context->connection->bindInstance($sth); 280 $sth->bindValue(":id", $this->id, \PDO::PARAM_INT); 281 $sth->bindValue(":type", $this->type, \PDO::PARAM_INT); 282 $sth->bindValue(":title", $this->title, \PDO::PARAM_STR); 283 $sth->bindValue(":descr", $this->description, \PDO::PARAM_STR); 284 285 $sth->execute(); 286 287 unset($this->context->cache[$this->id]); 288 289 } catch(\PDOException $e) { 290 throw new \Scrivo\ResourceException($e); 291 } 292 } 293 294 /** 295 * Check if deletion of role object data does not violate any 296 * business rules. 297 * 298 * @param \Scrivo\Context $context A Scrivo context. 299 * @param int $id The object id of the role to select. 300 * 301 * @throws \Scrivo\ApplicationException If the data is not accessible or 302 * if it is not possible to delete the language data. 303 */ 304 private static function validateDelete(\Scrivo\Context $context, $id) { 305 $context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS); 306 } 307 308 /** 309 * Delete existing role data from the database. 310 * 311 * First it is is checked if it's possible to delete role data, 312 * then the role data including its dependecies is deleted from 313 * the database. 314 * 315 * @param \Scrivo\Context $context A Scrivo context. 316 * @param int $id The object id of the role to select. 317 * 318 * @throws \Scrivo\ApplicationException If the data is not accessible or 319 * if it is not possible to delete the role data. 320 */ 321 public static function delete(\Scrivo\Context $context, $id) { 322 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( 323 null, 324 array(\Scrivo\ArgumentCheck::TYPE_INTEGER) 325 )); 326 try { 327 self::validateDelete($context, $id); 328 329 foreach (array("role", "user_role", "object_role") as $table) { 330 331 $sth = $context->connection->prepare( 332 "DELETE FROM $table 333 WHERE instance_id = :instId AND role_id = :id"); 334 335 $context->connection->bindInstance($sth); 336 $sth->bindValue(":id", $id, \PDO::PARAM_INT); 337 338 $sth->execute(); 339 } 340 341 unset($context->cache[$id]); 342 343 } catch(\PDOException $e) { 344 throw new \Scrivo\ResourceException($e); 345 } 346 } 347 348 /** 349 * Fetch a role object from the database using its object id. 350 * 351 * @param \Scrivo\Context $context A Scrivo context. 352 * @param int $id The object id of the role to select. 353 * 354 * @return \Scrivo\Role The requested role object. 355 */ 356 public static function fetch(\Scrivo\Context $context, $id) { 357 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( 358 null, 359 array(\Scrivo\ArgumentCheck::TYPE_INTEGER) 360 )); 361 try { 362 // Try to retieve the role from the cache ... 363 if (isset($context->cache[$id])) { 364 // ... get it from the cache and set the context. 365 $role = $context->cache[$id]; 366 $role->context = $context; 367 } else { 368 // ... else retrieve it and set it in the cache. 369 $sth = $context->connection->prepare( 370 "SELECT role_id, type, title, description 371 FROM role 372 WHERE instance_id = :instId AND role_id = :id"); 373 374 $context->connection->bindInstance($sth); 375 $sth->bindValue(":id", $id, \PDO::PARAM_INT); 376 377 $sth->execute(); 378 379 if ($sth->rowCount() != 1) { 380 throw new \Scrivo\SystemException("Failed to load role"); 381 } 382 383 $role = new \Scrivo\Role(); 384 $role->setFields($context, $sth->fetch(\PDO::FETCH_ASSOC)); 385 386 $context->cache[$id] = $role; 387 } 388 389 return $role; 390 391 } catch(\PDOException $e) { 392 throw new \Scrivo\ResourceException($e); 393 } 394 } 395 396 /** 397 * Select roles from the database. 398 * 399 * Depending on the given arguments the public or editor roles can be 400 * retrieved. 401 * 402 * @param \Scrivo\Context $context A Scrivo context. 403 * @param int $type A role type: \Scrivo\Role::PUBLIC_ROLE or 404 * \Scrivo\Role::EDITOR_ROLE for which to retrieve the roles. 405 * 406 * @return \Scrivo\Role[id] An array containing the selected roles. 407 */ 408 public static function select(\Scrivo\Context $context, $type) { 409 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( 410 null, 411 array(\Scrivo\ArgumentCheck::TYPE_INTEGER, 412 array(self::EDITOR_ROLE, self::PUBLIC_ROLE)) 413 )); 414 try { 415 $sth = $context->connection->prepare( 416 "SELECT role_id, type, title, description FROM role 417 WHERE instance_id = :instId AND type = :type"); 418 419 $context->connection->bindInstance($sth); 420 $sth->bindValue(":type", $type, \PDO::PARAM_INT); 421 422 $sth->execute(); 423 424 $res = array(); 425 426 while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { 427 428 $li = new Role(); 429 $li->setFields($context, $rd); 430 431 $res[$li->id] = $li; 432 } 433 434 return $res; 435 436 } catch(\PDOException $e) { 437 throw new \Scrivo\ResourceException($e); 438 } 439 } 440 441 } 442 443 ?>
Documentation generated by phpDocumentor 2.0.0a12 and ScrivoDocumentor on August 29, 2013