Agregar archivo .gitignore y eliminar archivos innecesarios
This commit is contained in:
commit
31e66fb310
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal 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
21
composer.json
Normal 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
388
composer.lock
generated
Normal 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
128
public/css/main.css
Normal 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
73
public/index.html
Normal 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
94
public/index.php
Normal 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
109
public/js/index.js
Normal 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');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
18
src/Adapters/JsonAdapter.php
Normal file
18
src/Adapters/JsonAdapter.php
Normal 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);
|
||||
}
|
||||
}
|
17
src/Adapters/PhpSerializedAdapter.php
Normal file
17
src/Adapters/PhpSerializedAdapter.php
Normal 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);
|
||||
}
|
||||
}
|
35
src/Adapters/XmlAdapter.php
Normal file
35
src/Adapters/XmlAdapter.php
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
46
src/Converter/FormatConverter.php
Normal file
46
src/Converter/FormatConverter.php
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
22
src/Interfaces/FormatAdapterInterface.php
Normal file
22
src/Interfaces/FormatAdapterInterface.php
Normal 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
28
src/Utils/ArrayToXml.php
Normal 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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user