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: PagePropertyDefinition.php 866 2013-08-25 16:22:35Z geert $
 30   */
 31  
 32  /**
 33   * Implementation of the \Scrivo\PagePropertyDefinition class.
 34   */
 35  
 36  namespace Scrivo;
 37  
 38  /**
 39   * The PagePropertyDefinition is used to create definions for page properties.
 40   *
 41   * Page properties are page objects (text blocks, images, urls, colors, etc)
 42   * that can be edited using the Scrivo user interface. A page property
 43   * definition holds the definition of a page property.
 44   *
 45   * TODO: full tab html text entry properties still store their data into the
 46   * etPageDefinition_ELEMENT table.
 47   *
 48   * @property-read int $id The page property definition id (DB key).
 49   * @property \Scrivo\String $phpSelector A textual identification/key for this
 50   *    page property.
 51   * @property int $pageDefinitionId The id of the page definition to which this
 52   *    page property definition belongs.
 53   * @property int $pageDefinitionTabId An optional id of a page definition tab
 54   *    on which the page property is displayed.
 55   * @property \Scrivo\String $title A descriptive name for the page property.
 56   * @property \Scrivo\String $type The page property type, one out of
 57   *    PagePropertyDefinition::TYPE_* constants.
 58   * @property \stdClass $typeData Optional data needed to for this specific
 59   *    page property.
 60   */
 61  class PagePropertyDefinition {
 62  
 63      /**
 64       * Value indicating an img property.
 65       */
 66      const TYPE_IMAGE "img";
 67  
 68      /**
 69       * Value indicating an input field property.
 70       */
 71      const TYPE_INPUT "input";
 72  
 73      /**
 74       * Value indicating a select list property.
 75       */
 76      const TYPE_SELECT "select";
 77  
 78      /**
 79       * Value indicating a color select list property.
 80       */
 81      const TYPE_COLOR_LIST "colorlist";
 82  
 83      /**
 84       * Value indicating a color property.
 85       */
 86      const TYPE_COLOR "color";
 87  
 88      /**
 89       * Value indicating a datetime property.
 90       */
 91      const TYPE_DATE_TIME "datetime";
 92  
 93      /**
 94       * Value indicating a url property.
 95       */
 96      const TYPE_URL "url";
 97  
 98      /**
 99       * Value indicating a checkbox property.
100       */
101      const TYPE_CHECKBOX "checkbox";
102  
103      /**
104       * Value indicating a html textarea property.
105       */
106      const TYPE_HTML_TEXT "html_text";
107  
108      /**
109       * Value indicating a single large html textarea on a tab.
110       */
111      const TYPE_HTML_TEXT_TAB "html_text_tab";
112  
113      /**
114       * Value indicating there's an application the tab.
115       */
116      const TYPE_APPLICATION_TAB "application_tab";
117  
118      /**
119       * Value indicating a textarea property.
120       */
121      const TYPE_TEXT "text";
122  
123      /**
124       * The page property definition id (DB key).
125       * @var int
126       */
127      private $id 0;
128  
129      /**
130       * The id of the pageDefinition to which this page property definition
131       * belongs.
132       * @var int
133       */
134      private $pageDefinitionId 0;
135  
136      /**
137       * A descriptive name for the page property.
138       * @var \Scrivo\String
139       */
140      private $title null;
141  
142      /**
143       * A textual identification/key for this page property.
144       * @var \Scrivo\String
145       */
146      private $phpSelector null;
147  
148      /**
149       * The page property type, one out of PagePropertyDefinition::TYPE_*
150       * constants.
151       * @var \Scrivo\String
152       */
153      private $type "";
154  
155      /**
156       * Optional data needed to for this specific page property.
157       * @var \stdClass
158       */
159      private $typeData null;
160  
161      /**
162       * An optional id of a pageDefinition tab on which the page property is
163       * displayed.
164       * @var int
165       */
166      private $pageDefinitionTabId 0;
167  
168      /**
169       * A Scrivo context.
170       * @var \Scrivo\Context
171       */
172      private $context null;
173  
174      /**
175       * A flag to indicate a resquence on update
176       * @var boolean
177       */
178      private $resequence false;
179  
180      /**
181       * Create an empty page property defintion object.
182       *
183       * @param \Scrivo\Context $context A Scrivo context.
184       */
185      public function __construct(\Scrivo\Context $context=null) {
186          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(null), 0);
187  
188          if ($context) {
189              $this->title = new \Scrivo\String();
190              $this->phpSelector = new \Scrivo\String();
191              $this->typeData = new \stdClass;
192  
193              $this->context $context;
194          }
195      }
196  
197      /**
198       * Implementation of the readable properties using the PHP magic
199       * method __get().
200       *
201       * @param string $name The name of the property to get.
202       *
203       * @return mixed The value of the requested property.
204       */
205      public function __get($name) {
206          switch($name) {
207              case "id": return $this->id;
208              case "pageDefinitionId": return $this->pageDefinitionId;
209              case "title": return $this->title;
210              case "phpSelector": return $this->phpSelector;
211              case "type": return $this->type;
212              case "typeData": return $this->typeData;
213              case "pageDefinitionTabId": return $this->pageDefinitionTabId;
214          }
215          throw new \Scrivo\SystemException("No such get-property '$name'.");
216      }
217  
218      /**
219       * Implementation of the writable properties using the PHP magic
220       * method __set().
221       *
222       * @param string $name The name of the property to set.
223       * @param mixed $value The value of the property to set.
224       */
225      public function __set($name$value) {
226          switch($name) {
227              case "pageDefinitionId"$this->setPageDefinitionId($value); return;
228              case "title"$this->setTitle($value); return;
229              case "phpSelector"$this->setPhpSelector($value); return;
230              case "type"$this->setType($value); return;
231              case "typeData"$this->setTypeData($value); return;
232              case "pageDefinitionTabId":
233                  $this->setPageDefinitionTabId($value); return;
234          }
235          throw new \Scrivo\SystemException("No such set-property '$name'.");
236      }
237  
238      /**
239       * Convenience method to set the fields of a page property defintion
240       * object from an array (result set row).
241       *
242       * @param \Scrivo\Context $context A Scrivo context.
243       * @param array $rd An array containing the field data using the database
244       *    field names as keys.
245       */
246      private function setFields(\Scrivo\Context $context, array $rd) {
247  
248          $this->id intval($rd["page_property_definition_id"]);
249          $this->pageDefinitionId intval($rd["page_definition_id"]);
250          $this->title = new \Scrivo\String($rd["title"]);
251          $this->phpSelector = new \Scrivo\String($rd["php_key"]);
252          $this->type = (string)$rd["type"];
253          $this->setTypeDataFromRS($rd);
254          $this->pageDefinitionTabId intval($rd["page_definition_tab_id"]);
255  
256          $this->context $context;
257      }
258  
259      /**
260       * Get an array of the possible property types.
261       *
262       * @return \Scrivo\String[] An array of all possible property types.
263       */
264      public static function getTypes() {
265          return array(
266              self::TYPE_IMAGE,
267              self::TYPE_INPUT,
268              self::TYPE_SELECT,
269              self::TYPE_COLOR_LIST,
270              self::TYPE_COLOR,
271              self::TYPE_DATE_TIME,
272              self::TYPE_URL,
273              self::TYPE_CHECKBOX,
274              self::TYPE_HTML_TEXT,
275              self::TYPE_HTML_TEXT_TAB,
276              self::TYPE_APPLICATION_TAB,
277              self::TYPE_TEXT
278          );
279      }
280  
281      /**
282       * Set the id of the page definition to which this page property definition
283       * belongs.
284       *
285       * @param int $pageDefinitionId The id of the page definition to which this
286       *    page property definition belongs.
287       */
288      private function setPageDefinitionId($pageDefinitionId) {
289          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
290              array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
291          ));
292  
293          $this->pageDefinitionId $pageDefinitionId;
294      }
295  
296      /**
297       * Set the descriptive name for the page property.
298       *
299       * @param \Scrivo\String $title A descriptive name for the page property.
300       */
301      private function setTitle(\Scrivo\String $title) {
302          $this->title $title;
303      }
304  
305      /**
306       * Set the textual identification/key for this page property.
307       *
308       * @param \Scrivo\String $phpSelector A textual identification/key for
309       *    this page property.
310       */
311      private function setPhpSelector(\Scrivo\String $phpSelector) {
312          $this->phpSelector $phpSelector;
313      }
314  
315      /**
316       * Set the page property type, one out of the
317       * \Scrivo\PagePropertyDefinition::TYPE_* constants.
318       * Note that TYPE_HTML_TEXT_TAB and TYPE_HTML_TEXT_TAB behave differently
319       * than normal properties so type juggling between these and other types
320       * is not allowed.
321       *
322       * @param string $type The property type, one out of the
323       *    \Scrivo\PagePropertyDefinition::TYPE_* constants.
324       */
325      private function setType($type) {
326          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
327              array(\Scrivo\ArgumentCheck::TYPE_STRING$this->getTypes())
328          ));
329  
330          if ($this->type && (
331                  ($this->type === self::TYPE_HTML_TEXT_TAB
332                      && $type !== self::TYPE_HTML_TEXT_TAB) ||
333                  ($this->type === self::TYPE_APPLICATION_TAB
334                      && $type !== self::TYPE_APPLICATION_TAB) ||
335                  (($this->type !== self::TYPE_APPLICATION_TAB
336                      && $this->type !== self::TYPE_HTML_TEXT_TAB) &&
337                  ($type === self::TYPE_APPLICATION_TAB
338                      || $type === self::TYPE_HTML_TEXT_TAB)))) {
339              throw new \Scrivo\SystemException(
340                  "Type change '{$this->type}' to '{$type}' is not supported");
341          }
342          $this->type $type;
343      }
344  
345      /**
346       * Set the data (optional) needed to for this specific page property type.
347       *
348       * @param \stdClass $typeData Optional data needed to for this specific
349       *    page property type.
350       */
351      private function setTypeData(\stdClass $typeData) {
352          $this->typeData $typeData;
353      }
354  
355      /**
356       * Set the id of a page definition tab (optional) on which this page
357       * property is displayed.
358       * Note that TYPE_HTML_TEXT_TAB and TYPE_HTML_TEXT_TAB types have their
359       * own exclusive tabs and setting their tab is therefore prohibited.
360       *
361       * @param int $pageDefinitionTabId An optional id of a page definition tab
362       *    on which this page property is displayed.
363       */
364      private function setPageDefinitionTabId($pageDefinitionTabId) {
365          if ($this->type == self::TYPE_HTML_TEXT_TAB
366                  || $this->type == self::TYPE_APPLICATION_TAB) {
367              throw new \Scrivo\SystemException(
368                  "cant't set the tab for HTML and Application tabs");
369          }
370          if ($this->id
371                  && ($this->pageDefinitionTabId != $pageDefinitionTabId)) {
372              $this->resequence true;
373          }
374          $this->pageDefinitionTabId $pageDefinitionTabId;
375      }
376  
377      /**
378       * Convert a string to its most likely type.
379       *
380       * @param string $val The value to convert to either an int, float or
381       *    \Scrivo\String.
382       *
383       * @return int|float|\Scrivo\String The given value converted to its
384       *    most likely type.
385       */
386      private function readStr($val) {
387          $str = (string)$val;
388          if (is_numeric($str)) {
389              if ((string)$str === (string)(int)$str) {
390                  return intval($str);
391              }
392              return floatval($str);
393          }
394          return $val;
395      }
396  
397      /**
398       * Convert plain text type data to an object.
399       *
400       * @param array $rs The type data as stored in the database.
401       */
402      private function setTypeDataFromRS($rs) {
403          $d = array();
404  
405          if ($rs["type"] == self::TYPE_HTML_TEXT_TAB) {
406              $d["css_selector"] = new \Scrivo\String($rs["css_selector"]);
407              $d["INITIAL_CONTENT"] = new \Scrivo\String("");
408              $d["page_css"] = new \Scrivo\String($rs["page_css"]);
409              $d["stylesheet"] = new \Scrivo\String($rs["stylesheet"]);
410              $d["css_id"] = new \Scrivo\String($rs["css_id"]);
411              $this->typeData = (object)$d;
412          } else if ($rs["type"] == self::TYPE_APPLICATION_TAB) {
413              $d["APPLICATION_DEFINITION_ID"] = intval($rs["application_definition_id"]);
414              $this->typeData = (object)$d;
415          } else {
416              $this->setTypeDataAsString(new \Scrivo\String($rs["type_data"]));
417          }
418      }
419  
420      /**
421       * Create a string representation of the type data member.
422       *
423       * @return \Scrivo\String The type data as an string.
424       */
425      private function getTypeDataAsString() {
426          $d = array();
427          foreach($this->typeData as $k=>$v) {
428              $d[] = $k."=".$v;
429          };
430          return new \Scrivo\String(implode("\n"$d));
431      }
432  
433      /**
434       * Set the type data member form a string representation. The format of
435       * the string should be NAME1=VALUE1\nNAME2=VALUE2\nNAME3...etc.
436       *
437       * @param \Scrivo\String $str The type data string.
438       */
439      private function setTypeDataAsString(\Scrivo\String $str) {
440          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
441              null,
442              array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
443          ), 1);
444  
445          $d = array();
446          $parts $str->split(new \Scrivo\String("\n"));
447          foreach($parts as $line) {
448              $p $line->split(new \Scrivo\String("="), 2);
449              if (count($p) == 2) {
450                  $d[(string)$p[0]->trim()] = $this->readStr($p[1]->trim());
451              }
452          }
453          $this->typeData = (object)$d;
454      }
455  
456      /**
457       * Check if the current php selector is unique.
458       *
459       * @throws ApplicationException If one or more of the fields contain
460       *   invalid data.
461       */
462      private function checkUniquePhpSelector() {
463  
464          $sth $this->context->connection->prepare(
465                  "SELECT COUNT(*) FROM page_property_definition WHERE
466                  instance_id = :instId AND page_property_definition_id <> :id AND
467                  page_definition_id = :templId AND php_key = :phpSelector");
468  
469          $this->context->connection->bindInstance($sth);
470          $sth->bindValue(":id"$this->id, \PDO::PARAM_INT);
471          $sth->bindValue(":templId"$this->pageDefinitionId, \PDO::PARAM_INT);
472          $sth->bindValue(":phpSelector"$this->phpSelector, \PDO::PARAM_STR);
473  
474          $sth->execute();
475  
476          if ($sth->fetchColumn()) {
477              throw new ApplicationException("PHP Selector not unique");
478          }
479      }
480  
481      /**
482       * Check if this page property defintion object can be inserted into the
483       * database.
484       *
485       * @throws \Scrivo\ApplicationException If the data is not accessible or
486       *   one or more of the fields contain invalid data.
487       */
488      private function validateInsert() {
489          $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
490          $this->checkUniquePhpSelector();
491      }
492  
493      /**
494       * Insert new page property defintion object data into the database.
495       *
496       * First it is checked if the data of this page property defintion object
497       * can be inserted into the database, then the data is inserted into the
498       * database. If no id was set a new object id is generated.
499       *
500       * @throws \Scrivo\ApplicationException If the data is not accessible or
501       *   one or more of the fields contain invalid data.
502       */
503      public function insert() {
504          try {
505              $this->validateInsert();
506  
507              if ($this->type == self::TYPE_HTML_TEXT_TAB
508                      || $this->type == self::TYPE_APPLICATION_TAB) {
509  
510                  if (!$this->pageDefinitionTabId) {
511                      $tab = new \Scrivo\PageDefinitionTab($this->context);
512                      $tab->pageDefinitionId $this->pageDefinitionId;
513                      $tab->title $this->title;
514                      $tab->insert();
515                      $this->pageDefinitionTabId $tab->id;
516                  }
517                  $this->id $this->pageDefinitionTabId;
518                  if ($this->type == self::TYPE_HTML_TEXT_TAB) {
519                      $this->updateHtmlTextTab();
520                  } else {
521                      $this->updateApplicationTab();
522                  }
523  
524              } else {
525  
526                  if (!$this->id) {
527                      $this->id $this->context->connection->generateId();
528                  }
529  
530                  $sth $this->context->connection->prepare(
531                      "INSERT INTO page_property_definition (
532                          instance_id, page_property_definition_id, page_definition_id, sequence_no,
533                          title, php_key, type, type_data, page_definition_tab_id
534                      ) VALUES (
535                          :instId, :id, :pageDefinitionId, 0, :title,
536                          :phpSelector, :type, :typeData, :pageDefinitionTabId
537                      )");
538  
539                  $this->context->connection->bindInstance($sth);
540                  $sth->bindValue(":id"$this->id, \PDO::PARAM_INT);
541                  $sth->bindValue(":pageDefinitionId",
542                      $this->pageDefinitionId, \PDO::PARAM_INT);
543                  $sth->bindValue(":title"$this->title, \PDO::PARAM_STR);
544                  $sth->bindValue(
545                      ":phpSelector"$this->phpSelector, \PDO::PARAM_STR);
546                  $sth->bindValue(":type"$this->type, \PDO::PARAM_STR);
547                  $sth->bindValue(
548                      ":typeData"$this->getTypeDataAsString(), \PDO::PARAM_STR);
549                  $sth->bindValue(":pageDefinitionTabId",
550                      $this->pageDefinitionTabId, \PDO::PARAM_INT);
551  
552                  $sth->execute();
553  
554                  \Scrivo\SequenceNo::position($this->context"page_property_definition",
555                      "page_definition_tab_id"$this->id, \Scrivo\SequenceNo::MOVE_LAST);
556              }
557  
558          } catch(\PDOException $e) {
559              throw new \Scrivo\ResourceException($e);
560          }
561      }
562  
563      /**
564       * Check if this page property defintion object can be updated in the
565       * database.
566       *
567       * @throws \Scrivo\ApplicationException If the data is not accessible or
568       *   one or more of the fields contain invalid data.
569       */
570      private function validateUpdate() {
571          $this->context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
572          $this->checkUniquePhpSelector();
573      }
574  
575      /**
576       * Update existing page property defintion object data in the database.
577       *
578       * First it is checked if the data of this page property defintion object
579       * can be updated in the database, then the data is updated in the database.
580       *
581       * @throws \Scrivo\ApplicationException If the data is not accessible or
582       *   one or more of the fields contain invalid data.
583       */
584      public function update() {
585          try {
586              $this->validateUpdate();
587  
588              if ($this->type == self::TYPE_HTML_TEXT_TAB) {
589  
590                  $this->updateHtmlTextTab();
591  
592              } else if ($this->type == self::TYPE_APPLICATION_TAB) {
593  
594                  $this->updateApplicationTab();
595  
596              } else {
597  
598                  $sth $this->context->connection->prepare(
599                      "UPDATE page_property_definition SET
600                          page_definition_id = :pageDefinitionId,
601                          title = :title,
602                          php_key = :phpSelector, type = :type,
603                          type_data = :typeData, page_definition_tab_id = :pageDefinitionTabId
604                      WHERE instance_id = :instId AND page_property_definition_id = :id");
605  
606                  $this->context->connection->bindInstance($sth);
607                  $sth->bindValue(":id"$this->id, \PDO::PARAM_INT);
608  
609                  $sth->bindValue(":pageDefinitionId",
610                      $this->pageDefinitionId, \PDO::PARAM_INT);
611                  $sth->bindValue(":title"$this->title, \PDO::PARAM_STR);
612                  $sth->bindValue(
613                      ":phpSelector"$this->phpSelector, \PDO::PARAM_STR);
614                  $sth->bindValue(":type"$this->type, \PDO::PARAM_STR);
615                  $sth->bindValue(
616                      ":typeData"$this->getTypeDataAsString(), \PDO::PARAM_STR);
617                  $sth->bindValue(":pageDefinitionTabId",
618                      $this->pageDefinitionTabId, \PDO::PARAM_INT);
619  
620                  $sth->execute();
621  
622                  // If marked (i.e. moved to other tab) move this property last.
623                  if ($this->resequence) {
624                      \Scrivo\SequenceNo::position($this->context,
625                          "page_property_definition""page_definition_tab_id"$this->id,
626                          \Scrivo\SequenceNo::MOVE_LAST);
627                      $this->resequence false;
628                  }
629  
630                  unset($this->context->cache[$this->id]);
631              }
632  
633          } catch(\PDOException $e) {
634              throw new \Scrivo\ResourceException($e);
635          }
636      }
637  
638      /**
639       * Set page property definition data for html text tab definitions in the
640       * page_definition_tab table.
641       */
642      private function updateHtmlTextTab() {
643  
644          $sth $this->context->connection->prepare(
645              "UPDATE page_definition_tab SET page_definition_id = :pageDefinitionId,
646                  php_key = :phpSelector, css_selector = :ccsSelector,
647                  page_css = :documentCss, stylesheet = :stylesheet,
648                  css_id = :cssId, application_definition_id = 0
649              WHERE instance_id = :instId AND page_definition_tab_id = :id");
650  
651          $this->context->connection->bindInstance($sth);
652          $sth->bindValue(":id"$this->id, \PDO::PARAM_INT);
653  
654          $sth->bindValue(
655              ":pageDefinitionId"$this->pageDefinitionId, \PDO::PARAM_INT);
656          $sth->bindValue(
657              ":phpSelector"$this->phpSelector, \PDO::PARAM_STR);
658          $sth->bindValue(
659              ":ccsSelector"$this->typeData->css_selector, \PDO::PARAM_STR);
660          $sth->bindValue(
661              ":documentCss"$this->typeData->page_css, \PDO::PARAM_STR);
662          $sth->bindValue(
663              ":stylesheet"$this->typeData->stylesheet, \PDO::PARAM_STR);
664          $sth->bindValue(
665              ":cssId"$this->typeData->css_id, \PDO::PARAM_STR);
666  
667          $sth->execute();
668      }
669  
670      /**
671       * Set page property definition data for application definitions in the
672       * page_definition_tab table.
673       */
674      private function updateApplicationTab() {
675  
676          $sth $this->context->connection->prepare(
677              "UPDATE page_definition_tab SET page_definition_id = :pageDefinitionId,
678                  php_key = :phpSelector, application_definition_id = :appId
679              WHERE instance_id = :instId AND page_definition_tab_id = :id");
680  
681          $this->context->connection->bindInstance($sth);
682          $sth->bindValue(":id"$this->id, \PDO::PARAM_INT);
683  
684          $sth->bindValue(
685              ":pageDefinitionId"$this->pageDefinitionId, \PDO::PARAM_INT);
686          $sth->bindValue(
687              ":phpSelector"$this->phpSelector, \PDO::PARAM_STR);
688          $sth->bindValue(":appId",
689              $this->typeData->APPLICATION_DEFINITION_ID, \PDO::PARAM_INT);
690  
691          $sth->execute();
692  
693      }
694  
695      /**
696       * Check if deletion of page property defintion object data does not
697       * violate any business rules.
698       *
699       * @param \Scrivo\Context $context A Scrivo context.
700       * @param int $id The object id of the page property defintion to select.
701       *
702       * @throws \Scrivo\ApplicationException If the data is not accessible or
703       *   if it is not possible to delete the language data.
704       */
705      private static function validateDelete(\Scrivo\Context $context$id) {
706          $context->checkPermission(\Scrivo\AccessController::WRITE_ACCESS);
707      }
708  
709      /**
710       * Delete existing page property defintion data from the database.
711       *
712       * First it is is checked if it's possible to delete page property
713       * defintion data, then the page property defintion data including its
714       * dependecies is deleted from the database.
715       *
716       * @param \Scrivo\Context $context A Scrivo context.
717       * @param int $id The object id of the page property defintion to select.
718       *
719       * @throws \Scrivo\ApplicationException If the data is not accessible or
720       *   if it is not possible to delete the page property defintion data.
721       */
722      public static function delete(\Scrivo\Context $context$id) {
723          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
724              null,
725              array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
726          ));
727          try {
728              self::validateDelete($context$id);
729  
730              $tmp self::fetch($context$id);
731  
732              if ($tmp->type != self::TYPE_HTML_TEXT_TAB &&
733                      $tmp->type != self::TYPE_APPLICATION_TAB) {
734  
735                  $sth $context->connection->prepare(
736                      "DELETE FROM page_property_definition
737                      WHERE instance_id = :instId AND page_property_definition_id = :id");
738  
739                  $context->connection->bindInstance($sth);
740                  $sth->bindValue(":id"$id, \PDO::PARAM_INT);
741  
742                  $sth->execute();
743  
744              } else {
745  
746                  \Scrivo\PageDefinitionTab::delete($context$id);
747  
748              }
749  
750          } catch(\PDOException $e) {
751              throw new \Scrivo\ResourceException($e);
752          }
753      }
754  
755      /**
756       * Move a property one position up or down.
757       *
758       * @param int $dir Direction of the move, see \Scrivo\SequenceNo:::MOVE_*
759       */
760      public function move($dir=\Scrivo\SequenceNo::MOVE_DOWN) {
761          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
762              array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
763          ), 0);
764  
765          $this->context->checkPermission(AccessController::WRITE_ACCESS);
766  
767          \Scrivo\SequenceNo::position($this->context"page_property_definition",
768              "page_definition_tab_id"$this->id$dir);
769      }
770  
771      /**
772       * Fetch a page property defintion object from the database using its
773       * object id.
774       *
775       * @param \Scrivo\Context $context A Scrivo context.
776       * @param int $id The object id of the page property defintion to select.
777       *
778       * @return \Scrivo\PagePropertyDefinition The requested page property
779       *    defintion object.
780       */
781      public static function fetch(\Scrivo\Context $context$id) {
782          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
783              null,
784              array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
785          ));
786          try {
787              // Try to retieve the page property defintion from the cache ...
788              if (isset($context->cache[$id])) {
789                  // ... get it from the cache and set the context.
790                  $pagePropertyDefinition $context->cache[$id];
791                  $pagePropertyDefinition->context $context;
792              } else {
793                  // ... else retrieve it and set it in the cache.
794                  $sth $context->connection->prepare(
795                      "SELECT page_property_definition_id, page_definition_id, sequence_no,
796                          title, php_key, type, type_data, page_definition_tab_id,
797                          '' css_selector, '' page_css, '' stylesheet,
798                          '' css_id, 0 application_definition_id
799                      FROM page_property_definition
800                      WHERE instance_id = :instId AND page_property_definition_id = :id
801                      UNION SELECT
802                          page_definition_tab_id page_property_definition_id,
803                          page_definition_id, sequence_no, title title, php_key,
804                          IF(application_definition_id > 0, :appTab, :htmlTab)
805                          type, '' type_data, page_definition_tab_id page_definition_tab_id,
806                          css_selector, page_css,    stylesheet, css_id,
807                          application_definition_id
808                      FROM page_definition_tab
809                      WHERE instance_id = :instId AND page_definition_tab_id = :id"
810                  );
811  
812                  $context->connection->bindInstance($sth);
813                  $sth->bindValue(":id"$id, \PDO::PARAM_INT);
814                  $sth->bindValue(
815                      ":appTab"self::TYPE_APPLICATION_TAB, \PDO::PARAM_STR);
816                  $sth->bindValue(
817                      ":htmlTab"self::TYPE_HTML_TEXT_TAB, \PDO::PARAM_STR);
818  
819                  $sth->execute();
820  
821                  if ($sth->rowCount() != 1) {
822                      throw new \Scrivo\SystemException(
823                          "Failed to load page definition property");
824                  }
825  
826                  $pagePropertyDefinition =
827                      new \Scrivo\PagePropertyDefinition();
828                  $pagePropertyDefinition->setFields(
829                      $context$sth->fetch(\PDO::FETCH_ASSOC));
830  
831                  $context->cache[$id] = $pagePropertyDefinition;
832              }
833  
834              return $pagePropertyDefinition;
835  
836          } catch(\PDOException $e) {
837              throw new \Scrivo\ResourceException($e);
838          }
839      }
840  
841      /**
842       * Select page property defintions from the database.
843       *
844       * @param \Scrivo\Context $context A Scrivo context.
845       * @param int $pageDefinitionId An id of a page definition for which to
846       *    select its properties.
847       *
848       * @return \Scrivo\PagePropertyDefinition[id] An array containing the
849       *    selected page property defintions.
850       */
851      public static function select(\Scrivo\Context $context$pageDefinitionId) {
852          \Scrivo\ArgumentCheck::assertArgs(func_get_args(), array(
853              null,
854              array(\Scrivo\ArgumentCheck::TYPE_INTEGER)
855          ));
856          try {
857              $sth $context->connection->prepare(
858                  "SELECT * FROM (
859                  SELECT page_property_definition_id, page_definition_id, sequence_no, title,
860                      php_key, type, type_data, page_definition_tab_id, '' css_selector,
861                      '' page_css, '' stylesheet, '' css_id, 0 application_definition_id
862                  FROM page_property_definition
863                  WHERE instance_id = :instId AND page_definition_id = :templId
864                  UNION SELECT
865                      page_definition_tab_id page_property_definition_id,
866                      page_definition_id, sequence_no, title title, php_key,
867                      IF(application_definition_id > 0, :appTab, :htmlTab)
868                      type, '' type_data, page_definition_tab_id page_definition_tab_id,
869                      css_selector, page_css,    stylesheet, css_id,
870                      application_definition_id
871                  FROM page_definition_tab
872                  WHERE instance_id = :instId AND application_definition_id >= 0
873                      AND page_definition_id = :templId
874                  ) TMP ORDER BY page_definition_tab_id, sequence_no");
875  
876              $context->connection->bindInstance($sth);
877              $sth->bindValue(":templId"$pageDefinitionId, \PDO::PARAM_INT);
878              $sth->bindValue(
879                  ":appTab"self::TYPE_APPLICATION_TAB, \PDO::PARAM_STR);
880              $sth->bindValue(
881                  ":htmlTab"self::TYPE_HTML_TEXT_TAB, \PDO::PARAM_STR);
882  
883              $sth->execute();
884  
885              $res = array();
886  
887              while ($rd $sth->fetch(\PDO::FETCH_ASSOC)) {
888  
889                  $li = new PagePropertyDefinition();
890                  $li->setFields($context$rd);
891  
892                  $res[$li->id] = $li;
893              }
894  
895              return $res;
896  
897          } catch(\PDOException $e) {
898              throw new \Scrivo\ResourceException($e);
899          }
900      }
901  
902  }
903  
904  ?>

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