Major additions: - Web-based setup wizard (setup.php, setup_wizard.php, setup-wizard.js) - Production Docker configuration (docker-compose.prod.yml, .env.production) - Database initialization SQL files (deploy/init_settings.sql) - Template builder system with drag-and-drop UI - Advanced features (OAuth, CDN, enhanced analytics, monetization) - Comprehensive documentation (deployment guides, quick start, feature docs) - Design system with accessibility and responsive layout - Deployment automation scripts (deploy.ps1, generate-secrets.ps1) Setup wizard allows customization of: - Platform name and branding - Domain configuration - Membership tiers and pricing - Admin credentials - Feature toggles Database includes 270+ tables for complete video streaming platform with advanced features for analytics, moderation, template building, and monetization. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
329 lines
7.9 KiB
PHP
329 lines
7.9 KiB
PHP
<?php
|
|
/**
|
|
* Template Builder AJAX Handler
|
|
* Handles all AJAX requests for the template builder
|
|
*/
|
|
|
|
// Include core configuration
|
|
require_once dirname(__FILE__) . '/../../f_core/config.core.php';
|
|
|
|
// Check if user is logged in
|
|
if (!isset($_SESSION['USER_ID']) || $_SESSION['USER_ID'] <= 0) {
|
|
http_response_code(401);
|
|
echo json_encode(['success' => false, 'error' => 'Unauthorized']);
|
|
exit;
|
|
}
|
|
|
|
// Initialize template builder class
|
|
require_once $cfg['classes_dir'] . '/class.templatebuilder.php';
|
|
$templateBuilder = new VTemplateBuilder();
|
|
|
|
// Get request data
|
|
$action = isset($_GET['action']) ? $_GET['action'] : (isset($_POST['action']) ? $_POST['action'] : '');
|
|
|
|
// Handle different actions
|
|
switch ($action) {
|
|
case 'get_components':
|
|
handleGetComponents($templateBuilder);
|
|
break;
|
|
|
|
case 'create_template':
|
|
handleCreateTemplate($templateBuilder);
|
|
break;
|
|
|
|
case 'update_template':
|
|
handleUpdateTemplate($templateBuilder);
|
|
break;
|
|
|
|
case 'delete_template':
|
|
handleDeleteTemplate($templateBuilder);
|
|
break;
|
|
|
|
case 'get_template':
|
|
handleGetTemplate($templateBuilder);
|
|
break;
|
|
|
|
case 'get_templates':
|
|
handleGetTemplates($templateBuilder);
|
|
break;
|
|
|
|
case 'publish_template':
|
|
handlePublishTemplate($templateBuilder);
|
|
break;
|
|
|
|
case 'duplicate_template':
|
|
handleDuplicateTemplate($templateBuilder);
|
|
break;
|
|
|
|
case 'preview':
|
|
handlePreview($templateBuilder);
|
|
break;
|
|
|
|
case 'render':
|
|
handleRender($templateBuilder);
|
|
break;
|
|
|
|
default:
|
|
http_response_code(400);
|
|
echo json_encode(['success' => false, 'error' => 'Invalid action']);
|
|
break;
|
|
}
|
|
|
|
/**
|
|
* Get all available components
|
|
*/
|
|
function handleGetComponents($templateBuilder)
|
|
{
|
|
$category = isset($_GET['category']) ? $_GET['category'] : null;
|
|
$components = $templateBuilder->getComponents($category);
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'components' => $components
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Create new template
|
|
*/
|
|
function handleCreateTemplate($templateBuilder)
|
|
{
|
|
$data = getJsonInput();
|
|
|
|
if (!$data) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid request data']);
|
|
return;
|
|
}
|
|
|
|
$result = $templateBuilder->createTemplate($data);
|
|
echo json_encode($result);
|
|
}
|
|
|
|
/**
|
|
* Update existing template
|
|
*/
|
|
function handleUpdateTemplate($templateBuilder)
|
|
{
|
|
$data = getJsonInput();
|
|
|
|
if (!$data || !isset($data['template_id'])) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid request data']);
|
|
return;
|
|
}
|
|
|
|
$templateId = (int)$data['template_id'];
|
|
$changeNote = isset($data['change_note']) ? $data['change_note'] : null;
|
|
|
|
$result = $templateBuilder->updateTemplate($templateId, $data, $changeNote);
|
|
echo json_encode($result);
|
|
}
|
|
|
|
/**
|
|
* Delete template
|
|
*/
|
|
function handleDeleteTemplate($templateBuilder)
|
|
{
|
|
$data = getJsonInput();
|
|
|
|
if (!$data || !isset($data['template_id'])) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid request data']);
|
|
return;
|
|
}
|
|
|
|
$templateId = (int)$data['template_id'];
|
|
$result = $templateBuilder->deleteTemplate($templateId);
|
|
echo json_encode($result);
|
|
}
|
|
|
|
/**
|
|
* Get template by ID
|
|
*/
|
|
function handleGetTemplate($templateBuilder)
|
|
{
|
|
$templateId = isset($_GET['template_id']) ? (int)$_GET['template_id'] : 0;
|
|
|
|
if ($templateId <= 0) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid template ID']);
|
|
return;
|
|
}
|
|
|
|
$template = $templateBuilder->getTemplate($templateId);
|
|
|
|
if ($template) {
|
|
echo json_encode(['success' => true, 'template' => $template]);
|
|
} else {
|
|
echo json_encode(['success' => false, 'error' => 'Template not found']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get all templates for current user
|
|
*/
|
|
function handleGetTemplates($templateBuilder)
|
|
{
|
|
$filters = [];
|
|
|
|
if (isset($_GET['template_type'])) {
|
|
$filters['template_type'] = $_GET['template_type'];
|
|
}
|
|
|
|
if (isset($_GET['is_active'])) {
|
|
$filters['is_active'] = (int)$_GET['is_active'];
|
|
}
|
|
|
|
if (isset($_GET['limit'])) {
|
|
$filters['limit'] = (int)$_GET['limit'];
|
|
}
|
|
|
|
$templates = $templateBuilder->getUserTemplates($filters);
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'templates' => $templates,
|
|
'count' => count($templates)
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Publish template (make active)
|
|
*/
|
|
function handlePublishTemplate($templateBuilder)
|
|
{
|
|
$data = getJsonInput();
|
|
|
|
if (!$data || !isset($data['template_id'])) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid request data']);
|
|
return;
|
|
}
|
|
|
|
$templateId = (int)$data['template_id'];
|
|
|
|
$result = $templateBuilder->updateTemplate($templateId, [
|
|
'is_active' => 1
|
|
], 'Published template');
|
|
|
|
echo json_encode($result);
|
|
}
|
|
|
|
/**
|
|
* Duplicate template
|
|
*/
|
|
function handleDuplicateTemplate($templateBuilder)
|
|
{
|
|
$data = getJsonInput();
|
|
|
|
if (!$data || !isset($data['template_id'])) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid request data']);
|
|
return;
|
|
}
|
|
|
|
$templateId = (int)$data['template_id'];
|
|
$newName = isset($data['new_name']) ? $data['new_name'] : null;
|
|
|
|
$result = $templateBuilder->duplicateTemplate($templateId, $newName);
|
|
echo json_encode($result);
|
|
}
|
|
|
|
/**
|
|
* Preview template
|
|
*/
|
|
function handlePreview($templateBuilder)
|
|
{
|
|
$templateId = isset($_GET['template_id']) ? (int)$_GET['template_id'] : 0;
|
|
|
|
if ($templateId <= 0) {
|
|
echo 'Invalid template ID';
|
|
return;
|
|
}
|
|
|
|
$template = $templateBuilder->getTemplate($templateId, false);
|
|
|
|
if (!$template) {
|
|
echo 'Template not found';
|
|
return;
|
|
}
|
|
|
|
// Render template
|
|
$html = $templateBuilder->renderTemplate($templateId);
|
|
|
|
// Output as HTML page
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Preview: <?php echo htmlspecialchars($template['template_name']); ?></title>
|
|
<link rel="stylesheet" href="<?php echo $cfg['styles_url']; ?>/init0.min.css">
|
|
<link rel="stylesheet" href="<?php echo $cfg['styles_url']; ?>/theme/theme.min.css">
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
padding: 20px;
|
|
background: #f5f5f5;
|
|
}
|
|
.preview-container {
|
|
max-width: <?php echo $template['template_structure']['max_width'] ?? 1200; ?>px;
|
|
margin: 0 auto;
|
|
background: white;
|
|
padding: 20px;
|
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="preview-container">
|
|
<?php echo $html; ?>
|
|
</div>
|
|
</body>
|
|
</html>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Render template (for frontend display)
|
|
*/
|
|
function handleRender($templateBuilder)
|
|
{
|
|
$templateId = isset($_GET['template_id']) ? (int)$_GET['template_id'] : 0;
|
|
$slug = isset($_GET['slug']) ? $_GET['slug'] : '';
|
|
|
|
if ($templateId > 0) {
|
|
$html = $templateBuilder->renderTemplate($templateId);
|
|
} elseif ($slug) {
|
|
$html = $templateBuilder->renderTemplate($slug);
|
|
} else {
|
|
echo json_encode(['success' => false, 'error' => 'Template ID or slug required']);
|
|
return;
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'html' => $html
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get JSON input from request body
|
|
*/
|
|
function getJsonInput()
|
|
{
|
|
$input = file_get_contents('php://input');
|
|
|
|
if (empty($input)) {
|
|
return $_POST;
|
|
}
|
|
|
|
$data = json_decode($input, true);
|
|
|
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
|
VLogger::log('ERROR', 'JSON decode error in template builder AJAX', [
|
|
'error' => json_last_error_msg(),
|
|
'input' => substr($input, 0, 1000)
|
|
]);
|
|
return null;
|
|
}
|
|
|
|
return $data;
|
|
}
|