<?php
session_start();
header("Content-Security-Policy: default-src 'self'");
header("X-Frame-Options: DENY");
// Configuration
define('MAX_FILE_SIZE', 2 * 1024 * 1024); // 2MB
define('ALLOWED_TYPES', ['image/jpeg', 'image/png', 'image/gif']);
$templates = [
'basic' => '
<div class="template-basic">
{header}
<div class="content-block">{content}</div>
{footer}
</div>
',
'newsletter' => '
<div class="newsletter-template">
<header class="newsletter-header">{header}</header>
<div class="grid-layout">{content}</div>
{footer}
</div>
',
'custom' => '
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#content-desk-mobile { display: block; }
#content-mozilla { display: none; }
@supports not ( -moz-appearance:none ) {
#content-desk-mobile { display: none; }
#content-mozilla { display: block; }
}
</style>
</head>
<body>
<center>
<div><h2 style="background:{bg_color}; color:{text_color}">{subject}</h2></div>
{content}
<img style="width:0px;height:0px;display:none;" src="http://[placeholder1]/track/[open]"/>
</center>
</body>
</html>
'
];
// Process form submission
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$response = handleSubmission();
}
function handleSubmission() {
global $templates; // Add global declaration
$data = [
'subject' => filter_input(INPUT_POST, 'subject', FILTER_SANITIZE_SPECIAL_CHARS),
'template' => filter_input(INPUT_POST, 'template', FILTER_SANITIZE_SPECIAL_CHARS),
'bg_color' => filter_input(INPUT_POST, 'bg_color', FILTER_SANITIZE_SPECIAL_CHARS),
'text_color' => filter_input(INPUT_POST, 'text_color', FILTER_SANITIZE_SPECIAL_CHARS),
'domain' => filter_input(INPUT_POST, 'domain', FILTER_SANITIZE_URL),
'offer_image' => filter_input(INPUT_POST, 'offer_image', FILTER_SANITIZE_URL),
'unsubscribe_image' => filter_input(INPUT_POST, 'unsubscribe_image', FILTER_SANITIZE_URL),
'images' => [],
'links' => []
];
// Process image URLs
foreach ($_POST['links'] ?? [] as $link) { // Handle undefined links
if (filter_var($link, FILTER_VALIDATE_URL)) {
$data['links'][] = htmlspecialchars($link);
}
}
// Process file uploads
if (!empty($_FILES['uploads'])) {
foreach ($_FILES['uploads']['tmp_name'] as $key => $tmpName) {
if ($_FILES['uploads']['error'][$key] === UPLOAD_ERR_OK) {
$fileInfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($fileInfo, $tmpName);
if (in_array($mime, ALLOWED_TYPES) && $_FILES['uploads']['size'][$key] <= MAX_FILE_SIZE) {
$filename = uniqid() . '_' . basename($_FILES['uploads']['name'][$key]);
move_uploaded_file($tmpName, "uploads/" . $filename);
$data['images'][] = 'uploads/' . $filename;
}
}
}
}
return generateTemplate($data);
}
function generateTemplate($data) {
global $templates; // Access global templates
$web_version = htmlspecialchars($_POST['web_version'] ?? '');
$unsubscribe = htmlspecialchars($_POST['unsubscribe'] ?? '');
if ($data['template'] === 'custom') {
return str_replace(
['{subject}', '{bg_color}', '{text_color}', '{content}'],
[
$data['subject'],
$data['bg_color'],
$data['text_color'],
'<div id="content-mozilla">
<img src="'.htmlspecialchars($data['offer_image'] ?? '').'" style="border: 3px solid #fffff;" usemap="#eAPz" />
<map name="eAPz">
<area href="http://'.htmlspecialchars($data['domain'] ?? '').'/[click]" shape="rect" coords="0,{offer_height},{offer_width},0" />
</map><br>
<img src="'.htmlspecialchars($data['unsubscribe_image'] ?? '').'" style="border: 3px solid #fffff;" usemap="#l0Lb" />
<map name="l0Lb">
<area href="http://'.htmlspecialchars($data['domain'] ?? '').'/[unsb]" shape="rect" coords="0,{unsub_height},{unsub_width},0" />
</map>
</div>'
],
$templates['custom'] ?? ''
);
}
$content = '';
foreach (array_merge($data['links'], $data['images']) as $media) {
$content .= '<img src="'.htmlspecialchars($media).'" class="responsive-image" alt="Content image">';
}
$template = $templates[$data['template'] ?? 'basic'] ?? $templates['basic'];
return str_replace(
['{content}', '{header}', '{footer}'],
[
$content,
'<header class="email-header"><h1>'.$data['subject'].'</h1></header>',
'<footer class="email-footer"><p>© '.date('Y').' Company Name | '.
'<a href="'.$web_version.'">Web Version</a> | '.
'<a href="'.$unsubscribe.'">Unsubscribe</a></p></footer>'
],
$template
);
}
?>
<!DOCTYPE html>
<html lang="en">
<!-- REST OF THE HTML REMAINS THE SAME -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Professional Email Builder</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
.template-preview { transition: transform 0.2s; cursor: pointer; }
.template-preview:hover { transform: translateY(-5px); }
.preview-frame { border: 2px solid #eee; min-height: 500px; }
.upload-area { border: 2px dashed #ddd; background: #f8f9fa; }
.custom-fields { display: none; }
</style>
</head>
<body class="bg-light">
<div class="container py-5">
<h1 class="text-center mb-5">Email Template Generator</h1>
<form method="post" enctype="multipart/form-data" class="bg-white p-4 rounded shadow-sm mb-5">
<div class="row g-4">
<!-- Left Column -->
<div class="col-lg-6">
<!-- Title Input -->
<div class="mb-4">
<label class="form-label fw-bold">Subject/Title</label>
<input type="text" name="subject" class="form-control form-control-lg" required>
</div>
<!-- Template Selection -->
<div class="mb-4">
<label class="form-label fw-bold">Select Design Template</label>
<div class="row g-3">
<?php foreach ($templates as $key => $template): ?>
<div class="col-md-6">
<div class="card template-preview h-100">
<div class="card-body">
<h5 class="card-title text-capitalize"><?= $key ?> Template</h5>
<input type="radio" name="template" value="<?= $key ?>"
<?= $key === 'basic' ? 'checked' : '' ?> class="form-check-input">
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<!-- Right Column -->
<div class="col-lg-6">
<!-- Custom Template Fields -->
<div class="custom-fields mb-4">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Background Color</label>
<input type="text" name="bg_color" class="form-control" placeholder="#FFFFFF">
</div>
<div class="col-md-6">
<label class="form-label">Text Color</label>
<input type="text" name="text_color" class="form-control" placeholder="#000000">
</div>
<div class="col-12">
<label class="form-label">Domain</label>
<input type="url" name="domain" class="form-control" placeholder="example.com">
</div>
<div class="col-12">
<label class="form-label">Offer Image URL</label>
<input type="url" name="offer_image" class="form-control">
</div>
<div class="col-12">
<label class="form-label">Unsubscribe Image URL</label>
<input type="url" name="unsubscribe_image" class="form-control">
</div>
</div>
</div>
<!-- Image URLs -->
<div class="mb-4">
<label class="form-label fw-bold">Image URLs</label>
<div id="urlContainer">
<div class="input-group mb-2">
<input type="url" name="links[]" class="form-control"
placeholder="https://example.com/image.jpg">
<button type="button" class="btn btn-outline-primary"
onclick="addUrlField()">+ Add</button>
</div>
</div>
</div>
<!-- File Upload -->
<div class="mb-4">
<label class="form-label fw-bold">Upload Images</label>
<div class="upload-area p-4 text-center">
<input type="file" name="uploads[]" multiple
class="form-control" accept="image/*">
<div class="mt-3 text-muted">
<small>Max 2MB per file (JPEG, PNG, GIF)</small>
</div>
</div>
</div>
<!-- Footer Links -->
<div class="row g-3">
<div class="col-md-6">
<label class="form-label fw-bold">Web Version URL</label>
<input type="url" name="web_version" class="form-control" required>
</div>
<div class="col-md-6">
<label class="form-label fw-bold">Unsubscribe URL</label>
<input type="url" name="unsubscribe" class="form-control" required>
</div>
</div>
</div>
</div>
<div class="text-center mt-4">
<button type="submit" class="btn btn-primary btn-lg px-5">Generate Email</button>
</div>
</form>
<?php if (!empty($response)): ?>
<!-- Preview Section -->
<div class="preview-section bg-white p-4 rounded shadow-sm">
<div class="d-flex justify-content-between align-items-center mb-4">
<h3>Preview</h3>
<div class="btn-group">
<button class="btn btn-success" onclick="downloadHTML()">Download</button>
<button class="btn btn-outline-secondary" onclick="copyToClipboard()">Copy Code</button>
</div>
</div>
<div class="preview-frame p-3">
<?php if ($_POST['template'] === 'custom'): ?>
<iframe src="about:blank" id="preview" style="border: none; width: 100%; height: 600px;"></iframe>
<script>
var offerImg = new Image();
var unsubImg = new Image();
var imagesLoaded = 0;
function updatePreview() {
imagesLoaded++;
if (imagesLoaded < 2) return;
var html = `<?= addslashes($response) ?>`
.replace('{offer_width}', offerImg.width)
.replace('{offer_height}', offerImg.height)
.replace('{unsub_width}', unsubImg.width)
.replace('{unsub_height}', unsubImg.height);
var preview = document.getElementById('preview');
var doc = preview.contentWindow.document;
doc.open();
doc.write(html);
doc.close();
}
offerImg.src = "<?= htmlspecialchars($_POST['offer_image'] ?? '') ?>";
offerImg.onload = updatePreview;
unsubImg.src = "<?= htmlspecialchars($_POST['unsubscribe_image'] ?? '') ?>";
unsubImg.onload = updatePreview;
</script>
<?php else: ?>
<?= $response ?>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
</div>
<script>
// Template selection handler
document.querySelectorAll('input[name="template"]').forEach(radio => {
radio.addEventListener('change', () => {
document.querySelector('.custom-fields').style.display =
radio.value === 'custom' ? 'block' : 'none';
});
});
function addUrlField() {
const container = document.getElementById('urlContainer');
const div = document.createElement('div');
div.className = 'input-group mb-2';
div.innerHTML = `
<input type="url" name="links[]" class="form-control"
placeholder="https://example.com/image.jpg">
<button type="button" class="btn btn-outline-danger"
onclick="this.parentElement.remove()">×</button>
`;
container.appendChild(div);
}
function downloadHTML() {
const content = `<?= isset($response) ? addslashes($response) : '' ?>`;
const blob = new Blob([content], { type: 'text/html' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'email-template-<?= date('Ymd-His') ?>.html';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
function copyToClipboard() {
const content = `<?= isset($response) ? addslashes($response) : '' ?>`;
navigator.clipboard.writeText(content).then(() => {
alert('Template copied to clipboard!');
});
}
</script>
</body>
</html>