public static function toPO($xmlstr, XSLTProcessor $xslt = NULL) { if ($xslt != NULL) { //$doc = DOMDocument::loadXML($xmlstr); $doc = new DOMDocument(); $doc->loadXML($xmlstr, LIBXML_NOCDATA); // TEST: hay 252 $xpath = new DOMXPath($doc); $nodelist = $xpath->query('//cuerpo/personas/persona'); echo 'Hay ' . $nodelist->length . ' nodos persona<br/>'; $xmlstr = $xslt->transformToXML($doc); } if ($xmlstr === NULL) { echo 'la transformacion retorna NULL<br/>'; return null; } // DEBUG //FileSystem::write('archivo_transformado_alta_pac.xml', $xmlstr); // Tengo que cargar todas las clases de la aplicacion actual porque // se como se llaman, pero no se donde estan. YuppLoader::forceReload(); YuppLoader::loadModel(); // FIXME: no carga las clases del imp! //print_r(YuppLoader::getLoadedClasses()); // Parseo el XML (deberia tener el formato de toXML) $xml = simplexml_load_string($xmlstr); // TEST: hay 252! $arr = $xml->xpath('//IMPPersona '); echo "En el transformado hay " . count($arr) . " personas<br/>"; // Referencias a paths con objetos para resolver referencias por loops $pathObj = new ArrayObject(); // *** // TODO: ver si el nodo raiz es un objeto simple o una coleccion. // <personas type="collection" of="IMPPersona"> if (!empty($xml['type']) && $xml['type'] == 'collection') { // TEST: // 252 nodos! echo count($xml->children()) . "<br/>"; // nodes, parentAttr, path, pathObj $list_po = self::toPOCollection($xml->children(), '/' . $xml->getName(), $pathObj); // TEST: error hay 381 personas! echo "Hay " . count($list_po) . " en la lista de PO<br/>"; return $list_po; } // Para el primer nodo, la clase es el nombre del elemento $class = $xml->getName(); $po = self::toPOSingle($class, $xml, '', -1, $pathObj); // TODO: no necesito loop detection para no entrar en loops infinitos, // lo necesito para resolver referencias a nodos, y reflejarlo en el PO que estoy creando. //$loopDetection = new ArrayObject(); //self::toXMLSingle( $po, $xml_dom, $xml_dom, $recursive, $loopDetection ); /* if ($xslt === NULL) return $xml_dom->saveXML(); else return $xslt->transformToXML( $xml_dom ); */ //print_r($pathObj); return $po; }
/** * clazz es el nombre de una clase de modelo (tambien puede ser PersistentObject). * Devuelve una estructura multiple con los nombres de todas las clases que heredan de clazz (hijas, nietas, etc) */ public static function getAllSubclassesOf($clazz) { //echo "<h1>ModelUtils.getAllSubclassesOf $clazz</h1>"; //Logger::struct( get_declared_classes(), "Declared classes ".__FILE__." ".__LINE__ ); // Esto en realidad se deberia hacer con getLoadedModelClasses // porque ModelUtils es para resolver temas de las clases del modelo. //$loadedClasses = YuppLoader::getLoadedClasses(); // Como las clases cargadas dependen de la aplicacion, // me ancargo de cargar todas las clases de la aplicacion // actual para obtener correctamente las subclases. // Mismo codigo que getSubclassesOf. $ctx = YuppContext::getInstance(); $appName = $ctx->getApp(); if ($appName == 'core') { // Si no se cargaron todas las clases y no se pasa el nombre de la app, no devuelve realmente todas las subclases, solo las que estan cargadas. YuppLoader::loadModel(); // Carga el modelo de todas las aplicaciones } else { // TODO: metodo para cargar todas las clases del modelo de una aplicacion. $classes = array(); // FIXME: Mismo codigo que CoreController.dbStatus YuppLoader::load('core.app', 'App'); // Puede no estar cargada $app = new App($appName); $modelClassFileNames = $app->getModel(); // Logger::struct( $modelClassFileNames, "modelClassFileNames ".__FILE__." ".__LINE__ ); $modelClassFileNames = self::array_flatten($modelClassFileNames); $fn = new FileNames(); foreach ($modelClassFileNames as $classFileName) { $fileInfo = $fn->getFileNameInfo($classFileName); YuppLoader::load($fileInfo['package'], $fileInfo['name']); } } $loadedClasses = YuppLoader::getLoadedModelClasses(); $res = array(); foreach ($loadedClasses as $loadedClass) { if (class_exists($loadedClass) && is_subclass_of($loadedClass, $clazz)) { $res[] = $loadedClass; } } return $res; }
/** * Accion para crear una nueva instancia de la clase pasada como parametro. * Sirve cuando la accion no esta definida en el controller o mismo no hay definido un controller para la clase. */ public function createAction() { $clazz = $this->params['class']; $loadedClasses = get_declared_classes(); //YuppLoader::getLoadedModelClasses(); // FIXME: Tengo clases cargadas en YuppLoader pero no estan incluidas (debe ser por persistencia del singleton en session) if (!in_array($clazz, $loadedClasses)) { YuppLoader::loadModel(); } $obj = new $clazz(); // Crea instancia para mostrar en la web los valores por defecto para los atributos que los tengan. $appName = $this->params['app']; // Para que cargue la configuracion correcta de la base de datos. // Si no trata de ejecutar usando la configuracion de la base por defecto. $ctx = YuppContext::getInstance(); $ctx->setRealApp($appName); // View create, que es como edit pero la accion de salvar vuelve aqui. if (isset($this->params['doit'])) { $obj->setProperties($this->params); //Logger::getInstance()->on(); //Logger::struct($ctx); if (!$obj->save()) { $this->flash['message'] = 'Ha ocurrido un error al guardar'; // FIXME: redirect a show $this->params['object'] = $obj; return $this->render("create"); } $this->params['object'] = $obj; return $this->render("show"); } $this->params['object'] = $obj; return $this->render("create"); }