393 lines
18 KiB
PHP
Executable File
393 lines
18 KiB
PHP
Executable File
<?php
|
|
require_once __DIR__ . '/includes/db.php';
|
|
require_once __DIR__ . '/includes/session_check.php';
|
|
require_once __DIR__ . '/includes/i18n.php';
|
|
checkSession();
|
|
require_once __DIR__ . '/includes/activity_logger.php';
|
|
|
|
$pageTitle = t('Plantillas de Mensajes');
|
|
|
|
$templates = [];
|
|
$galleryImages = [];
|
|
|
|
try {
|
|
$pdo = getDbConnection();
|
|
$stmt = $pdo->query("SELECT * FROM recurrent_messages ORDER BY name");
|
|
$templates = $stmt->fetchAll();
|
|
|
|
// Cargar imágenes de la galería
|
|
$galleryPath = __DIR__ . '/galeria';
|
|
if (is_dir($galleryPath)) {
|
|
$files = scandir($galleryPath);
|
|
foreach ($files as $file) {
|
|
if (in_array(strtolower(pathinfo($file, PATHINFO_EXTENSION)), ['jpg', 'jpeg', 'png', 'gif', 'webp'])) {
|
|
$galleryImages[] = $file;
|
|
}
|
|
}
|
|
}
|
|
} catch (Exception $e) {
|
|
$error = $e->getMessage();
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
$action = $_POST['action'] ?? '';
|
|
|
|
if ($action === 'create') {
|
|
$stmt = $pdo->prepare("INSERT INTO recurrent_messages (name, message_content, telegram_command, created_at, updated_at) VALUES (?, ?, ?, NOW(), NOW())");
|
|
$stmt->execute([
|
|
$_POST['name'],
|
|
$_POST['message_content'],
|
|
$_POST['telegram_command'] ?? null
|
|
]);
|
|
|
|
logActivity(getCurrentUserId(), 'create_template', 'Plantilla creada: ' . $_POST['name']);
|
|
header('Location: recurrentes.php');
|
|
exit;
|
|
|
|
} elseif ($action === 'update') {
|
|
$stmt = $pdo->prepare("UPDATE recurrent_messages SET name = ?, message_content = ?, telegram_command = ?, updated_at = NOW() WHERE id = ?");
|
|
$stmt->execute([
|
|
$_POST['name'],
|
|
$_POST['message_content'],
|
|
$_POST['telegram_command'] ?? null,
|
|
$_POST['id']
|
|
]);
|
|
|
|
logActivity(getCurrentUserId(), 'update_template', 'Plantilla actualizada: ' . $_POST['name']);
|
|
header('Location: recurrentes.php');
|
|
exit;
|
|
|
|
} elseif ($action === 'delete') {
|
|
$stmt = $pdo->prepare("DELETE FROM recurrent_messages WHERE id = ?");
|
|
$stmt->execute([$_POST['id']]);
|
|
|
|
logActivity(getCurrentUserId(), 'delete_template', 'Plantilla eliminada ID: ' . $_POST['id']);
|
|
header('Location: recurrentes.php');
|
|
exit;
|
|
}
|
|
}
|
|
|
|
require_once __DIR__ . '/templates/header.php';
|
|
?>
|
|
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<h2><i class="bi bi-collection"></i> <?= t('Plantillas de Mensajes') ?></h2>
|
|
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#templateModal">
|
|
<i class="bi bi-plus-circle"></i> <?= t('Nueva Plantilla') ?>
|
|
</button>
|
|
</div>
|
|
|
|
<?php if (isset($error)): ?>
|
|
<div class="alert alert-danger"><?= htmlspecialchars($error) ?></div>
|
|
<?php endif; ?>
|
|
|
|
<div class="row">
|
|
<?php if (empty($templates)): ?>
|
|
<div class="col-12">
|
|
<p class="text-muted text-center py-4"><?= t('No hay plantillas creadas') ?></p>
|
|
</div>
|
|
<?php else: ?>
|
|
<?php foreach ($templates as $template): ?>
|
|
<div class="col-md-6 mb-4">
|
|
<div class="card border-0 shadow-sm h-100">
|
|
<div class="card-header border-0 d-flex justify-content-between align-items-center">
|
|
<h5 class="mb-0"><?= htmlspecialchars($template['name']) ?></h5>
|
|
<div class="btn-group btn-group-sm">
|
|
<button class="btn btn-outline-primary" onclick="editTemplate(<?= htmlspecialchars(json_encode($template)) ?>)">
|
|
<i class="bi bi-pencil"></i>
|
|
</button>
|
|
<form method="POST" onsubmit="return confirm('<?= t('¿Eliminar esta plantilla?') ?>');" class="d-inline">
|
|
<input type="hidden" name="action" value="delete">
|
|
<input type="hidden" name="id" value="<?= $template['id'] ?>">
|
|
<button type="submit" class="btn btn-outline-danger">
|
|
<i class="bi bi-trash"></i>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="text-muted small mb-2">
|
|
<i class="bi bi-terminal"></i> <?= t('Comando') ?>: <code>#<?= htmlspecialchars($template['telegram_command'] ?? t('sin comando')) ?></code>
|
|
</p>
|
|
<div class="bg-light p-2 rounded mb-2" style="max-height: 100px; overflow-y: auto; font-size: 0.85rem;">
|
|
<?= strip_tags(substr($template['message_content'], 0, 200)) ?><?= strlen($template['message_content']) > 200 ? '...' : '' ?>
|
|
</div>
|
|
<button class="btn btn-sm btn-outline-info" data-bs-toggle="modal" data-bs-target="#previewModal<?= $template['id'] ?>">
|
|
<i class="bi bi-eye"></i> <?= t('Ver preview') ?>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
|
|
<!-- Modal de Plantilla -->
|
|
<div class="modal fade" id="templateModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<form method="POST">
|
|
<input type="hidden" name="action" value="create" id="modalAction">
|
|
<input type="hidden" name="id" value="" id="templateId">
|
|
|
|
<div class="modal-header">
|
|
<h5 class="modal-title" id="modalTitle"><?= t('Nueva Plantilla') ?></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
<div class="mb-3">
|
|
<label class="form-label"><?= t('Nombre') ?></label>
|
|
<input type="text" name="name" class="form-control" required id="templateName">
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label"><?= t('Comando de Telegram (sin #)') ?></label>
|
|
<input type="text" name="telegram_command" class="form-control" placeholder="<?= t('ejemplo') ?>" id="templateCommand">
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label class="form-label"><?= t('Contenido') ?></label>
|
|
<textarea name="message_content" class="form-control" rows="10" required id="templateContent"></textarea>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?= t('Cancelar') ?></button>
|
|
<button type="submit" class="btn btn-primary"><?= t('Guardar') ?></button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Modal de Galería -->
|
|
<div class="modal fade" id="galleryModal" tabindex="-1">
|
|
<div class="modal-dialog modal-lg modal-dialog-scrollable">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title"><i class="bi bi-images"></i> <?= t('Galería de Imágenes') ?></h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="row g-3">
|
|
<?php if (empty($galleryImages)): ?>
|
|
<div class="col-12 text-center text-muted py-5">
|
|
<i class="bi bi-images" style="font-size: 3rem;"></i>
|
|
<p class="mt-3"><?= t('No hay imágenes en la galería') ?></p>
|
|
</div>
|
|
<?php else: ?>
|
|
<?php foreach ($galleryImages as $image): ?>
|
|
<div class="col-md-3 col-sm-4 col-6">
|
|
<div class="card h-100 cursor-pointer" onclick="insertImageToTemplate('galeria/<?= urlencode($image) ?>')" style="cursor: pointer;">
|
|
<img src="galeria/<?= urlencode($image) ?>" class="card-img-top" alt="<?= htmlspecialchars($image) ?>" style="height: 120px; object-fit: cover;">
|
|
<div class="card-body p-2">
|
|
<small class="text-muted text-truncate d-block"><?= htmlspecialchars($image) ?></small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<?php foreach ($templates as $template): ?>
|
|
<!-- Modal de Preview para <?= htmlspecialchars($template['name']) ?> -->
|
|
<div class="modal fade" id="previewModal<?= $template['id'] ?>" tabindex="-1">
|
|
<div class="modal-dialog modal-lg">
|
|
<div class="modal-content">
|
|
<div class="modal-header">
|
|
<h5 class="modal-title">
|
|
<i class="bi bi-eye"></i> <?= t('Preview') ?>: <?= htmlspecialchars($template['name']) ?>
|
|
</h5>
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
|
</div>
|
|
<div class="modal-body">
|
|
<ul class="nav nav-tabs mb-3" role="tablist">
|
|
<li class="nav-item">
|
|
<button class="nav-link active" data-bs-toggle="tab" data-bs-target="#previewDiscord<?= $template['id'] ?>">
|
|
<i class="bi bi-discord"></i> Discord
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#previewTelegram<?= $template['id'] ?>">
|
|
<i class="bi bi-telegram"></i> Telegram
|
|
</button>
|
|
</li>
|
|
<li class="nav-item">
|
|
<button class="nav-link" data-bs-toggle="tab" data-bs-target="#previewHtml<?= $template['id'] ?>">
|
|
<i class="bi bi-code-slash"></i> HTML
|
|
</button>
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="tab-content">
|
|
<div class="tab-pane fade show active" id="previewDiscord<?= $template['id'] ?>">
|
|
<div class="bg-dark text-white p-3 rounded" style="font-family: 'Whitney', 'Helvetica Neue', Helvetica, Arial, sans-serif;">
|
|
<div class="d-flex align-items-start mb-2">
|
|
<div class="rounded-circle bg-primary me-2" style="width: 40px; height: 40px; display: flex; align-items: center; justify-content: center;">
|
|
<i class="bi bi-robot"></i>
|
|
</div>
|
|
<div>
|
|
<div class="fw-bold text-primary">Bot</div>
|
|
<div style="color: #dcddde; white-space: pre-wrap;">
|
|
<?php
|
|
require_once __DIR__ . '/discord/converters/HtmlToDiscordMarkdownConverter.php';
|
|
$converter = new Discord\Converters\HtmlToDiscordMarkdownConverter();
|
|
$discordContent = $converter->convert($template['message_content']);
|
|
echo nl2br(htmlspecialchars($discordContent));
|
|
?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="tab-pane fade" id="previewTelegram<?= $template['id'] ?>">
|
|
<div class="bg-light p-3 rounded" style="background: linear-gradient(180deg, #f5f5f5 0%, #e8e8e8 100%); border-radius: 10px;">
|
|
<div class="d-flex align-items-start mb-2">
|
|
<div class="rounded-circle bg-info me-2" style="width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; color: white;">
|
|
<i class="bi bi-telegram"></i>
|
|
</div>
|
|
<div class="bg-white p-2 rounded" style="max-width: 80%; box-shadow: 0 1px 2px rgba(0,0,0,0.1);">
|
|
<div class="fw-bold text-info mb-1">Bot</div>
|
|
<div style="white-space: pre-wrap;">
|
|
<?php
|
|
require_once __DIR__ . '/telegram/converters/HtmlToTelegramHtmlConverter.php';
|
|
$converter = new Telegram\Converters\HtmlToTelegramHtmlConverter();
|
|
$telegramContent = $converter->convert($template['message_content']);
|
|
echo $telegramContent;
|
|
?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="tab-pane fade" id="previewHtml<?= $template['id'] ?>">
|
|
<div class="border rounded p-3 bg-white">
|
|
<h6><?= t('Renderizado') ?>:</h6>
|
|
<div class="border rounded p-3 mb-3 bg-light">
|
|
<?= $template['message_content'] ?>
|
|
</div>
|
|
<h6><?= t('Código HTML') ?>:</h6>
|
|
<pre class="bg-dark text-light p-3 rounded" style="max-height: 200px; overflow-y: auto;"><code><?= htmlspecialchars($template['message_content']) ?></code></pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal"><?= t('Cerrar') ?></button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
|
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote-lite.min.js"></script>
|
|
|
|
<script>
|
|
const galleryImages = <?= json_encode($galleryImages) ?>;
|
|
const i18n = {
|
|
editTemplate: '<?= t('Editar Plantilla') ?>',
|
|
gallery: '<?= t('Galería') ?>',
|
|
insertImage: '<?= t('Insertar imagen desde galería') ?>',
|
|
newTemplate: '<?= t('Nueva Plantilla') ?>'
|
|
};
|
|
|
|
function editTemplate(template) {
|
|
document.getElementById('modalAction').value = 'update';
|
|
document.getElementById('modalTitle').textContent = i18n.editTemplate;
|
|
document.getElementById('templateId').value = template.id;
|
|
document.getElementById('templateName').value = template.name;
|
|
document.getElementById('templateCommand').value = template.telegram_command || '';
|
|
|
|
// Inicializar Summernote para edición
|
|
$('#templateContent').summernote({
|
|
height: 250,
|
|
toolbar: [
|
|
['style', ['bold', 'italic', 'underline', 'clear']],
|
|
['font', ['strikethrough', 'superscript', 'subscript']],
|
|
['fontsize', ['fontsize']],
|
|
['color', ['color']],
|
|
['para', ['ul', 'ol', 'paragraph']],
|
|
['height', ['height']],
|
|
['insert', ['link', 'video', 'gallery']],
|
|
['view', ['fullscreen', 'codeview']]
|
|
],
|
|
buttons: {
|
|
gallery: function() {
|
|
return $.summernote.ui.button({
|
|
contents: '<i class="bi bi-images"></i> ' + i18n.gallery,
|
|
tooltip: i18n.insertImage,
|
|
click: function() {
|
|
$('#galleryModal').modal('show');
|
|
}
|
|
}).render();
|
|
}
|
|
}
|
|
});
|
|
|
|
$('#templateContent').summernote('code', template.message_content);
|
|
|
|
const modal = new bootstrap.Modal(document.getElementById('templateModal'));
|
|
modal.show();
|
|
}
|
|
|
|
function insertImageToTemplate(url) {
|
|
const imgTag = '<img src="' + url + '" style="max-width: 100%; height: auto;">';
|
|
$('#templateContent').summernote('editor.pasteHTML', imgTag);
|
|
$('#galleryModal').modal('hide');
|
|
}
|
|
|
|
$(document).ready(function() {
|
|
// Inicializar Summernote cuando se abre el modal para crear nueva plantilla
|
|
$('#templateModal').on('shown.bs.modal', function(e) {
|
|
if (document.getElementById('modalAction').value === 'create') {
|
|
$('#templateContent').summernote({
|
|
height: 250,
|
|
toolbar: [
|
|
['style', ['bold', 'italic', 'underline', 'clear']],
|
|
['font', ['strikethrough', 'superscript', 'subscript']],
|
|
['fontsize', ['fontsize']],
|
|
['color', ['color']],
|
|
['para', ['ul', 'ol', 'paragraph']],
|
|
['height', ['height']],
|
|
['insert', ['link', 'video', 'gallery']],
|
|
['view', ['fullscreen', 'codeview']]
|
|
],
|
|
buttons: {
|
|
gallery: function() {
|
|
return $.summernote.ui.button({
|
|
contents: '<i class="bi bi-images"></i> ' + i18n.gallery,
|
|
tooltip: i18n.insertImage,
|
|
click: function() {
|
|
$('#galleryModal').modal('show');
|
|
}
|
|
}).render();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
$('#templateModal').on('hidden.bs.modal', function() {
|
|
document.getElementById('modalAction').value = 'create';
|
|
document.getElementById('modalTitle').textContent = i18n.newTemplate;
|
|
document.getElementById('templateId').value = '';
|
|
document.getElementById('templateName').value = '';
|
|
document.getElementById('templateCommand').value = '';
|
|
if ($('#templateContent').summernote) {
|
|
$('#templateContent').summernote('destroy');
|
|
}
|
|
document.getElementById('templateContent').value = '';
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<?php require_once __DIR__ . '/templates/footer.php'; ?>
|