public function aSet($attribute, $value) { Logger::getInstance()->po_log("PO:aSet {$attribute}=" . print_r($value, true) . " PHP Type: " . gettype($value)); // Chekeo is_scalar para seteo de atributos simples. // Se agregaron returns para los casos de seteo correcto. // Chekeo de is_null para hasOne. // Consideracion de valor null para hasOne. // ==================================================================== // Si es una tributo simple // VERIFY: CUal es la joda de discutir en que lista esta si al final hago lo mismo ??? // SIRVE PARA VERIFICAR QUE LO QUE ESTOY SETEANDO ES VALIDO. // CHECK 1: El atributo esta en la lista de atributos? if (isset($this->attributeTypes[$attribute]) || array_key_exists($attribute, $this->attributeTypes)) { // https://code.google.com/p/yupp/issues/detail?id=172 // Para DATES, SQLServer devuelve un DateTime object, por lo que no es escalar (integer, float, string, boolean) y tira excepcion. // DateTime > PHP 5.2 if (Datatypes::isDateTime($this->attributeTypes[$attribute]) && $value instanceof DateTime) { $value = $value->format('Y-m-d H:i:s'); // Saca el string de la fecha } if (Datatypes::isText($this->attributeTypes[$attribute]) && is_string($value)) { $value = trim($value); } // Si el valor es null o es un tipo simple (no una clase) // - Dejo tambien setear NULL xq al setear email_id puede ser NULL // y un valor simple tambien puede ser NULL si se lo desea. if ($value !== NULL && !is_scalar($value)) { throw new Exception("El valor para el atributo simple {$attribute} no es simple, es un " . gettype($value)); } // TICKET: http://code.google.com/p/yupp/issues/detail?id=35 // Resuelve el problema de que si es un booleano y carga de la base, // el tipo del valor pasa a ser string y debe mantener el tipo boolean de PHP. if ($this->attributeTypes[$attribute] == Datatypes::BOOLEAN && !is_bool($value)) { // TODO: otro valor posible podria ser "true" o "false" como strings. // TODO: ademas depende del DBMS // - "0"/"1" para MySQL funciona // - "f"/"t" para Postgres funciona $boolFalseValues = array(0, "0", "f", "F", "false", "FALSE"); $boolTrueValues = array(1, "1", "t", "T", "true", "TRUE"); // Si es $value=null y attr es booleano, la validez del valor depende de que sea nullable(true) if (!is_null($value)) { // Si esta en trueValues es true, si esta en falseValues es false, otro caso no es soportado. if ($value === "") { $value = null; } else { if (in_array($value, $boolTrueValues, true)) { $value = true; } else { if (in_array($value, $boolFalseValues, true)) { $value = false; } else { throw new Exception("El valor '{$value}' para '{$attribute}' no es un valor booleano valido"); } } } // Si es otro valor, no es soportado } } // TODO: verificar que el tipo del dato corresponde con el tipo del campo. $this->attributeValues[$attribute] = $value; $this->dirty = true; // Marca como modificada return; } else { // Esto es para buscar atributos generados ej. hoattr_id // Pruebo si el attribute no es el nombre de la columna que // corresponde con algun atributo de esta clase en el ORM. foreach ($this->attributeTypes as $classAttr => $type) { if (DatabaseNormalization::col($classAttr) == $attribute) { if ($value !== NULL && !is_scalar($value)) { throw new Exception("El valor para el atributo simple {$attribute} no es simple, es un " . gettype($value)); } $this->attributeValues[$classAttr] = $value; $this->dirty = true; // Marca como modificada return; } } } // ====================================================================== // Es hasMany o hasOne // si no esta en la lista de atributos, me fijo si no encuentro un atributo con // nombre "similar" a $attribute, esto pasa porque si el atributo es normalizedName // en la tabla guarda 'normalizedname' todo en minusculas (por YuppConventions). // Se debe hacer idem para hasOne y hasMany // Si el rol tiene el nombre de la assoc declarado, necesito ver cual es el nombre // completo de la key en hasOne o hasMany porque usa attribute__assocName. $attribute = $this->getRoleWithAssocName($attribute); if (isset($this->hasOne[$attribute]) || array_key_exists($attribute, $this->hasOne)) { if ($value !== NULL && !is_subclass_of($value, 'PersistentObject')) { throw new Exception("El valor para el atributo hasOne {$full_attribute} no es persistente, es un " . gettype($value)); } $this->attributeValues[$attribute] = $value; // email // Si seteo NULL no puedo preguntarle el id!!! $refAttrName = DatabaseNormalization::simpleAssoc($attribute); // "email_id" if ($value) { $this->attributeValues[$refAttrName] = $value->getId(); } else { $this->attributeValues[$refAttrName] = NULL; } // Seteo tambien "email_id", puede ser NULL !!! $this->dirtyOne = true; // Marca como modificada return; } else { // Pruebo si el attribute no es el nombre de la columna que // corresponde con algun atributo de esta clase en el ORM. foreach ($this->hasOne as $classHOAttr) { if (DatabaseNormalization::col($classHOAttr) == $attribute) { if ($value !== NULL && !is_subclass_of($value, 'PersistentObject')) { throw new Exception("El valor para el atributo hasOne {$full_attribute} no es persistente, es un " . gettype($value)); } $this->attributeValues[$attribute] = $value; // email // Si seteo NULL no puedo preguntarle el id!!! $refAttrName = DatabaseNormalization::simpleAssoc($attribute); // "email_id" if ($value) { $this->attributeValues[$refAttrName] = $value->getId(); } else { $this->attributeValues[$refAttrName] = NULL; } // Seteo tambien "email_id", puede ser NULL !!! $this->dirtyOne = true; // Marca como modificada return; } } } if (isset($this->hasMany[$attribute]) || array_key_exists($attribute, $this->hasMany)) { // TODO: ademas deberia ser de objetos persistentes. // TODO: NULL es un valor valido para una lista de objetos ? if (!is_array($value)) { throw new Exception("El valor para el atributo " . $attribute . " debe ser un array."); } $this->attributeValues[$attribute] = $value; $this->dirtyMany = true; // Marca como modificada return; } else { // Pruebo si el attribute no es el nombre de la columna // que corresponde con algun atributo de esta clase en el ORM. foreach ($this->hasMany as $classHMAttr) { if (DatabaseNormalization::col($classHMAttr) == $attribute) { if (!is_array($value)) { throw new Exception("El valor para el atributo " . $attribute . " debe ser un array."); } $this->attributeValues[$attribute] = $value; // Si seteo NULL no puedo preguntarle el id!!! $refAttrName = DatabaseNormalization::simpleAssoc($attribute); // "email_id" if ($value) { $this->attributeValues[$refAttrName] = $value->getId(); } else { $this->attributeValues[$refAttrName] = NULL; } // Seteo tambien "email_id", puede ser NULL !!! $this->dirtyMany = true; // Marca como modificada return; } } } throw new Exception("PO.aSet: El atributo '{$attribute}' no existe en la clase (" . get_class($this) . ")"); }
public function getDBType($type, $constraints) { $dbms_type = NULL; if (Datatypes::isText($type)) { $maxLength = NULL; // TODO: Falta ver si tengo restricciones de maxlength!!! $maxLengthConstraint = NULL; if ($constraints !== NULL) { foreach ($constraints as $constraint) { if (get_class($constraint) === 'MaxLengthConstraint') { $maxLengthConstraint = $constraint; break; // rompe for } } } //$maxLengthConstraint = $obj->getConstraintOfClass( $attr, MaxLengthConstraint ); if ($maxLengthConstraint !== NULL) { $maxLength = $maxLengthConstraint->getValue(); } $dbms_type = $this->getTextType($type, $maxLength); // Devuelve VARCHAR, TEXT, o el tipo correcto dependiendo del maxlength. } else { if (Datatypes::isNumber($type)) { $dbms_type = $this->getNumericType($type); } else { if (Datatypes::isDateTime($type)) { $dbms_type = $this->getDateTimeType($type); } else { throw new Exception("DatabasePosgreSQL.getDBType: el tipo ({$type}) no esta definido."); } } } return $dbms_type; }
public function getDBType($type, $constraints) { $dbms_type = NULL; if (Datatypes::isText($type)) { $maxLength = NULL; $maxLengthConstraint = NULL; if ($constraints !== NULL) { foreach ($constraints as $constraint) { if (get_class($constraint) === 'MaxLengthConstraint') { $maxLengthConstraint = $constraint; break; // rompe for } } } // FIXME: no tengo este metodo? para que se hace la busqueda aca? En MySQL debe estar igual... //$maxLengthConstraint = $obj->getConstraintOfClass( $attr, MaxLengthConstraint ); if ($maxLengthConstraint !== NULL) { $maxLength = $maxLengthConstraint->getValue(); } $dbms_type = $this->getTextType($type, $maxLength); // Devuelve VARCHAR, TEXT, o el tipo correcto dependiendo del maxlength. } else { if (Datatypes::isNumber($type)) { $dbms_type = $this->getNumericType($type); } else { if (Datatypes::isDateTime($type)) { $dbms_type = $this->getDateTimeType($type); } else { throw new Exception("DatabaseMySQL.getDBType: el tipo ({$type}) no esta definido."); } } } return $dbms_type; }