# EntityProto.class.php

Go to the documentation of this file.

    00001 <?php
    00002 /***************************************************************************
    00003  *   Copyright (C) 2007 by Ivan Y. Khvostishkov                            *
    00004  *                                                                         *
    00005  *   This program is free software; you can redistribute it and/or modify  *
    00006  *   it under the terms of the GNU Lesser General Public License as        *
    00007  *   published by the Free Software Foundation; either version 3 of the    *
    00008  *   License, or (at your option) any later version.                       *
    00009  *                                                                         *
    00010  ***************************************************************************/
    00011
    00012     class EntityProto extends Singleton
    00013     {
    00014         const PROTO_CLASS_PREFIX = 'EntityProto';
    00015
    00016         public function baseProto()
    00017         {
    00018             return null;
    00019         }
    00020
    00021         public function className()
    00022         {
    00023             return null;
    00024         }
    00025
    00026         // TODO: think about anonymous primitives and persistant mapping
    00027         // instead of creating new one on each call
    00028         public function getFormMapping()
    00029         {
    00030             return array();
    00031         }
    00032
    00033         // TODO: use checkConstraints($object, $previousObject = null)
    00034         // where object may be business object, form, scope, etc.
    00035         // NOTE: object may contain errors already
    00036         public function checkConstraints(
    00037             $object, Form $form, $previousObject = null
    00038         )
    00039         {
    00040             return $this;
    00041         }
    00042
    00043         public function isAbstract()
    00044         {
    00045             return false;
    00046         }
    00047
    00048         public function isInstanceOf(EntityProto $proto)
    00049         {
    00050             return ClassUtils::isInstanceOf(
    00051                 $this->className(), $proto->className()
    00052             );
    00053         }
    00054
    00055         final public function getFullFormMapping()
    00056         {
    00057             $result = $this->getFormMapping();
    00058
    00059             if ($this->baseProto())
    00060                 $result = $result + $this->baseProto()->getFullFormMapping();
    00061
    00062             return $result;
    00063         }
    00064
    00065         final public function validate(
    00066             $object, $form, $previousObject = null
    00067         )
    00068         {
    00069             if (is_array($object)) {
    00070                 return $this->validateList($object, $form, $previousObject);
    00071             }
    00072
    00073             Assert::isInstance($object, $this->className());
    00074             Assert::isInstance($form, 'Form');
    00075
    00076             if ($previousObject)
    00077                 Assert::isInstance($previousObject, $this->className());
    00078
    00079             if ($this->baseProto())
    00080                 $this->baseProto()->
    00081                     validate($object, $form, $previousObject);
    00082
    00083             return $this->validateSelf($object, $form, $previousObject);
    00084         }
    00085
    00086         final public function validateSelf(
    00087             $object, $form, $previousObject = null
    00088         )
    00089         {
    00090             $this->checkConstraints($object, $form, $previousObject);
    00091
    00092             $getter = new ObjectGetter($this, $object);
    00093
    00094             $previousGetter = $previousObject
    00095                 ? new ObjectGetter($this, $previousObject)
    00096                 : null;
    00097
    00098             foreach ($this->getFormMapping() as $id => $primitive) {
    00099
    00100                 if ($primitive instanceof PrimitiveForm) {
    00101                     $proto = $primitive->getProto();
    00102
    00103                     $childForm = $form->getValue($primitive->getName());
    00104
    00105                     $child = $getter->get($id);
    00106
    00107                     $previousChild = $previousGetter
    00108                         ? $previousGetter->get($id)
    00109                         : null;
    00110
    00111                     $childResult = true;
    00112
    00113                     if (
    00114                         $child
    00115                         && !$proto->validate(
    00116                             $child, $childForm, $previousChild
    00117                         )
    00118                     ) {
    00119                         $form->markWrong($primitive->getName());
    00120                     }
    00121                 }
    00122             }
    00123
    00124             $errors = $form->getErrors();
    00125
    00126             return empty($errors);
    00127         }
    00128
    00129         final public function validateList(
    00130             $objectsList, $formsList, $previousObjectsList = null
    00131         )
    00132         {
    00133             Assert::isEqual(count($objectsList), count($formsList));
    00134
    00135             reset($formsList);
    00136
    00137             if ($previousObjectsList) {
    00138                 Assert::isEqual(
    00139                     count($objectsList), count($previousObjectsList)
    00140                 );
    00141
    00142                 reset($previousObjectsList);
    00143             }
    00144
    00145             $result = true;
    00146
    00147             $previousObject = null;
    00148
    00149             foreach ($objectsList as $object) {
    00150
    00151                 $form = current($formsList);
    00152                 next($formsList);
    00153
    00154                 if ($previousObjectsList) {
    00155                     $previousObject = current($previousObjectsList);
    00156                     next($previousObjectsList);
    00157                 }
    00158
    00159                 if (!$this->validate($object, $form, $previousObject))
    00160                     $result = false;
    00161             }
    00162
    00163             return $result;
    00164         }
    00165
    00166         final public function createObject()
    00167         {
    00168             $className = $this->className();
    00169
    00170             return new $className;
    00171         }
    00172
    00178         final public function makeForm()
    00179         {
    00180             return
    00181                 $this->
    00182                     attachPrimitives(
    00183                         $this->baseProto()
    00184                             ? $this->baseProto()->makeForm()
    00185                             : Form::create()
    00186                     );
    00187         }
    00188
    00192         final public function attachPrimitives(Form $form)
    00193         {
    00194             foreach ($this->getFormMapping() as $primitive)
    00195                 $form->add($primitive);
    00196
    00197             return $form;
    00198         }
    00199
    00200         final public function getOwnPrimitive($name)
    00201         {
    00202             $mapping = $this->getFormMapping();
    00203
    00204             if (!isset($mapping[$name]))
    00205                 throw new WrongArgumentException(
    00206                     "i know nothing about property '$name'"
    00207                 );
    00208
    00209             return $mapping[$name];
    00210         }
    00211
    00212         final public function getPrimitive($name)
    00213         {
    00214             try {
    00215                 $result = $this->getOwnPrimitive($name);
    00216
    00217             } catch (WrongArgumentException $e) {
    00218
    00219                 if (!$this->baseProto())
    00220                     throw $e;
    00221
    00222                 $result = $this->baseProto()->getPrimitive($name);
    00223             }
    00224
    00225             return $result;
    00226         }
    00227     }
    00228 ?>