Agregar archivo .gitignore y eliminar archivos innecesarios

This commit is contained in:
David Vargas 2024-09-05 12:01:59 -06:00
commit 31e66fb310
13 changed files with 1000 additions and 0 deletions

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
/vendor/
composer.lock
*.log
.vscode/
.idea/
*.sublime-workspace
*.sublime-project
.DS_Store
Thumbs.db
.phpunit.result.cache
/public/storage
/storage/*.key
/storage/*.log
.env
.env.*

21
composer.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "david/format_converter",
"description": "Conversion entre formatos XML, JSON y PHP (Serializado)",
"autoload": {
"psr-4": {
"FormatConverter\\": "src/"
}
},
"authors": [
{
"name": "DavidDevGt",
"email": "josuedavidvl18@gmail.com"
}
],
"minimum-stability": "stable",
"require": {
"symfony/yaml": "^6.4",
"psr/log": "^3.0",
"monolog/monolog": "^3.7"
}
}

388
composer.lock generated Normal file
View File

@ -0,0 +1,388 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "a020b975918320b15b7d8cf8286212c1",
"packages": [
{
"name": "monolog/monolog",
"version": "3.7.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/f4393b648b78a5408747de94fca38beb5f7e9ef8",
"reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8",
"shasum": ""
},
"require": {
"php": ">=8.1",
"psr/log": "^2.0 || ^3.0"
},
"provide": {
"psr/log-implementation": "3.0.0"
},
"require-dev": {
"aws/aws-sdk-php": "^3.0",
"doctrine/couchdb": "~1.0@dev",
"elasticsearch/elasticsearch": "^7 || ^8",
"ext-json": "*",
"graylog2/gelf-php": "^1.4.2 || ^2.0",
"guzzlehttp/guzzle": "^7.4.5",
"guzzlehttp/psr7": "^2.2",
"mongodb/mongodb": "^1.8",
"php-amqplib/php-amqplib": "~2.4 || ^3",
"phpstan/phpstan": "^1.9",
"phpstan/phpstan-deprecation-rules": "^1.0",
"phpstan/phpstan-strict-rules": "^1.4",
"phpunit/phpunit": "^10.5.17",
"predis/predis": "^1.1 || ^2",
"ruflin/elastica": "^7",
"symfony/mailer": "^5.4 || ^6",
"symfony/mime": "^5.4 || ^6"
},
"suggest": {
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
"elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
"ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
"ext-mbstring": "Allow to work properly with unicode symbols",
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
"ext-openssl": "Required to send log messages using SSL",
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
"rollbar/rollbar": "Allow sending log messages to Rollbar",
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Monolog\\": "src/Monolog"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "https://seld.be"
}
],
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
"homepage": "https://github.com/Seldaek/monolog",
"keywords": [
"log",
"logging",
"psr-3"
],
"support": {
"issues": "https://github.com/Seldaek/monolog/issues",
"source": "https://github.com/Seldaek/monolog/tree/3.7.0"
},
"funding": [
{
"url": "https://github.com/Seldaek",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
"type": "tidelift"
}
],
"time": "2024-06-28T09:40:51+00:00"
},
{
"name": "psr/log",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "79dff0b268932c640297f5208d6298f71855c03e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/79dff0b268932c640297f5208d6298f71855c03e",
"reference": "79dff0b268932c640297f5208d6298f71855c03e",
"shasum": ""
},
"require": {
"php": ">=8.0.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/3.0.1"
},
"time": "2024-08-21T13:31:24+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.5.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.5-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-04-18T09:32:20+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.30.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "0424dff1c58f028c451efff2045f5d92410bd540"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
"reference": "0424dff1c58f028c451efff2045f5d92410bd540",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-05-31T15:07:36+00:00"
},
{
"name": "symfony/yaml",
"version": "v6.4.11",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "be37e7f13195e05ab84ca5269365591edd240335"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/be37e7f13195e05ab84ca5269365591edd240335",
"reference": "be37e7f13195e05ab84ca5269365591edd240335",
"shasum": ""
},
"require": {
"php": ">=8.1",
"symfony/deprecation-contracts": "^2.5|^3",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
"symfony/console": "<5.4"
},
"require-dev": {
"symfony/console": "^5.4|^6.0|^7.0"
},
"bin": [
"Resources/bin/yaml-lint"
],
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Loads and dumps YAML files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v6.4.11"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-08-12T09:55:28+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": [],
"plugin-api-version": "2.6.0"
}

128
public/css/main.css Normal file
View File

@ -0,0 +1,128 @@
body {
font-family: 'Roboto', sans-serif;
padding-top: 50px;
background: linear-gradient(135deg, #f0f4f8, #e0e7ff);
transition: background 0.3s ease;
min-height: 100vh;
}
.dark-mode {
background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
}
.container {
max-width: 720px;
background-color: #fff;
padding: 30px;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: background-color 0.3s ease;
}
.dark-mode .container {
background-color: #1e1e1e;
box-shadow: none;
}
h1 {
font-size: 2rem;
font-weight: 500;
color: #424242;
text-align: center;
transition: color 0.3s ease;
}
.dark-mode h1 {
color: #e0e0e0;
}
label {
font-size: 1.1rem;
color: #424242;
transition: color 0.3s ease;
}
.dark-mode label {
color: #e0e0e0;
}
textarea, select {
font-size: 1rem;
padding: 10px;
border: 1px solid #d1d9e6;
background-color: #fff;
color: #333;
transition: background-color 0.3s ease, color 0.3s ease;
}
.dark-mode textarea, .dark-mode select {
background-color: #2c2c2c;
color: #e0e0e0;
border: 1px solid #555;
}
button {
font-size: 1.2rem;
padding: 12px;
background-color: #6200ea;
border: none;
border-radius: 5px;
color: white;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #3700b3;
}
button:disabled {
background-color: #bbb;
cursor: not-allowed;
}
.spinner-border {
display: none;
width: 1rem;
height: 1rem;
}
.loading .spinner-border {
display: inline-block;
}
.output-container {
background-color: #f0f4f8;
padding: 15px;
border-radius: 5px;
border: 1px solid #d1d9e6;
margin-top: 20px;
transition: background-color 0.3s ease, border-color 0.3s ease;
}
.dark-mode .output-container {
background-color: #2c2c2c;
border-color: #555;
}
.text-success {
color: #2e7d32;
}
.text-danger {
color: #c62828;
}
.switch-container {
display: flex;
justify-content: flex-end;
margin-top: -10px;
margin-bottom: 10px;
}
.dark-switch {
display: flex;
justify-content: center;
align-items: center;
margin-top: 10px;
max-width: 50px;
}

73
public/index.html Normal file
View File

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Convertir formatos XML, JSON y Objetos serializados de PHP">
<title>Serial2Format</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="css/main.css">
</head>
<body :class="{ 'dark-mode': darkMode }">
<div id="app" class="container">
<div class="row switch-container">
<div class="col-md-12 text-right">
<button @click="toggleDarkMode" class="btn btn-secondary dark-switch">
<i :class="darkMode ? 'fas fa-moon' : 'fas fa-sun'"></i>
</button>
</div>
</div>
<h1 class="display-4 fw-bold mb-3">Serial2Format</h1>
<div class="mb-3">
<label for="inputData" class="form-label">Datos de Entrada:</label>
<textarea class="form-control" v-model="inputData" rows="6" placeholder="Ingrese sus datos aquí..."></textarea>
</div>
<div class="row mb-3">
<div class="col">
<label for="inputFormat" class="form-label">Formato de Entrada:</label>
<select class="form-select" v-model="inputFormat" @change="highlightCode">
<option value="auto">Auto-detectar</option>
<option value="json">JSON</option>
<option value="xml">XML</option>
<option value="phpSerialized">PHP Serializado</option>
</select>
</div>
<div class="col">
<label for="outputFormat" class="form-label">Formato de Salida:</label>
<select class="form-select" v-model="outputFormat">
<option value="json">JSON</option>
<option value="xml">XML</option>
<option value="phpSerialized">PHP Serializado</option>
</select>
</div>
</div>
<div class="text-center">
<button class="btn btn-primary mt-3 mb-3" @click="convertData" :disabled="loading">
<i :class="[loading ? 'fas fa-spinner fa-spin' : 'fas fa-exchange-alt']"></i>
<span v-if="!loading">Convertir</span>
<span v-else>Convirtiendo...</span>
</button>
</div>
<div class="output-container">
<label for="outputData" class="mt-4 form-label">Datos Convertidos:</label>
<textarea class="form-control" v-model="outputData" rows="6" readonly></textarea>
</div>
<div v-if="message" :class="{'text-success': success, 'text-danger': !success}" class="mt-3">
{{ message }}
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
<script src="js/index.js"></script>
</body>
</html>

94
public/index.php Normal file
View File

@ -0,0 +1,94 @@
<?php
require_once __DIR__ . '/../vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use FormatConverter\Converter\FormatConverter;
use Psr\Log\LoggerInterface;
$logger = new Logger('format_converter');
$logger->pushHandler(new StreamHandler(__DIR__ . '/../logs/app.log', Logger::DEBUG));
$converter = new FormatConverter($logger);
// Forwardeo al frontend
if ($_SERVER['REQUEST_URI'] === '/') {
header('Location: /index.html');
exit;
}
/**
* Maneja la conversión de formatos.
*/
function handleConversion(FormatConverter $converter)
{
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
sendErrorResponse(405, 'Método no permitido.');
return;
}
$inputData = file_get_contents('php://input');
$requestData = json_decode($inputData, true);
// Validar datos de entrada
if (json_last_error() !== JSON_ERROR_NONE || empty($requestData['inputData']) || empty($requestData['inputFormat']) || empty($requestData['outputFormat'])) {
sendErrorResponse(400, 'Solicitud no es válida. Asegúrese de que los datos están correctamente formateados.');
return;
}
$inputData = $requestData['inputData'];
$inputFormat = $requestData['inputFormat'];
$outputFormat = $requestData['outputFormat'];
if ($inputFormat === $outputFormat) {
sendErrorResponse(400, 'Los formatos de entrada y salida no pueden ser iguales.');
return;
}
try {
$convertedData = $converter->convert($inputFormat, $outputFormat, $inputData);
if ($convertedData === null) {
sendErrorResponse(500, 'Error interno en el servidor.');
} else {
sendSuccessResponse(['convertedData' => $convertedData]);
}
} catch (Exception $e) {
sendErrorResponse(500, 'Error en la conversión: ' . $e->getMessage());
}
}
/**
* Envía una respuesta JSON con éxito.
*
* @param array $data
*/
function sendSuccessResponse(array $data)
{
header('Content-Type: application/json');
echo json_encode([
'status' => 'success',
'data' => $data
]);
exit;
}
/**
* Envía una respuesta JSON de error.
*
* @param int $statusCode
* @param string $message
*/
function sendErrorResponse(int $statusCode, string $message)
{
http_response_code($statusCode);
header('Content-Type: application/json');
echo json_encode([
'status' => 'error',
'message' => $message
]);
exit;
}
handleConversion($converter);

109
public/js/index.js Normal file
View File

@ -0,0 +1,109 @@
new Vue({
el: '#app',
data() {
return {
inputData: '',
inputFormat: 'auto',
outputFormat: 'json',
outputData: '',
loading: false,
message: '',
success: false,
darkMode: false // para el modo oscuro
};
},
methods: {
// function para auto-detectar el formato de los datos de entrada
detectFormat(input) {
try {
JSON.parse(input);
return 'json';
} catch (e) {
// No es JSON
}
if (input.trim().startsWith('<') && input.trim().endsWith('>')) {
return 'xml';
}
if (/^a:\d+:\{.*\}$/.test(input)) {
return 'phpSerialized';
}
return 'unknown';
},
toggleDarkMode() {
this.darkMode = !this.darkMode; // Invertir el valor de darkMode
},
async convertData() {
this.message = '';
if (!this.inputData.trim()) {
this.showAlert('Por favor, ingrese los datos de entrada.', false);
return;
}
// Si el usuario seleccionó "auto", detectar el formato
if (this.inputFormat === 'auto') {
const detectedFormat = this.detectFormat(this.inputData);
if (detectedFormat === 'unknown') {
this.showAlert('No se pudo detectar el formato de entrada.', false);
return;
}
this.inputFormat = detectedFormat;
this.showAlert(`Formato detectado: ${detectedFormat.toUpperCase()}.`, true);
}
if (this.inputFormat === this.outputFormat) {
this.showAlert('Seleccione formatos diferentes para la conversión.', false);
return;
}
this.loading = true;
try {
const response = await fetch('/index.php', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
inputData: this.inputData,
inputFormat: this.inputFormat,
outputFormat: this.outputFormat
})
});
const result = await response.json();
if (response.ok) {
this.outputData = result.data.convertedData;
this.$nextTick(() => hljs.highlightElement(this.$refs.outputData));
this.showAlert('Conversión exitosa.', true);
} else {
this.outputData = 'Error en la conversión.';
this.showAlert(result.message || 'Error desconocido.', false);
}
} catch (error) {
console.error('Error:', error);
this.outputData = 'Error al convertir los datos.';
this.showAlert('Ocurrió un error al convertir los datos.', false);
} finally {
this.loading = false;
}
},
showAlert(message, success) {
this.message = message;
this.success = success;
}
},
watch: {
darkMode(val) {
if (val) {
document.body.classList.add('dark-mode');
} else {
document.body.classList.remove('dark-mode');
}
}
}
});

View File

@ -0,0 +1,18 @@
<?php
namespace FormatConverter\Adapters;
use FormatConverter\Interfaces\FormatAdapterInterface;
class JsonAdapter implements FormatAdapterInterface
{
public function deserialize(string $data)
{
return json_decode($data, true);
}
public function serialize($data): string
{
return json_encode($data, JSON_PRETTY_PRINT);
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace FormatConverter\Adapters;
use FormatConverter\Interfaces\FormatAdapterInterface;
class PhpSerializedAdapter implements FormatAdapterInterface
{
public function deserialize(string $data)
{
return unserialize($data);
}
public function serialize($data): string
{
return serialize($data);
}
}

View File

@ -0,0 +1,35 @@
<?php
namespace FormatConverter\Adapters;
use FormatConverter\Interfaces\FormatAdapterInterface;
use FormatConverter\Utils\ArrayToXml;
class XmlAdapter implements FormatAdapterInterface
{
public function deserialize(string $data)
{
$xml = simplexml_load_string($data, "SimpleXMLElement", LIBXML_NOCDATA);
return json_decode(json_encode($xml), true);
}
public function serialize($data): string
{
$xml = new \SimpleXMLElement('<?xml version="1.0"?><root></root>');
ArrayToXml::convert($data, $xml);
$rawXml = $xml->asXML();
try {
$dom = new \DOMDocument();
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
$dom->loadXML($rawXml);
// XML formateado
return $dom->saveXML();
} catch (\Exception $e) {
return $rawXml;
}
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace FormatConverter\Converter;
use FormatConverter\Interfaces\FormatAdapterInterface;
use FormatConverter\Adapters\JsonAdapter;
use FormatConverter\Adapters\XmlAdapter;
use FormatConverter\Adapters\PhpSerializedAdapter;
use Psr\Log\LoggerInterface;
class FormatConverter
{
private array $adapters = [];
private LoggerInterface $logger;
public function __construct(LoggerInterface $logger)
{
$this->logger = $logger;
$this->adapters = [
'json' => new JsonAdapter(),
'xml' => new XmlAdapter(),
'phpSerialized' => new PhpSerializedAdapter()
];
}
public function convert(string $inputFormat, string $outputFormat, string $data): ?string
{
try {
if (!isset($this->adapters[$inputFormat]) || !isset($this->adapters[$outputFormat])) {
throw new \InvalidArgumentException("Formatos no soportados.");
}
/** @var FormatAdapterInterface $inputAdapter */
$inputAdapter = $this->adapters[$inputFormat];
/** @var FormatAdapterInterface $outputAdapter */
$outputAdapter = $this->adapters[$outputFormat];
$transformedData = $inputAdapter->deserialize($data);
return $outputAdapter->serialize($transformedData);
} catch (\Exception $e) {
$this->logger->error('Error en la conversion de formatos' , ['exception' => $e]);
return null;
}
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace FormatConverter\Interfaces;
interface FormatAdapterInterface
{
/**
* Convertir data desde formato nativo a formato array|object de PHP
*
* @param string $data
* @return array|object
*/
public function deserialize(string $data);
/**
* Convertir data desde formato array|object de PHP a formato nativo
*
* @param array|object $data
* @return string
*/
public function serialize($data): string;
}

28
src/Utils/ArrayToXml.php Normal file
View File

@ -0,0 +1,28 @@
<?php
namespace FormatConverter\Utils;
class ArrayToXml
{
/**
* Convierte un array a XML.
*
* @param array|object $data
* @param \SimpleXMLElement $xml
*/
public static function convert($data, \SimpleXMLElement &$xml)
{
foreach ($data as $key => $value)
{
if (is_numeric($key)) {
$key = 'item';
}
if (is_array($value) || is_object($value)) {
$subnode = $xml->addChild($key);
self::convert($value, $subnode);
} else {
$xml->addChild("$key", htmlspecialchars("$value"));
}
}
}
}