/**
  * Metodo auxiliar para cargar los objetos asociados en cascada, tanto los hasOne como los hasMany, 
  * verificando previamente si no fueron ya cargados.
  * @param PersistentObject $obj el objeto al que hay que cargarle los objetos asociados.
  */
 private function getCascadeAssocs($obj)
 {
     // Para saber si estaba limpia previamente, para poder limpiar lo que esta operacion ensucia (dirty bits)
     $wasClean = $obj->isClean();
     // TODO: Verificar si para los objetos en hasOne, sus asociaciones son cargadas en cascada.
     // Para cada objeto hasOne, lo trae.
     // Para el objeto hago get para hasOne y getMany para los hasMany.
     $ho_attrs = $obj->getHasOne();
     foreach ($ho_attrs as $attr => $assoc_class) {
         // attr = "email_id" ?
         $ho_instance = new $assoc_class();
         $hasOneAttr = DatabaseNormalization::getSimpleAssocName($attr);
         // email
         $assoc_id = $ho_instance->aGet($attr);
         $assoc_obj = NULL;
         if (ArtifactHolder::getInstance()->existsModel($assoc_class, $assoc_id)) {
             $assoc_obj = ArtifactHolder::getInstance()->getModel($assoc_class, $assoc_id);
         } else {
             $assoc_obj = $this->get($assoc_class, $assoc_id);
             ArtifactHolder::getInstance()->addModel($assoc_obj);
         }
         //$obj->{"set".$attr}( $assoc_obj );
         $obj->aSet($attr, $assoc_obj);
     }
     // Para cada objeto hasMany, lo trae
     // Para el objeto hago get para hasOne y getMany para los hasMany.
     $hm_attrs = $obj->getHasMany();
     foreach ($hm_attrs as $attr => $class) {
         $this->getMany($obj, $attr);
         // Carga los elementos del atributo en la clase.
     }
     // TODO: si carga en cascada, entonces la instancia de obj y sus clases asociadas
     //       se cargan todas en el mismo momento, por lo que no habria nada sucio,
     //       y seria innecesario verificar si estaba sucia antes de la carga.
     // Solo limpia si la clase estaba limpia antes de la operacion
     if ($wasClean) {
         $obj->resetDirty();
     }
     // Apaga las banderas que se prendieron en la carga
 }
 public function nullable($attr)
 {
     // Atributos inyectados no son nullables.
     if (self::isInyectedAttribute($attr)) {
         return false;
     }
     if (DatabaseNormalization::isSimpleAssocName($attr)) {
         $attr = DatabaseNormalization::getSimpleAssocName($attr);
     }
     if (isset($this->constraints[$attr])) {
         foreach ($this->constraints[$attr] as $constraint) {
             if (get_class($constraint) === 'Nullable') {
                 return $constraint->getValue();
             }
         }
     }
     return true;
     // Por defecto es nullable. Es mas facil para generar las tablas, ahora se pone en not null solo si hay una restriccion que lo diga.
 }
Exemplo n.º 3
0
 /**
  * Devuelve HTML para edicion de un objeto como una tabla con 2 columnas, la primera de nombres de campos la segunda con campos con valores para modificar.
  */
 private static function display_edit(PersistentObject $po)
 {
     $res = '<table>';
     $attrs = $po->getAttributeTypes();
     foreach ($attrs as $attr => $type) {
         // Los atributos inyectados no se deberian poder editar!
         $res .= '<tr><td>';
         $res .= $attr;
         // TODO: Habria que ver si esto es i18n, deberia haber algun "display name" asociado al nombre del campo.
         $res .= '</td><td>';
         if ($po->isInyectedAttribute($attr)) {
             //$res .= $po->aGet($attr);
             $res .= self::field_to_html_show($attr, $type, $po->aGet($attr));
         } else {
             if (DatabaseNormalization::isSimpleAssocName($attr)) {
                 // Si es un fk a un id de un hasOne, quiero mostrar una lista de los posibles ids
                 // de la clase de la relacion HO que le puedo asignar, y como esto es create o edit,
                 // si tiene un valor actual, deberia quedar seleccionado en el select.
                 $currentValue = $po->aGet($attr);
                 // Puede ser NULL
                 $role = DatabaseNormalization::getSimpleAssocName($attr);
                 // email_id -> email
                 $relClass = $po->getAttributeType($role);
                 // Clase de la relacion HO
                 // Objetos que puedo tener relacionadoss
                 // Se puede en PHP 5.3.0...
                 //$list = $relClass::listAll(new ArrayObject()); // Objetos que podria tener asociados
                 // ... pero por las dudas ...
                 $list = call_user_func_array(array($relClass, 'listAll'), array(new ArrayObject()));
                 $select = '<select name="' . $attr . '"><option value=""></option>';
                 foreach ($list as $relObj) {
                     $sel = $currentValue == $relObj->getId() ? ' selected="true"' : '';
                     $select .= '<option value="' . $relObj->getId() . '"' . $sel . '>' . $relClass . '[' . $relObj->getId() . ']</option>';
                     // TODO: Si se tuviera un toString en la clase se mostraria mejor
                 }
                 $select .= '</select>';
                 $res .= $select;
             } else {
                 $maxStringLength = NULL;
                 if ($type === Datatypes::TEXT) {
                     $maxLengthConstraint = $po->getConstraintOfClass($attr, 'MaxLengthConstraint');
                     if ($maxLengthConstraint !== NULL) {
                         $maxStringLength = $maxLengthConstraint->getValue();
                     }
                 }
                 $res .= self::field_to_html_edit($attr, $type, $po->aGet($attr), $maxStringLength);
                 // Si el campo tiene errores, los muestro
                 if ($po->getErrors()->hasFieldErrors($attr)) {
                     $res .= '<div class="errors">';
                     $res .= self::fieldErrors($po, $attr);
                     $res .= '</div>';
                 }
             }
         }
         $res .= '</td></tr>';
     }
     $res .= '</table>';
     return $res;
 }