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: Folder.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 Folder extends Asset {
 41  
 42      /**
 43       * The cache headers settings for the files in this folder.
 44       * @var \Scrivo\String
 45       */
 46      private $cacheHeaderSettings null;
 47  
 48      /**
 49       * Create an empty asset object.
 50       *
 51       * @param \Scrivo\Context $context A Scrivo context.
 52       */
 53      public function __construct(\Scrivo\Context $context=null) {
 54          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null), 0);
 55  
 56          if ($context) {
 57  
 58              parent::__construct($context);
 59  
 60              $this->cacheHeaderSettings = new \Scrivo\String();
 61          }
 62      }
 63  
 64      /**
 65       * Implementation of the readable properties using the PHP magic
 66       * method __get().
 67       *
 68       * @param string $name The name of the property to get.
 69       *
 70       * @return mixed The value of the requested property.
 71       */
 72      public function __get($name) {
 73          switch($name) {
 74              case "cacheHeaderSettings": return $this->getCacheHeaderSettings();
 75          }
 76          return parent::__get($name);
 77      }
 78  
 79      /**
 80       * Implementation of the writable properties using the PHP magic
 81       * method __set().
 82       *
 83       * @param string $name The name of the property to set.
 84       * @param mixed $value The value of the property to set.
 85       */
 86      public function __set($name$value) {
 87          switch($name) {
 88              case "cacheHeaderSettings":
 89                  $this->setCacheHeaderSettings($value); return;
 90          }
 91          parent::__set($name$value);
 92      }
 93  
 94      /**
 95       * Convenience method to set the fields of a asset definition object from
 96       * an array (result set row).
 97       *
 98       * @param \Scrivo\Context $context A Scrivo context.
 99       * @param array $rd An array containing the field data using the database
100       *    field names as keys.
101       */
102      protected function setFields(\Scrivo\Context $context, array $rd) {
103  
104          parent::setFields($context$rd);
105  
106          $this->cacheHeaderSettings = new \Scrivo\String($rd["location"]);
107      }
108  
109      /**
110       * Get the cache header settings.
111       *
112       * @return \stdClass The cache header settings data.
113       */
114      private function getCacheHeaderSettings() {
115          $res = new \stdClass;
116          $res->setting = new \Scrivo\String("last-modified");
117          if ($this->cacheHeaderSettings)
118              if ($this->cacheHeaderSettings->equals(
119                      new \Scrivo\String("NOCACHE"))) {
120              $res->setting = new \Scrivo\String("no-cache");
121          } else if ($this->cacheHeaderSettings->length >= &&
122                  $this->cacheHeaderSettings->substr(0,5)->equals(
123                  new \Scrivo\String("CACHE"))) {
124              $dat $this->cacheHeaderSettings->split(new \Scrivo\String(":"));
125              $res->setting = new \Scrivo\String("expires");
126              $res->timePeriod intval((string)$dat[1]);
127              $res->timeUnit $dat[2];
128          }
129          return $res;
130      }
131  
132      /**
133       * Set the cache header settings.
134       *
135       * @param \stdClass $settingData The cache header settings data.
136       */
137      private function setCacheHeaderSettings(\stdClass $settingData) {
138          if ($settingData->setting->equals(new \Scrivo\String("expires"))) {
139              $this->cacheHeaderSettings = new \Scrivo\String(
140                  "CACHE:{$settingData->timePeriod}:{$settingData->timeUnit}");
141          } else if ($settingData->setting->equals(
142                  new \Scrivo\String("no-cache"))) {
143              $this->cacheHeaderSettings = new \Scrivo\String("NOCACHE");
144          } else {
145              $this->cacheHeaderSettings = new \Scrivo\String("");
146          }
147      }
148  
149      /**
150       * Check if the asset data can be inserted into the database.
151       *
152       * @throws \Scrivo\ApplicationException If the data is not accessible,
153       *   one or more of the fields contain invalid data or some other business
154       *   rule is not met.
155       */
156      private function validateInsert() {
157  
158          if ($this->parentId) {
159  
160              $this->context->checkPermission(
161                  \Scrivo\AccessController::WRITE_ACCESS$this->parentId);
162  
163          } else {
164  
165              // If we're trying to insert a new root, check if there there is
166              // none yet.
167              $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
168  
169              $sth $this->context->connection->prepare(
170                  "SELECT COUNT(*) FROM asset
171                      WHERE instance_id = :instId AND parent_id = 0");
172  
173              $this->context->connection->bindInstance($sth);
174  
175              $sth->execute();
176  
177              if ($sth->fetchColumn(0) > 0) {
178                  throw new \Scrivo\SystemException(
179                      "Trying to create a new root folder");
180              }
181  
182          }
183  
184      }
185  
186      /**
187       * Insert a new asset into the database.
188       *
189       * First the data fields of this asset will be validated. If no id
190       * is set a new object id is generated. Then the data is inserted into to
191       * database.
192       *
193       * @throws \Scrivo\ApplicationException If one or more of the fields
194       *   contain invalid data.
195       */
196      public function insert() {
197          try {
198              $this->validateInsert();
199  
200              if (!$this->id) {
201                  $this->id $this->context->connection->generateId();
202              }
203  
204              $sth $this->context->connection->prepare(
205                  "INSERT INTO asset (
206                      instance_id, asset_id, parent_id, sequence_no,
207                      type, size, date_created, date_modified, date_online, date_offline,
208                      title, location, mime_type
209                  ) VALUES (
210                      :instId, :id, :parentId, 0,
211                      0, 0, now(), now(), now(), null,
212                      :title,    :ch, ''
213                  )");
214  
215              $this->context->connection->bindInstance($sth);
216              $sth->bindValue(":id"$this->id, \PDO::PARAM_INT);
217              $sth->bindValue(":parentId"$this->parentId, \PDO::PARAM_INT);
218              $sth->bindValue(":title"$this->title, \PDO::PARAM_STR);
219              $sth->bindValue(":ch"$this->cacheHeaderSettings, \PDO::PARAM_STR);
220  
221              $sth->execute();
222  
223              ObjectRole::set($this->context$this->id,
224                  ObjectRole::select($this->context$this->parentId));
225  
226              unset($this->context->cache[$this->parentId]);
227  
228          } catch(\PDOException $e) {
229              throw new \Scrivo\ResourceException($e);
230          }
231      }
232  
233      /**
234       * Check if this the asset data can be updated in the database.
235       *
236       * @throws \Scrivo\ApplicationException If the data is not accessible,
237       *   one or more of the fields contain invalid data or some other business
238       *   rule is not met.
239       */
240      private function validateUpdate() {
241  
242          $this->context->checkPermission(
243              \Scrivo\AccessController::WRITE_ACCESS$this->id);
244  
245          try {
246              $newPath self::selectPath($this);
247          } catch (\Scrivo\SystemException $e) {
248              throw new \Scrivo\ApplicationException(
249                  "Can't move a folder underneath itself");
250          }
251  
252      }
253  
254      /**
255       * Update an existing asset in the database.
256       *
257       * First the data fields of this user will be validated, then the data
258       * is updated in to database.
259       *
260       * @throws \Scrivo\ApplicationException If one or more of the fields
261       *   contain invalid data.
262       */
263      public function update() {
264          try {
265              $this->validateUpdate();
266  
267              $isParentWritable false;
268              if ($this->parentId) {
269                  try {
270                      $this->context->checkPermission(
271                          \Scrivo\AccessController::WRITE_ACCESS,
272                          $this->parentId);
273                      $isParentWritable true;
274                  } catch (\Scrivo\ApplicationException $e) {}
275              }
276  
277              $sth $this->context->connection->prepare(
278                  "UPDATE asset SET
279                      parent_id = :parentId, title = :title, location = :ch
280                  WHERE instance_id = :instId AND asset_id = :id");
281  
282              $this->context->connection->bindInstance($sth);
283              $sth->bindValue(":id"$this->id, \PDO::PARAM_INT);
284  
285              $sth->bindValue(":parentId"$this->parentId, \PDO::PARAM_INT);
286              $sth->bindValue(":title"$this->title, \PDO::PARAM_STR);
287              $sth->bindValue(":ch"$this->cacheHeaderSettings, \PDO::PARAM_STR);
288  
289              $sth->execute();
290  
291              unset($this->context->cache[$this->id]);
292              unset($this->context->cache[$this->parentId]);
293  
294          } catch(\PDOException $e) {
295              throw new \Scrivo\ResourceException($e);
296          }
297      }
298  
299      /**
300       * Check if deletion of asset object data does not violate any
301       * business rules.
302       *
303       * @param \Scrivo\Context $context A Scrivo context.
304       * @param int $id The object id of the asset definition to select.
305       *
306       * @throws \Scrivo\ApplicationException If the data is not accessible or
307       *   if it is not possible to delete the language data.
308       */
309      protected static function validateDelete(\Scrivo\Context $context$id) {
310  
311          $context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS$id);
312  
313          // Is it a labeled asset?
314          $sth $context->connection->prepare(
315              "SELECT COUNT(*) FROM id_label
316              WHERE instance_id = :instId AND id = :id");
317  
318          $context->connection->bindInstance($sth);
319          $sth->bindValue(":id"$id, \PDO::PARAM_INT);
320  
321          $sth->execute();
322  
323          if ($sth->fetchColumn(0) > 0) {
324              throw new \Scrivo\ApplicationException(
325                  "Trying to delete a labelled asset");
326          }
327  
328          // Check the child assets.
329          $sth $context->connection->prepare(
330              "SELECT asset_id, type FROM asset WHERE instance_id = :instId
331                  AND parent_id = :id");
332  
333          $context->connection->bindInstance($sth);
334          $sth->bindValue(":id"$id, \PDO::PARAM_INT);
335  
336          $sth->execute();
337  
338          $folders = array();
339          while ($rd $sth->fetch(\PDO::FETCH_ASSOC)) {
340              throw new \Scrivo\ApplicationException(
341                  "Trying to delete an asset with child assets");
342          }
343      }
344  
345  }
346  
347  ?>

Documentation generated by phpDocumentor 2.0.0a12 and ScrivoDocumentor on August 29, 2013