. * */ namespace SP\Import; use SP\Core\Exceptions\SPException; defined('APP_ROOT') || die(_('No es posible acceder directamente a este archivo')); /** * Class XmlImportBase abstracta para manejar archivos de importación en formato XML * * @package SP */ abstract class XmlImportBase extends ImportBase { /** * @var \SimpleXMLElement */ protected $xml; /** * @var \DOMDocument */ protected $xmlDOM; /** * ImportBase constructor. * * @param FileImport $File * @param ImportParams $ImportParams * @throws SPException */ public function __construct(FileImport $File, ImportParams $ImportParams) { parent::__construct($File, $ImportParams); try { $this->readXMLFile(); } catch (SPException $e) { throw $e; } } /** * Leer el archivo a un objeto XML. * * @throws SPException */ protected function readXMLFile() { $this->xml = simplexml_load_file($this->file->getTmpFile()); // Cargar el XML con DOM $this->xmlDOM = new \DOMDocument(); $this->xmlDOM->load($this->file->getTmpFile()); if ($this->xml === false) { throw new SPException( SPException::SP_CRITICAL, _('Error interno'), _('No es posible procesar el archivo XML') ); } } /** * Detectar la aplicación que generó el XML. * * @throws SPException */ public function detectXMLFormat() { if ((string)$this->xml->Meta->Generator === 'KeePass') { return 'keepass'; } else if ((string)$this->xml->Meta->Generator === 'sysPass') { return 'syspass'; } else if ($xmlApp = $this->parseFileHeader()) { switch ($xmlApp) { case 'keepassx_database': return 'keepassx'; case 'revelationdata': return 'revelation'; default: break; } } else { throw new SPException( SPException::SP_CRITICAL, _('Archivo XML no soportado'), _('No es posible detectar la aplicación que exportó los datos') ); } return ''; } /** * Obtener los datos de los nodos * * @param string $nodeName Nombre del nodo principal * @param string $childNodeName Nombre de los nodos hijos * @throws SPException */ protected function getNodesData($nodeName, $childNodeName, $callback) { $ParentNode = $this->xmlDOM->getElementsByTagName($nodeName); if ($ParentNode->length === 0) { throw new SPException(SPException::SP_WARNING, _('Formato de XML inválido'), sprintf(_('El nodo "%s" no existe'), $nodeName)); } elseif (!is_callable([$this, $callback])) { throw new SPException(SPException::SP_WARNING, _('Método inválido')); } /** @var \DOMElement $nodes */ foreach ($ParentNode as $nodes) { /** @var \DOMElement $Account */ foreach ($nodes->getElementsByTagName($childNodeName) as $Node) { $this->$callback($Node); } } } }