',','GROUP'=>'.'); } /** * Define los carácteres usados en internamente (PHP) para los números * * @access public * @static * @return mixed array asociativo con entrada 'DECIMAL' y 'GROUP' */ static function caracteresNumericosNegocio(){ return array('DECIMAL'=>'.','GROUP'=>''); } /** * Da formato a un número desde PHP para presentarlo en pantalla. * * @access public * @static * @param numero numero a formatear * @param numero decimales a considerar * @return string devuelve el número formateado */ static function formatoNumero($num,$decimales=2){ $carp = ConfIgep::caracteresNumericos(); $carn = ConfIgep::caracteresNumericosNegocio(); $transformer = new IgepTransformer(); $transformer->setDecimal($carn['DECIMAL'],$carp['DECIMAL'],$carn['GROUP'],$carp['GROUP']); $num = $transformer->expandExponent($num); $num = $transformer->decimalPad($num, $decimales); $num = $transformer->process(TIPO_DECIMAL,$num); return $num; } /** * Da formato a un número de pantalla para manejarlo en el php * Independientemente de la configuracion de bds y de presentación, * el php maneja el punto decimal. * Anteriormente este metodo solo eliminaba el separador de grupos * si habia sep. de grupos y de decimales; de esta forma si el numero venia * con puntos decimales los aceptaba como comas. * En adelante se eliminan siempre los separadores de grupos. * * @access public * @static * @param numero a formatear * @return string devuelve el número para PHP */ static function transformaNumero($num){ return ConfIgep::transformaNegocio($num, TIPO_DECIMAL); } /** * Define la mascara de representación de fechas * La j es como d pero puede no tener ceros iniciales * La n es como m pero puede no tener ceros iniciales * Si usamos la d o la m en la mascara no se podran manejar fechas * donde el dia o el mes inicial no esten precedidas de ceros. * Solo se puede cambiar el orden de las letras y el caracter separador * (y que sea un solo caracter, y el mismo) * * Aunque solo aparezca un formato, realmente se distinguen dos: * - entrada: formato usado para introduccion de datos, y que nos interesa que sea * lo mas flexible posible, por lo que no obliga a introducir ceros cuando el dia o el * mes son menores de 10. Es el que representa esta funcion. * - salida: formato usado para mostrar dados, y que nos interesa mostrar que las fechas * salgan lo mas homogeneas posibles. Es el usado implicitamente por el transformer y por * formatoFecha(). * * @access public * @static * @return string */ static function mascaraRepresentacionFechas() { return 'j/n/Y'; } /** * Define la mascara de representación de fechas en negocio (PHP) * No se debe cambiar sin modificar la implementacion de las transformaciones !!! * * TODO: hay que tener precaucion en las transformaciones a otra capa, ya que la * fecha en negocio tambien puede estar en numero (timestamp) y podria ocurrir que * no se transformara. * * @access public * @static * @return string */ static function mascaraFechasNegocio(){ return 'Y/m/d'; } /** * Da formato a una fecha para presentarlo en pantalla. * Acepta como entrada la fecha en timestamp o en formato string de negocio. * Cuando recibe una fecha en timestamp, modifica el formato para que salga * el dia y mes rellenado con ceros, como hace el transformer * * @access public * @static * @param string fecha en formato timestamp * @param string tipo de formato: FECHAHORA, FECHA * @return string devuelve la fecha formateada */ static function formatoFecha($fecha,$tipo){ if ($tipo != 'FECHA' and $tipo != 'FECHAHORA') return '!!tipo fecha incorrecto!!'; $fmt_dest = self::mascaraRepresentacionFechas(); if (is_numeric($fecha)) { // calculo repetido en tests $fmt_dest = str_replace('j', 'd', $fmt_dest); $fmt_dest = str_replace('n', 'm', $fmt_dest); if ($tipo == 'FECHAHORA') $fmt_dest .= ' H:i:s'; return date($fmt_dest, $fecha); } else { $fmt_ori = self::mascaraFechasNegocio(); $transformer = new IgepTransformer(); $transformer->setDate($fmt_ori,$fmt_dest); return $transformer->process(($tipo == 'FECHAHORA'? TIPO_FECHAHORA : TIPO_FECHA), $fecha); } } /** * Da formato a una fecha pantalla para tratarla en negocio * Devuelve false si es incorrecta, o null si el valor es vacio * Hay algunas fechas como '30/02/2007' que no dan error con la funcion * strtotime sino que equivale a 2/3/2007. Por ese motivo: * - añadimos mas controles y asi poder validar la entrada del usuario * - no usamos ConfIgep::transformaNegocio($str_fechaHora, TIPO_FECHAHORA) TODO * * @access public * @static * @param string fecha en formato string * @return time devuelve la fecha formateada */ static function formatoFechaNegocio($str_fechaHora) { self::setTransformErrors(array()); if (empty($str_fechaHora)) return NULL; // return ConfIgep::transformaNegocio($str_fechaHora, TIPO_FECHAHORA); $fecha_ori = ConfIgep::mascaraRepresentacionFechas(); $fecha_dest = ConfIgep::mascaraFechasNegocio(); $transformer = new IgepTransformer(true); $transformer->setDate($fecha_ori,$fecha_dest); $str_fechaHora = $transformer->process(TIPO_FECHAHORA, $str_fechaHora); self::setTransformErrors($transformer->getTransformErrors()); $res = strtotime($str_fechaHora); if (!$res) return false; list($f, $h) = explode(" ",$str_fechaHora); if ($f != date($fecha_dest, $res)) return false; if (isset($h)) { list($hh, $hm, $hs) = explode(':',$h); if ($hh<0 || $hh>23 || $hm<0 || $hm>59 || (isset($hs) && ($hs<0 || $hs>59)) ) return false; } return $res; } /** * Compara dos fechas en formato string, de la capa interfaz * Devuelve un número positivo si la segunda fecha es posterior a la primera * * @access public * @static * @param string fecha (interfaz) * @param string fecha (interfaz) * @return int (timestamp) */ function comparaFechas($str_fechaHora1, $str_fechaHora2){ $fecha1 = ConfIgep::formatoFechaNegocio($str_fechaHora1); $fecha2 = ConfIgep::formatoFechaNegocio($str_fechaHora2); return ($fecha2-$fecha1); } // Fin de comparaFechas /** * Este método prepara los datos que vienen de una consulta de la BD antes de mostrarse en * el formato propio de gvHidra. Generalmente, las fechas y los decimales en los sistemas que * tengan mascaras diferentes a las de gvHidra (p.e. MySQL). * Este método puede ser invocado por el usuario, o bien se puede llamar opcionalmente con los metodos * 'consultar' de IgepNegocio e IgepConexion si le pasamos un segundo parámetro indicandole el NODO_INTERFAZ. * Se puede optimizar controlando que en el array de tipos haya fechas o numeros decimales. * Si estamos convirtiendo un numero a decimal podemos indicar el numero de decimales. * * @access public * @param any $a_parametros * @param any $a_tipo * @param mixed $a_dsn * @param number $a_decimales * @return mixed */ static function prepararPresentacion(& $a_parametros, $a_tipo, $a_dsn, $a_decimales=2) { $transformer = new IgepTransformer(); $carbd = IgepDB::caracteresNumericos($a_dsn); $carconf = ConfIgep::caracteresNumericos(); $transformer->setDecimal($carbd['DECIMAL'],$carconf['DECIMAL'],$carbd['GROUP'],$carconf['GROUP']); $fechabd = IgepDB::mascaraFechas($a_dsn); $fechaconf = ConfIgep::mascaraRepresentacionFechas(); $transformer->setDate($fechabd,$fechaconf); if(is_array($a_parametros)) { if(is_array($a_tipo)){ foreach($a_parametros as $fila => $tupla){ foreach($a_tipo as $campo => $descTipo){ if(isset($tupla[$campo])) { $tipo_efectivo = (empty($descTipo['tipo'])? TIPO_CARACTER: ($descTipo['tipo']==TIPO_ENTERO? TIPO_DECIMAL: $descTipo['tipo'])); if ($tipo_efectivo == TIPO_DECIMAL) $tupla[$campo] = $transformer->expandExponent($tupla[$campo], $carbd['DECIMAL'], $carbd['GROUP']); if ($descTipo['tipo'] == TIPO_DECIMAL) $tupla[$campo] = $transformer->decimalPadDatos($tupla[$campo], $descTipo['parteDecimal'], $a_dsn); $a_parametros[$fila][$campo] = $transformer->process($tipo_efectivo, $tupla[$campo]); } } } } } elseif($a_parametros!='' and $a_tipo!='') { $tipo_efectivo = ($a_tipo==TIPO_ENTERO? TIPO_DECIMAL: $a_tipo); if ($tipo_efectivo == TIPO_DECIMAL) $a_parametros = $transformer->expandExponent($a_parametros, $carbd['DECIMAL'], $carbd['GROUP']); if ($a_tipo == TIPO_DECIMAL) $a_parametros = $transformer->decimalPadDatos($a_parametros, $a_decimales, $a_dsn); $a_parametros = $transformer->process($tipo_efectivo,$a_parametros); } return $a_parametros; } // Fin de prepararPresentacion /** * Este método prepara los datos que vienen de una consulta de la BD antes de operar en PHP. * Generalmente, las fechas y los decimales en los sistemas que tengan mascaras diferentes a las de PHP. * Este método puede ser invocado por el usuario, o bien se puede llamar opcionalmente con los metodos * 'consultar' de IgepNegocio e IgepConexion si le pasamos un segundo parámetro indicandole el NODO_NEGOCIO. * Se puede optimizar controlando que en el array de tipos haya fechas o numeros decimales. * * @access public * @param any $a_parametros * @param any $a_tipo * @param mixed $dsn * @return mixed */ function prepararNegocio(& $a_parametros, $a_tipo, $a_dsn) { $transformer = new IgepTransformer(); $carbd = IgepDB::caracteresNumericos($a_dsn); $carconf = ConfIgep::caracteresNumericosNegocio(); $transformer->setDecimal($carbd['DECIMAL'],$carconf['DECIMAL'],$carbd['GROUP'],$carconf['GROUP']); $fechabd = IgepDB::mascaraFechas($a_dsn); $fechaconf = ConfIgep::mascaraFechasNegocio(); $transformer->setDate($fechabd,$fechaconf); if (is_array($a_parametros)){ if (is_array($a_tipo)){ foreach ($a_parametros as $fila => $tupla){ foreach ($a_tipo as $campo => $descTipo) { $tipo_efectivo = (empty($descTipo['tipo'])? TIPO_CARACTER: ($descTipo['tipo']==TIPO_ENTERO? TIPO_DECIMAL: $descTipo['tipo'])); $a_parametros[$fila][$campo] = $transformer->process($tipo_efectivo, $tupla[$campo]); } } } } elseif ($a_parametros!='' and $a_tipo!='') { $tipo_efectivo = ($a_tipo==TIPO_ENTERO? TIPO_DECIMAL: $a_tipo); $a_parametros = $transformer->process($tipo_efectivo,$a_parametros); } return $a_parametros; } // Fin de prepararNegocio /** * Este método transforma los datos de negocio a datos. * Este método puede ser invocado por el usuario * Se llama en IgepConexion prepararNumero y prepararFecha * Para fechas, si vienen en formato numerico (timestamp) se convierten directamente sin usar el IgepTransformer * * @param any $a_parametros * @param any $a_tipo * @param mixed $a_dsn * @return mixed */ static function prepararDatos($a_parametros, $a_tipo, $a_dsn, $a_quotes=true) { $transformer = new IgepTransformer(); $carbd = IgepDB::caracteresNumericos($a_dsn); $carconf = ConfIgep::caracteresNumericosNegocio(); $transformer->setDecimal($carconf['DECIMAL'],$carbd['DECIMAL'],$carconf['GROUP'],$carbd['GROUP']); $fechabd = IgepDB::mascaraFechas($a_dsn); $fechaconf = ConfIgep::mascaraFechasNegocio(); $transformer->setDate($fechaconf, $fechabd); if ($a_quotes and get_magic_quotes_gpc()==0){ $transformer->setCharacter("'","''"); $transformer->setCharacter("\\","\\\\"); } $vector = true; if (!is_array($a_parametros) and $a_parametros!='' and $a_tipo!='') { // le doy estructura de vector para no repetir el codigo $vector = false; $a_parametros = array(array('col'=>$a_parametros,),); $a_tipo = array('col'=>array('tipo'=>$a_tipo,),); } if (is_array($a_tipo)){ foreach ($a_parametros as $fila => $tupla){ foreach ($tupla as $campo => $valor){ if (isset($tupla[$campo])) { $descTipo = $a_tipo[$campo]; $tipo_efectivo = (empty($descTipo['tipo'])? TIPO_CARACTER: ($descTipo['tipo']==TIPO_ENTERO? TIPO_DECIMAL: $descTipo['tipo'])); if ($tipo_efectivo == TIPO_DECIMAL) $tupla[$campo] = $transformer->expandExponent($tupla[$campo], $carconf['DECIMAL'], $carconf['GROUP']); if (($tipo_efectivo == TIPO_FECHA or $tipo_efectivo == TIPO_FECHAHORA) and is_int($tupla[$campo])) { $a_parametros[$fila][$campo] = date($fechabd.($tipo_efectivo==TIPO_FECHAHORA? ' H:i:s':''), $tupla[$campo]); if ($tipo_efectivo==TIPO_FECHAHORA and ($i=strpos($a_parametros[$fila][$campo],' 00:00:00'))!==false) $a_parametros[$fila][$campo] = substr($a_parametros[$fila][$campo], 0, $i); } else { $a_parametros[$fila][$campo] = $transformer->process($tipo_efectivo, $tupla[$campo]); } } } } } if ($vector) return $a_parametros; else return $a_parametros[0]['col']; } /** * Este método transforma los datos de interfaz a negocio. * Este método puede ser invocado por el usuario * Las fechas se convierten a timestamp siempre * Se llama en: * - ConfIgep::transformaNumero * * @param any $a_parametros * @param any $a_tipo * @return mixed */ static function transformaNegocio($a_parametros, $a_tipo) { self::setTransformErrors(array()); $transformer = new IgepTransformer(true); $car_i = ConfIgep::caracteresNumericos(); $car_n = ConfIgep::caracteresNumericosNegocio(); $transformer->setDecimal($car_i['DECIMAL'],$car_n['DECIMAL'],$car_i['GROUP'],$car_n['GROUP']); $fecha_i = ConfIgep::mascaraRepresentacionFechas(); $fecha_n = ConfIgep::mascaraFechasNegocio(); $transformer->setDate($fecha_i, $fecha_n); $vector = true; if (!is_array($a_parametros) and $a_parametros!='' and $a_tipo!='') { // le doy estructura de vector para no repetir el codigo $vector = false; $a_parametros = array(array('col'=>$a_parametros,),); $a_tipo = array('col'=>array('tipo'=>$a_tipo,),); } if (is_array($a_tipo)){ foreach ($a_parametros as $fila => $tupla){ foreach ($a_tipo as $campo => $descTipo) { if (isset($tupla[$campo])) { $tipo_efectivo = ($descTipo['tipo']==TIPO_ENTERO? TIPO_DECIMAL: $descTipo['tipo']); $a_parametros[$fila][$campo] = $transformer->process($tipo_efectivo, $tupla[$campo]); if ($tipo_efectivo == TIPO_FECHA or $tipo_efectivo == TIPO_FECHAHORA) { // uso formato negocio en timestamp $a_parametros[$fila][$campo] = strtotime($a_parametros[$fila][$campo]); } } } } } self::setTransformErrors($transformer->getTransformErrors()); if ($vector) return $a_parametros; else return $a_parametros[0]['col']; } function getTransformErrors() { return self::$transformErrors; } function setTransformErrors($lis) { self::$transformErrors = $lis; } } ?>