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: ApplicationDefinition.php 866 2013-08-25 16:22:35Z geert $
 30   */
 31  
 32  /**
 33   * Implementation of the \Scrivo\ApplicationDefinition class.
 34   */
 35  
 36  namespace Scrivo;
 37  
 38  /**
 39   * The ApplicationDefinition class is used to create references to applications.
 40   *
 41   * Scrivo applications are (small) specialized web applications that are hosted
 42   * on a tab in the user interface. These can be internal applications such
 43   * as list or form, or any custom made web application.
 44   *
 45   * The application definition class holds the entry point (an url to display
 46   * in an iframe or a Javascript class constructor) for the application.
 47   *
 48   * @property-read int $id The application definition id (DB key)
 49   * @property \Scrivo\String $description An additional description for the
 50   *    application.
 51   * @property \Scrivo\String $location The location of the application start
 52   *    page.
 53   * @property \Scrivo\String $title A descriptive title for the application.
 54   * @property int $type The application type: one out of the
 55   *    ApplicationDefinition::TYPE_* constants.
 56   */
 57  class ApplicationDefinition {
 58  
 59  
 60      /**
 61       * Constant to denote an external (custom) application.
 62       */
 63      const TYPE_URL 1;
 64  
 65      /**
 66       * Constant to denote a news-like list application (manually sortable).
 67       */
 68      const TYPE_LIST 2;
 69  
 70      /**
 71       * Constant to denote a column list application with sort option on headers.
 72       */
 73      const TYPE_LISTVIEW 3;
 74  
 75      /**
 76       * Constant to denote a from application.
 77       */
 78      const TYPE_FORM 4;
 79  
 80      /**
 81       * Constant to denote distributed list.
 82       */
 83      const TYPE_DISTRIBUTED_LIST 5;
 84  
 85      /**
 86       * The application definition id (DB key)
 87       * @var int
 88       */
 89      private $id 0;
 90  
 91      /**
 92       * A descriptive title for the application.
 93       * @var \Scrivo\String
 94       */
 95      private $title null;
 96  
 97      /**
 98       * An additional description for the application.
 99       * @var \Scrivo\String
100       */
101      private $description null;
102  
103      /**
104       * The location of the application start page.
105       * @var \Scrivo\String
106       */
107      private $location null;
108  
109      /**
110       * The application type: one out of the
111       * ApplicationDefinition::TYPE_* constants.
112       * @var int
113       */
114      private $type self::TYPE_URL;
115  
116      /**
117       * A Scrivo context.
118       * @var \Scrivo\Context
119       */
120      private $context null;
121  
122      /**
123       * Create an empty application definition object.
124       *
125       * @param \Scrivo\Context $context A Scrivo context.
126       */
127      public function __construct(\Scrivo\Context $context=null) {
128          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null), 0);
129  
130          if ($context) {
131              $this->title = new \Scrivo\String();
132              $this->description = new \Scrivo\String();
133              $this->location = new \Scrivo\String();
134  
135              $this->context $context;
136          }
137      }
138  
139      /**
140       * Implementation of the readable properties using the PHP magic
141       * method __get().
142       *
143       * @param string $name The name of the property to get.
144       *
145       * @return mixed The value of the requested property.
146       */
147      public function __get($name) {
148          switch($name) {
149              case "id": return $this->id;
150              case "title": return $this->title;
151              case "description": return $this->description;
152              case "location": return $this->location;
153              case "type": return $this->type;
154          }
155          throw new \Scrivo\SystemException("No such get-property '$name'.");
156      }
157  
158      /**
159       * Implementation of the writable properties using the PHP magic
160       * method __set().
161       *
162       * @param string $name The name of the property to set.
163       * @param mixed $value The value of the property to set.
164       */
165      public function __set($name$value) {
166          switch($name) {
167              case "title"$this->setTitle($value); return;
168              case "description"$this->setDescription($value); return;
169              case "location"$this->setLocation($value); return;
170              case "type"$this->setType($value); return;
171          }
172          throw new \Scrivo\SystemException("No such set-property '$name'.");
173      }
174  
175      /**
176       * Convenience method to set the fields of a application definition object
177       * from an array (result set row).
178       *
179       * @param \Scrivo\Context $context A Scrivo context.
180       * @param array $rd An array containing the field data using the database
181       *    field names as keys.
182       */
183      private function setFields(\Scrivo\Context $context, array $rd) {
184  
185          $this->id intval($rd["application_definition_id"]);
186          $this->title = new \Scrivo\String($rd["title"]);
187          $this->description = new \Scrivo\String($rd["description"]);
188          $this->location = new \Scrivo\String($rd["action"]);
189          $this->type intval($rd["type"]);
190  
191          $this->context $context;
192      }
193  
194      /**
195       * Set the descriptive title for the application.
196       *
197       * @param \Scrivo\String $title A descriptive title for the application.
198       */
199      private function setTitle(\Scrivo\String $title) {
200          $this->title $title;
201      }
202  
203      /**
204       * Set the additional description for the application.
205       *
206       * @param \Scrivo\String $description An additional description for the
207       *    application.
208       */
209      private function setDescription(\Scrivo\String $description) {
210          $this->description $description;
211      }
212  
213      /**
214       * Set the location of the application start page.
215       *
216       * @param \Scrivo\String $location The location of the application start
217       *    page.
218       */
219      private function setLocation(\Scrivo\String $location) {
220          $this->location $location;
221      }
222  
223      /**
224       * Set the application type: one out of the
225       * ApplicationDefinition::TYPE_* constants.
226       *
227       * @param int $type The application type: one out of the
228       *    ApplicationDefinition::TYPE_* constants.
229       */
230      private function setType($type) {
231          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
232              array(\Scrivo\ArgumentCheck::TYPE_INTEGER, array(
233                  self::TYPE_URLself::TYPE_LISTself::TYPE_LISTVIEW,
234                  self::TYPE_FORMself::TYPE_DISTRIBUTED_LIST))
235          ));
236  
237          $this->type $type;
238      }
239  
240      /**
241       * Check if this application definition object can be inserted into the
242       * database.
243       *
244       * @throws \Scrivo\ApplicationException If the data is not accessible or
245       *   one or more of the fields contain invalid data.
246       */
247      private function validateInsert() {
248          $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
249      }
250  
251      /**
252       * Insert new application definition object data into the database.
253       *
254       * First it is checked if the data of this application definition object
255       * can be inserted into the database, then the data is inserted into the
256       * database. If no id was set a new object id is generated.
257       *
258       * @throws \Scrivo\ApplicationException If the data is not accessible or
259       *   one or more of the fields contain invalid data.
260       */
261      public function insert() {
262          try {
263              $this->validateInsert();
264  
265              if (!$this->id) {
266                  $this->id $this->context->connection->generateId();
267              }
268  
269              $sth $this->context->connection->prepare(
270                  "INSERT INTO application_definition (
271                      instance_id, application_definition_id, title, description, action, type
272                  ) VALUES (
273                      :instId, :id, :title, :description, :location, :type
274                  )");
275  
276              $this->context->connection->bindInstance($sth);
277              $sth->bindValue(":id"$this->id, \PDO::PARAM_INT);
278              $sth->bindValue(":title"$this->title, \PDO::PARAM_STR);
279              $sth->bindValue(
280                  ":description"$this->description, \PDO::PARAM_STR);
281              $sth->bindValue(":location"$this->location, \PDO::PARAM_STR);
282              $sth->bindValue(":type"$this->type, \PDO::PARAM_INT);
283  
284              $sth->execute();
285  
286          } catch(\PDOException $e) {
287              throw new \Scrivo\ResourceException($e);
288          }
289      }
290  
291      /**
292       * Check if this application definition object can be updated in the
293       * database.
294       *
295       * @throws \Scrivo\ApplicationException If the data is not accessible or
296       *   one or more of the fields contain invalid data.
297       */
298      private function validateUpdate() {
299          $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
300      }
301  
302      /**
303       * Update existing application definition object data in the database.
304       *
305       * First it is checked if the data of this application definition object
306       * can be updated in the database, then the data is updated in the database.
307       *
308       * @throws \Scrivo\ApplicationException If the data is not accessible or
309       *   one or more of the fields contain invalid data.
310       */
311      public function update() {
312          try {
313              $this->validateUpdate();
314  
315              $sth $this->context->connection->prepare(
316                  "UPDATE application_definition SET
317                      title = :title, description = :description,
318                      action = :location, type = :type
319                  WHERE instance_id = :instId AND application_definition_id = :id");
320  
321              $this->context->connection->bindInstance($sth);
322              $sth->bindValue(":id"$this->id, \PDO::PARAM_INT);
323  
324              $sth->bindValue(":title"$this->title, \PDO::PARAM_STR);
325              $sth->bindValue(
326                  ":description"$this->description, \PDO::PARAM_STR);
327              $sth->bindValue(":location"$this->location, \PDO::PARAM_STR);
328              $sth->bindValue(":type"$this->type, \PDO::PARAM_INT);
329  
330              $sth->execute();
331  
332              unset($this->context->cache[$this->id]);
333  
334          } catch(\PDOException $e) {
335              throw new \Scrivo\ResourceException($e);
336          }
337      }
338  
339      /**
340       * Check if deletion of application definition object data does not violate
341       * any business rules.
342       *
343       * @param \Scrivo\Context $context A Scrivo context.
344       * @param int $id The object id of the application definition to select.
345       *
346       * @throws \Scrivo\ApplicationException If the data is not accessible or
347       *   if it is not possible to delete the language data.
348       */
349      private static function validateDelete(\Scrivo\Context $context$id) {
350          $context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
351      }
352  
353      /**
354       * Delete existing application definition data from the database.
355       *
356       * First it is is checked if it's possible to delete application
357       * definition data, then the application definition data including
358       * its dependencies is deleted from the database.
359       *
360       * @param \Scrivo\Context $context A Scrivo context.
361       * @param int $id The object id of the application definition to select.
362       *
363       * @throws \Scrivo\ApplicationException If the data is not accessible or
364       *   if it is not possible to delete the application definition data.
365       */
366      public static function delete(\Scrivo\Context $context$id) {
367          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
368              null,
369              array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
370          ));
371          try {
372  
373              self::validateDelete($context$id);
374  
375              $sth $context->connection->prepare(
376                  "DELETE FROM application_definition
377                  WHERE instance_id = :instId AND application_definition_id = :id");
378  
379              $context->connection->bindInstance($sth);
380              $sth->bindValue(":id"$id, \PDO::PARAM_INT);
381  
382              $sth->execute();
383  
384              unset($context->cache[$id]);
385  
386          } catch(\PDOException $e) {
387              throw new \Scrivo\ResourceException($e);
388          }
389      }
390  
391      /**
392       * Fetch a application definition object from the database using its
393       * object id.
394       *
395       * @param \Scrivo\Context $context A Scrivo context.
396       * @param int $id The object id of the application definition to select.
397       *
398       * @return \Scrivo\ApplicationDefinition The requested application
399       *    definition object.
400       */
401      public static function fetch(\Scrivo\Context $context$id) {
402          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
403              null,
404              array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
405          ));
406          try {
407              // Try to retieve the application definition from the cache ...
408              if (isset($context->cache[$id])) {
409                  // ... get it from the cache and set the context.
410                  $applicationDefintition $context->cache[$id];
411                  $applicationDefintition->context $context;
412              } else {
413                  // ... else retrieve it and set it in the cache.
414                  $sth $context->connection->prepare(
415                      "SELECT application_definition_id, title, description, action, type
416                      FROM application_definition
417                      WHERE instance_id = :instId AND application_definition_id = :id");
418  
419                  $context->connection->bindInstance($sth);
420                  $sth->bindValue(":id"$id, \PDO::PARAM_INT);
421  
422                  $sth->execute();
423  
424                  if ($sth->rowCount() != 1) {
425                      throw new \Scrivo\SystemException(
426                          "Failed to load application definition");
427                  }
428  
429                  $applicationDefintition =
430                      new \Scrivo\ApplicationDefinition();
431                  $applicationDefintition->setFields(
432                      $context$sth->fetch(\PDO::FETCH_ASSOC));
433  
434                  $context->cache[$id] = $applicationDefintition;
435              }
436  
437              return $applicationDefintition;
438  
439          } catch(\PDOException $e) {
440              throw new \Scrivo\ResourceException($e);
441          }
442      }
443  
444      /**
445       * Select application definitions from the database.
446       *
447       * @param \Scrivo\Context $context A Scrivo context.
448       *
449       * @return \Scrivo\ApplicationDefinition[id] An array containing the
450       *    selected application definitions.
451       */
452      public static function select(\Scrivo\Context $context) {
453          try {
454              $sth $context->connection->prepare(
455                  "SELECT application_definition_id, title, description, action, type
456                  FROM application_definition
457                  WHERE instance_id = :instId
458                  ORDER BY title");
459  
460              $context->connection->bindInstance($sth);
461  
462              $sth->execute();
463  
464              $res = array();
465  
466              while ($rd $sth->fetch(\PDO::FETCH_ASSOC)) {
467  
468                  $li = new \Scrivo\ApplicationDefinition();
469                  $li->setFields($context$rd);
470  
471                  $res[$li->id] = $li;
472              }
473  
474              return $res;
475  
476          } catch(\PDOException $e) {
477              throw new \Scrivo\ResourceException($e);
478          }
479      }
480  
481  }
482  
483  ?>

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