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: File.php 866 2013-08-25 16:22:35Z geert $ 30 */ 31 32 /** 33 * Implementation of the \Scrivo\Asset class. 34 */ 35 36 namespace Scrivo; 37 38 /** 39 */ 40 class File extends Asset { 41 42 /** 43 * The size in bytes of the asset. 44 * @var int 45 */ 46 private $size = 0; 47 48 /** 49 * The asset location. 50 * @var \Scrivo\String 51 */ 52 private $location = null; 53 54 /** 55 * The asset mimeType. 56 * @var \Scrivo\String 57 */ 58 private $mimeType = null; 59 60 /** 61 * The date/time this asset need to go online. 62 * @var \DateTime 63 */ 64 private $dateOnline = null; 65 66 /** 67 * The date/time this asset need to go offline. 68 * @var \DateTime 69 */ 70 private $dateOffline = null; 71 72 /** 73 * Create an empty asset object. 74 * 75 * @param \Scrivo\Context $context A Scrivo context. 76 */ 77 public function __construct(\Scrivo\Context $context=null) { 78 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null), 0); 79 80 if ($context) { 81 82 parent::__construct($context); 83 84 $this->size = 0; 85 $this->location = new \Scrivo\String(); 86 $this->mimeType = new \Scrivo\String(); 87 $this->dateOnline = new \DateTime("now"); 88 $this->dateOffline = null; 89 } 90 } 91 92 /** 93 * Implementation of the readable properties using the PHP magic 94 * method __get(). 95 * 96 * @param string $name The name of the property to get. 97 * 98 * @return mixed The value of the requested property. 99 */ 100 public function __get($name) { 101 switch($name) { 102 case "size": return $this->size; 103 case "location": return $this->location; 104 case "mimeType": return $this->mimeType; 105 case "dateOnline": return $this->dateOnline; 106 case "dateOffline": return $this->dateOffline; 107 } 108 return parent::__get($name); 109 } 110 111 /** 112 * Implementation of the writable properties using the PHP magic 113 * method __set(). 114 * 115 * @param string $name The name of the property to set. 116 * @param mixed $value The value of the property to set. 117 */ 118 public function __set($name, $value) { 119 switch($name) { 120 case "size": $this->setSize($value); return; 121 case "location": $this->setLocation($value); return; 122 case "mimeType": $this->setMimeType($value); return; 123 case "dateOnline": $this->setDateOnline($value); return; 124 case "dateOffline": $this->setDateOffline($value); return; 125 } 126 parent::__set($name, $value); 127 } 128 129 /** 130 * Convenience method to set the fields of a asset definition object from 131 * an array (result set row). 132 * 133 * @param \Scrivo\Context $context A Scrivo context. 134 * @param array $rd An array containing the field data using the database 135 * field names as keys. 136 */ 137 protected function setFields(\Scrivo\Context $context, array $rd) { 138 139 parent::setFields($context, $rd); 140 141 $this->size = intval($rd["size"]); 142 $this->location = new \Scrivo\String($rd["location"]); 143 $this->mimeType = new \Scrivo\String($rd["mime_type"]); 144 $this->dateOnline = new \DateTime($rd["date_online"]); 145 $this->dateOffline = $rd["date_offline"] == null 146 ? null : new \DateTime($rd["date_offline"]); 147 } 148 149 /** 150 * Set the id of the asset template. 151 * 152 * @param int $size The id ot the asset template. 153 */ 154 private function setSize($size) { 155 \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array( 156 array(\Scrivo\ArgumentCheck::TYPE_INTEGER) 157 )); 158 $this->size = $size; 159 } 160 161 /** 162 * Set the asset location (<location>). 163 * 164 * @param \Scrivo\String $location The asset location 165 * (<location>). 166 */ 167 private function setLocation(\Scrivo\String $location) { 168 $this->location = $location; 169 } 170 171 /** 172 * Set the mimeType for this asset (<mimeType>). 173 * 174 * @param \Scrivo\String $mimeType The mimeType for this asset 175 * (<mimeType>). 176 */ 177 private function setMimeType(\Scrivo\String $mimeType) { 178 $this->mimeType = $mimeType; 179 } 180 181 /** 182 * Set the date/time this asset needs to go online. 183 * 184 * @param \DateTime $dateOnline The date/time this asset needs to go online. 185 */ 186 private function setDateOnline(\DateTime $dateOnline) { 187 $this->dateOnline = $dateOnline; 188 } 189 190 /** 191 * Set the date/time this asset need to go offline. 192 * 193 * @param \DateTime $dateOffline The date/time this asset need to go offline. 194 */ 195 private function setDateOffline(\DateTime $dateOffline=null) { 196 $this->dateOffline = $dateOffline; 197 } 198 199 /** 200 * Get a unique filename within the scope of the selected directory. 201 */ 202 private function getUniqueName() { 203 204 $base = $this->title; 205 $ext = ""; 206 $pos = $this->title->lastIndexOf(new String(".")); 207 208 if ($pos !== -1) { 209 $base = $this->title->substr(0, $pos); 210 if (!$base[$base->length - 1]->equals(new String("_"))) { 211 $base = "{$base}_"; 212 } 213 $ext = $this->title->substr($pos); 214 } 215 216 $index = 1; 217 while (!$this->checkUnique()) { 218 $this->title = new String($base.$index.$ext); 219 $index++; 220 } 221 222 } 223 224 /** 225 * Test if the asset title is unique within the scope of the directory. 226 * @return boolean 227 */ 228 private function checkUnique() { 229 230 $sth = $this->context->connection->prepare( 231 "SELECT COUNT(*) cnt FROM asset WHERE 232 instance_id = :instId AND 233 parent_id = :parentId AND title = :title"); 234 235 $this->context->connection->bindInstance($sth); 236 $sth->bindValue(":parentId", $this->parentId, \PDO::PARAM_INT); 237 $sth->bindValue(":title", $this->title, \PDO::PARAM_STR); 238 239 $sth->execute(); 240 241 if (intval($sth->fetchColumn(0)) == 0) { 242 return true; 243 } 244 return false; 245 } 246 247 /** 248 * Check if the asset data can be inserted into the database. 249 * 250 * @throws \Scrivo\ApplicationException If the data is not accessible, 251 * one or more of the fields contain invalid data or some other business 252 * rule is not met. 253 */ 254 private function validateInsert() { 255 256 if (!$this->parentId) { 257 throw new \Scrivo\SystemException( 258 "Files can't be created whithout folder"); 259 } 260 261 $this->context->checkPermission( 262 \Scrivo\AccessController::WRITE_ACCESS, $this->parentId); 263 264 $this->getUniqueName(); 265 } 266 267 /** 268 * Insert a new asset into the database. 269 * 270 * First the data fields of this asset will be validated. If no id 271 * is set a new object id is generated. Then the data is inserted into to 272 * database. 273 * 274 * @throws \Scrivo\ApplicationException If one or more of the fields 275 * contain invalid data. 276 */ 277 public function insert() { 278 try { 279 $this->validateInsert(); 280 281 if (!$this->id) { 282 $this->id = $this->context->connection->generateId(); 283 } 284 285 $sth = $this->context->connection->prepare( 286 "INSERT INTO asset ( 287 instance_id, asset_id, parent_id, sequence_no, 288 type, size, date_created, date_modified, date_online, date_offline, 289 title, location, mime_type 290 ) VALUES ( 291 :instId, :id, :parentId, 0, 292 1, :size, now(), now(), :dateOnline, :dateOffline, 293 :title, :location, :mimeType 294 )"); 295 296 $this->context->connection->bindInstance($sth); 297 $sth->bindValue(":id", $this->id, \PDO::PARAM_INT); 298 $sth->bindValue(":parentId", $this->parentId, \PDO::PARAM_INT); 299 $sth->bindValue(":size", $this->size, \PDO::PARAM_INT); 300 $sth->bindValue(":dateOnline", 301 $this->dateOnline->format("Y-m-d H:i:s"), \PDO::PARAM_STR); 302 $sth->bindValue(":dateOffline", $this->dateOffline 303 ? $this->dateOffline->format("Y-m-d H:i:s") 304 : null, \PDO::PARAM_STR); 305 $sth->bindValue(":title", $this->title, \PDO::PARAM_STR); 306 $sth->bindValue(":location", $this->location, \PDO::PARAM_STR); 307 $sth->bindValue(":mimeType", $this->mimeType, \PDO::PARAM_STR); 308 309 $sth->execute(); 310 311 unset($this->context->cache[$this->parentId]); 312 313 } catch(\PDOException $e) { 314 throw new \Scrivo\ResourceException($e); 315 } 316 } 317 318 /** 319 * Check if this the asset data can be updated in the database. 320 * 321 * @throws \Scrivo\ApplicationException If the data is not accessible, 322 * one or more of the fields contain invalid data or some other business 323 * rule is not met. 324 */ 325 private function validateUpdate() { 326 327 $this->context->checkPermission( 328 \Scrivo\AccessController::WRITE_ACCESS, $this->id); 329 330 try { 331 $newPath = self::selectPath($this); 332 } catch (\Scrivo\SystemException $e) { 333 throw new \Scrivo\ApplicationException( 334 "Can't move a asset underneath itself"); 335 } 336 337 $this->getUniqueName(); 338 } 339 340 /** 341 * Update an existing asset in the database. 342 * 343 * First the data fields of this user will be validated, then the data 344 * is updated in to database. 345 * 346 * @throws \Scrivo\ApplicationException If one or more of the fields 347 * contain invalid data. 348 */ 349 public function update() { 350 try { 351 $this->validateUpdate(); 352 353 $isParentWritable = false; 354 if ($this->parentId) { 355 try { 356 $this->context->checkPermission( 357 \Scrivo\AccessController::WRITE_ACCESS, 358 $this->parentId); 359 $isParentWritable = true; 360 } catch (\Scrivo\ApplicationException $e) {} 361 } 362 363 $sth = $this->context->connection->prepare( 364 "UPDATE asset SET 365 parent_id = :parentId, type = 1, size = :size, 366 date_online = :dateOnline, date_offline = :dateOffline, 367 date_modified = now(), title = :title, location = :location, 368 mime_type = :mimeType 369 WHERE instance_id = :instId AND asset_id = :id"); 370 371 $this->context->connection->bindInstance($sth); 372 $sth->bindValue(":id", $this->id, \PDO::PARAM_INT); 373 374 $sth->bindValue(":parentId", $this->parentId, \PDO::PARAM_INT); 375 $sth->bindValue(":size", $this->size, \PDO::PARAM_INT); 376 $sth->bindValue(":dateOnline", 377 $this->dateOnline->format("Y-m-d H:i:s"), \PDO::PARAM_STR); 378 $sth->bindValue(":dateOffline", $this->dateOffline 379 ? $this->dateOffline->format("Y-m-d H:i:s") 380 : null, \PDO::PARAM_STR); 381 $sth->bindValue(":title", $this->title, \PDO::PARAM_STR); 382 $sth->bindValue(":location", $this->location, \PDO::PARAM_STR); 383 $sth->bindValue(":mimeType", $this->mimeType, \PDO::PARAM_STR); 384 385 $sth->execute(); 386 387 unset($this->context->cache[$this->id]); 388 unset($this->context->cache[$this->parentId]); 389 390 } catch(\PDOException $e) { 391 throw new \Scrivo\ResourceException($e); 392 } 393 } 394 395 /** 396 * Check if deletion of asset object data does not violate any 397 * business rules. 398 * 399 * @param \Scrivo\Context $context A Scrivo context. 400 * @param int $id The object id of the asset definition to select. 401 * 402 * @throws \Scrivo\ApplicationException If the data is not accessible or 403 * if it is not possible to delete the language data. 404 */ 405 protected static function validateDelete(\Scrivo\Context $context, $id) { 406 407 $context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS, $id); 408 409 // Is it a labeled asset? 410 $sth = $context->connection->prepare( 411 "SELECT COUNT(*) FROM id_label 412 WHERE instance_id = :instId AND id = :id"); 413 414 $context->connection->bindInstance($sth); 415 $sth->bindValue(":id", $id, \PDO::PARAM_INT); 416 417 $sth->execute(); 418 419 if ($sth->fetchColumn(0) > 0) { 420 throw new \Scrivo\ApplicationException( 421 "Trying to delete a labelled asset"); 422 } 423 424 } 425 426 } 427 428 ?>
Documentation generated by phpDocumentor 2.0.0a12 and ScrivoDocumentor on August 29, 2013