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: Language.php 866 2013-08-25 16:22:35Z geert $ 30 */ 31 32 /** 33 * Implementation of the \Scrivo\Language class. 34 */ 35 36 namespace Scrivo; 37 38 /** 39 * Class that represents a language. 40 * 41 * Pages (and possible HTML elements) can have a language attribute. For that 42 * reason Scrivo maintains a table of (primary) language codes. 43 * 44 * To facilitate language selection a short list of languages can be compiled. 45 * In the user interface language selection will be limited to those that 46 * are on the short list. 47 * 48 * Since the primary purpose of the language class is to fill language 49 * selection dialogs the full display name of the languages is stored in 50 * both Dutch and English. 51 * 52 * TODO: This should be refactored. There is no need for a seperate class: 53 * ISO language codes will do fully here. An other undesirable feature is 54 * the storage of i18n data (the full language names) in the database. 55 * 56 * @property-read int $id The language id (DB key). 57 * @property \Scrivo\String $family The language family (Germanic, Slavic). 58 * @property \Scrivo\String $isoCode The language ISO code. 59 * @property \Scrivo\String $nameEn The language name in English. 60 * @property \Scrivo\String $nameNl The language name in Dutch. 61 * @property boolean $shortList Whether a language is on the short list or not. 62 */ 63 class Language { 64 65 /** 66 * The language id (DB key). 67 * @var int 68 */ 69 private $id = 0; 70 71 /** 72 * Whether a language is on the short list or not. 73 * @var boolean 74 */ 75 private $shortList = false; 76 77 /** 78 * The language ISO code. 79 * @var \Scrivo\String 80 */ 81 private $isoCode = null; 82 83 /** 84 * The language family (Germanic, Slavic). 85 * @var \Scrivo\String 86 */ 87 private $family = null; 88 89 /** 90 * The language name in English. 91 * @var \Scrivo\String 92 */ 93 private $nameEn = null; 94 95 /** 96 * The language name in Dutch. 97 * @var \Scrivo\String 98 */ 99 private $nameNl = null; 100 101 /** 102 * A Scrivo context. 103 * @var \Scrivo\Context 104 */ 105 private $context = null; 106 107 /** 108 * Create an empty language object. 109 * 110 * @param \Scrivo\Context $context A Scrivo context. 111 */ 112 public function __construct(\Scrivo\Context $context=null) { 113 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null)); 114 115 if ($context) { 116 $this->isoCode = new\Scrivo\String(); 117 $this->family = new\Scrivo\String(); 118 $this->nameEn = new\Scrivo\String(); 119 $this->nameNl = new\Scrivo\String(); 120 121 $this->context = $context; 122 } 123 } 124 125 /** 126 * Implementation of the readable properties using the PHP magic 127 * method __get(). 128 * 129 * @param string $name The name of the property to get. 130 * 131 * @return mixed The value of the requested property. 132 */ 133 public function __get($name) { 134 switch($name) { 135 case "id": return $this->id; 136 case "shortList": return $this->shortList; 137 case "isoCode": return $this->isoCode; 138 case "family": return $this->family; 139 case "nameEn": return $this->nameEn; 140 case "nameNl": return $this->nameNl; 141 } 142 throw new \Scrivo\SystemException("No such get-property '$name'."); 143 } 144 145 /** 146 * Implementation of the writable properties using the PHP magic 147 * method __set(). 148 * 149 * @param string $name The name of the property to set. 150 * @param mixed $value The value of the property to set. 151 */ 152 public function __set($name, $value) { 153 switch($name) { 154 case "shortList": $this->setShortList($value); return; 155 case "isoCode": $this->setIsoCode($value); return; 156 case "family": $this->setFamily($value); return; 157 case "nameEn": $this->setNameEn($value); return; 158 case "nameNl": $this->setNameNl($value); return; 159 } 160 throw new \Scrivo\SystemException("No such set-property '$name'."); 161 } 162 163 /** 164 * Convenience method to set the fields of a language object from 165 * an array (result set row). 166 * 167 * @param \Scrivo\Context $context A Scrivo context. 168 * @param array $rd An array containing the field data using the database 169 * field names as keys. 170 */ 171 private function setFields(\Scrivo\Context $context, array $rd) { 172 173 $this->id = intval($rd["language_id"]); 174 $this->shortList = intval($rd["short_list"]) == 1 ? true : false; 175 $this->isoCode = new \Scrivo\String($rd["iso_code"]); 176 $this->family = new \Scrivo\String($rd["family"]); 177 $this->nameEn = new \Scrivo\String($rd["name_en"]); 178 $this->nameNl = new \Scrivo\String($rd["name_nl"]); 179 180 $this->context = $context; 181 } 182 183 /** 184 * Set the value to indicate if a language is on the short list or not. 185 * 186 * @param boolean $shortList Whether a language is on the short list or not. 187 */ 188 private function setShortList($shortList) { 189 \Scrivo\ArgumentCheck::assert( 190 $shortList, \Scrivo\ArgumentCheck::TYPE_BOOLEAN); 191 $this->shortList = $shortList; 192 } 193 194 /** 195 * Set the language ISO code. 196 * 197 * @param \Scrivo\String $isoCode The language ISO code. 198 */ 199 private function setIsoCode(\Scrivo\String $isoCode) { 200 $this->isoCode = $isoCode; 201 } 202 203 /** 204 * Set the language family (Germanic, Slavic). 205 * 206 * @param \Scrivo\String $family The language family (Germanic, Slavic). 207 */ 208 private function setFamily(\Scrivo\String $family) { 209 $this->family = $family; 210 } 211 212 /** 213 * Set the language name in English. 214 * 215 * @param \Scrivo\String $nameEn The language name in English. 216 */ 217 private function setNameEn(\Scrivo\String $nameEn) { 218 $this->nameEn = $nameEn; 219 } 220 221 /** 222 * Set the language name in Dutch. 223 * 224 * @param \Scrivo\String $nameNl The language name in Dutch. 225 */ 226 private function setNameNl(\Scrivo\String $nameNl) { 227 $this->nameNl = $nameNl; 228 } 229 230 /** 231 * Check if this language object can be inserted into the database. 232 * 233 * @throws \Scrivo\ApplicationException If the data is not accessible or 234 * one or more of the fields contain invalid data. 235 */ 236 private function validateInsert() { 237 $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS); 238 } 239 240 /** 241 * Insert new language object data into the database. 242 * 243 * First it is checked if the data of this language object can be inserted 244 * into the database, then the data is inserted into the database. If no id 245 * was set a new object id is generated. 246 * 247 * @throws \Scrivo\ApplicationException If the data is not accessible or 248 * one or more of the fields contain invalid data. 249 */ 250 public function insert() { 251 try { 252 $this->validateInsert(); 253 254 if (!$this->id) { 255 $this->id = $this->context->connection->generateId(); 256 } 257 258 $sth = $this->context->connection->prepare( 259 "INSERT INTO language ( 260 instance_id, language_id, short_list, iso_code, family, 261 name_en, name_nl 262 ) VALUES ( 263 :instId, :id, :shortList, :isoCode, :family, 264 :nameEn, :nameNl 265 )"); 266 267 $this->context->connection->bindInstance($sth); 268 $sth->bindValue(":id", $this->id, \PDO::PARAM_INT); 269 $sth->bindValue(":shortList", $this->shortList, \PDO::PARAM_INT); 270 $sth->bindValue(":isoCode", $this->isoCode, \PDO::PARAM_STR); 271 $sth->bindValue(":family", $this->family, \PDO::PARAM_STR); 272 $sth->bindValue(":nameEn", $this->nameEn, \PDO::PARAM_STR); 273 $sth->bindValue(":nameNl", $this->nameNl, \PDO::PARAM_STR); 274 275 $sth->execute(); 276 277 } catch(\PDOException $e) { 278 throw new \Scrivo\ResourceException($e); 279 } 280 } 281 282 /** 283 * Check if this language object can be updated in the database. 284 * 285 * @throws \Scrivo\ApplicationException If the data is not accessible or 286 * one or more of the fields contain invalid data. 287 */ 288 private function validateUpdate() { 289 $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS); 290 } 291 292 /** 293 * Update an existing language object data in the database. 294 * 295 * First it is checked if the data of this language object can be updated 296 * in the database, then the data is updated in the database. 297 * 298 * @throws \Scrivo\ApplicationException If the data is not accessible or 299 * one or more of the fields contain invalid data. 300 */ 301 public function update() { 302 try { 303 $this->validateUpdate(); 304 305 $sth = $this->context->connection->prepare( 306 "UPDATE language SET 307 short_list = :shortList, iso_code = :isoCode, family = :family, 308 name_en = :nameEn, name_nl = :nameNl 309 WHERE instance_id = :instId AND language_id = :id"); 310 311 $this->context->connection->bindInstance($sth); 312 $sth->bindValue(":id", $this->id, \PDO::PARAM_INT); 313 314 $sth->bindValue(":shortList", $this->shortList, \PDO::PARAM_INT); 315 $sth->bindValue(":isoCode", $this->isoCode, \PDO::PARAM_STR); 316 $sth->bindValue(":family", $this->family, \PDO::PARAM_STR); 317 $sth->bindValue(":nameEn", $this->nameEn, \PDO::PARAM_STR); 318 $sth->bindValue(":nameNl", $this->nameNl, \PDO::PARAM_STR); 319 320 $sth->execute(); 321 322 unset($this->context->cache["L".$this->id]); 323 324 } catch(\PDOException $e) { 325 throw new \Scrivo\ResourceException($e); 326 } 327 } 328 329 /** 330 * Check if deletion of language object data does not violate any 331 * business rules. 332 * 333 * @param \Scrivo\Context $context A Scrivo context. 334 * @param int $id The object id of the language to select. 335 * 336 * @throws \Scrivo\ApplicationException If the data is not accessible or 337 * if it is not possible to delete the language data. 338 */ 339 private static function validateDelete(\Scrivo\Context $context, $id) { 340 $context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS); 341 } 342 343 /** 344 * Delete existing language data from the database. 345 * 346 * First it is is checked if it's possible to delete language data, 347 * then the language data including its dependecies is deleted from 348 * the database. 349 * 350 * @param \Scrivo\Context $context A Scrivo context. 351 * @param int $id The object id of the language to select. 352 * 353 * @throws \Scrivo\ApplicationException If the data is not accessible or 354 * if it is not possible to delete the language data. 355 */ 356 public static function delete(\Scrivo\Context $context, $id) { 357 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( 358 null, 359 array(\Scrivo\ArgumentCheck::TYPE_INTEGER) 360 )); 361 try { 362 self::validateDelete($context, $id); 363 364 $sth = $context->connection->prepare( 365 "DELETE FROM language 366 WHERE instance_id = :instId AND language_id = :id"); 367 368 $context->connection->bindInstance($sth); 369 $sth->bindValue(":id", $id, \PDO::PARAM_INT); 370 371 $sth->execute(); 372 373 unset($context->cache["L".$id]); 374 375 } catch(\PDOException $e) { 376 throw new \Scrivo\ResourceException($e); 377 } 378 } 379 380 /** 381 * Fetch a language object by from the database using the object id. 382 * 383 * @param \Scrivo\Context $context A Scrivo context. 384 * @param int $id The object id of the language to select. 385 * 386 * @return \Scrivo\Language The requested language object. 387 */ 388 public static function fetch(\Scrivo\Context $context, $id) { 389 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( 390 null, 391 array(\Scrivo\ArgumentCheck::TYPE_INTEGER) 392 )); 393 try { 394 // Try to retieve the language from the cache ... 395 if (isset($context->cache["L".$id])) { 396 // ... get it from the cache and set the context. 397 $language = $context->cache["L".$id]; 398 $language->context = $context; 399 } else { 400 // ... else retrieve it and set it in the cache. 401 $sth = $context->connection->prepare( 402 "SELECT language_id, short_list, iso_code, family, name_en, name_nl 403 FROM language 404 WHERE instance_id = :instId AND language_id = :id"); 405 406 $context->connection->bindInstance($sth); 407 $sth->bindValue(":id", $id, \PDO::PARAM_INT); 408 409 $sth->execute(); 410 411 if ($sth->rowCount() != 1) { 412 throw new 413 \Scrivo\SystemException("Failed to load language"); 414 } 415 416 $language = new \Scrivo\Language(); 417 $language->setFields($context, $sth->fetch(\PDO::FETCH_ASSOC)); 418 419 $context->cache["L".$id] = $language; 420 } 421 422 return $language; 423 424 } catch(\PDOException $e) { 425 throw new \Scrivo\ResourceException($e); 426 } 427 } 428 429 /** 430 * Select languages from the database. 431 * 432 * @param \Scrivo\Context $context A Scrivo context. 433 * @param boolean $shortList A Scrivo context. 434 * 435 * @return Language[id] An array containing the selected languages. 436 */ 437 public static function select(\Scrivo\Context $context, $shortList=null) { 438 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( 439 null, 440 array(\Scrivo\ArgumentCheck::TYPE_BOOLEAN) 441 ), 1); 442 try { 443 $sth = $context->connection->prepare( 444 "SELECT language_id, short_list, iso_code, family, name_en, name_nl 445 FROM language WHERE instance_id = :instId ". 446 ($shortList ? " AND short_list=1" : ""). " ORDER BY iso_code"); 447 448 $context->connection->bindInstance($sth); 449 450 $sth->execute(); 451 452 $res = array(); 453 454 while ($rd = $sth->fetch(\PDO::FETCH_ASSOC)) { 455 456 $li = new Language(); 457 $li->setFields($context, $rd); 458 459 $res[$li->id] = $li; 460 } 461 462 return $res; 463 464 } catch(\PDOException $e) { 465 throw new \Scrivo\ResourceException($e); 466 } 467 } 468 469 } 470 471 ?>
Documentation generated by phpDocumentor 2.0.0a12 and ScrivoDocumentor on August 29, 2013