FILE 1: /home/custom-concert-ticket.digitalprank.com/public_html/tool_config.json code JSON { "tool": { "identity": { "slug": "custom-concert-ticket", "name": "Custom Concert Tickets", "category": "prank", "tagline": "Design hilarious custom concert tickets with custom names, venues, and QR codes!", "description": "Create realistic-looking custom concert tickets for fun, pranks, or party props. Customize artist, venue, seat, date, and even add a custom QR code. Perfect for birthdays, jokes, or creative projects.", "keywords": ["custom ticket", "concert prank", "ticket generator", "event ticket", "digital prank"] }, "features": { "bulk_enabled": false, "history_enabled": true, "export_enabled": true, "api_enabled": true }, "fields": [ { "id": "artist_name", "type": "text", "label": "Artist or Band Name", "placeholder": "e.g., Taylor Swift", "required": true, "validation": { "min_length": 2, "max_length": 100 }, "pro_only": false }, { "id": "venue_name", "type": "text", "label": "Venue Name", "placeholder": "e.g., Madison Square Garden", "required": true, "validation": { "min_length": 2, "max_length": 100 }, "pro_only": false }, { "id": "concert_date", "type": "date", "label": "Concert Date", "required": true, "pro_only": false }, { "id": "seat_info", "type": "text", "label": "Seat Info", "placeholder": "e.g., Section A, Row 2, Seat 14", "required": true, "validation": { "min_length": 5, "max_length": 50 }, "pro_only": false }, { "id": "template_style", "type": "select", "label": "Ticket Template", "default": "classic", "options": [ { "value": "classic", "label": "Classic Ticket" }, { "value": "modern", "label": "Modern E-Ticket" }, { "value": "vip_gold", "label": "VIP Gold Style (Pro)" } ], "pro_only": false }, { "id": "custom_qr", "type": "checkbox", "label": "Add Custom QR Code", "default": true, "pro_only": false }, { "id": "upload_logo", "type": "file", "label": "Upload Custom Logo (Tour/Event)", "required": false, "pro_only": true }, { "id": "remove_watermark", "type": "checkbox", "label": "Remove Watermark", "default": false, "pro_only": true } ], "limits": { "tier_daily": { "free": 3, "basic": 20, "gold": 200, "ultimate": -1 }, "rate_limit_per_minute": 8, "max_concurrent_requests": 2 }, "billing": { "credit_cost": 1, "one_off_enabled": true, "one_off_price_cents": 199, "bill_on": "success" }, "ui": { "theme": { "primary_color": "#B22222", "secondary_color": "#2c2c2c" }, "layout": { "show_sidebar_ads": true, "form_style": "card", "result_display": "inline" } }, "dependencies": { "php_extensions": ["gd", "json", "mbstring"], "system_packages": ["imagemagick"], "python_packages": ["pillow", "reportlab"], "external_apis": [], "requires_internet": false }, "database": { "tool_specific_table": "custom_concert_tickets", "store_results": true, "enable_history": true, "retention_days": 90 }, "seo": { "meta_title": "Custom Concert Ticket Generator | Design Prank Tickets Online", "meta_description": "Create custom concert tickets for fun! Customize artist, venue, date, seat, and QR code. Download high-res prank tickets instantly.", "canonical_url": "https://digitalprank.com/tools/custom-concert-ticket", "structured_data": { "type": "WebApplication", "category": "Entertainment" } }, "help": { "quick_start": [ "Step 1: Enter artist and venue name.", "Step 2: Select the date and seat info.", "Step 3: Pick a template and optional logo.", "Step 4: Generate your custom ticket!", "Step 5: Download and share it with friends." ], "faq": [ { "question": "Are these tickets real?", "answer": "No. These are completely custom and intended for pranks or creative use only." }, { "question": "Can I remove the watermark?", "answer": "Yes, watermark removal is available for Pro users only." }, { "question": "Can I print these tickets?", "answer": "Yes, they are high resolution and suitable for printing or digital use." } ], "examples": [ { "title": "Taylor Swift VIP Prank", "description": "A custom VIP ticket to a sold-out Taylor Swift concert to prank a superfan.", "input": { "artist_name": "Taylor Swift", "venue_name": "Madison Square Garden", "concert_date": "2025-11-01", "seat_info": "VIP Zone, Row A, Seat 1", "template_style": "vip_gold" } }, { "title": "Classic Rock Comeback Tour", "description": "Design a retro-looking ticket for a custom reunion tour.", "input": { "artist_name": "The Rocking Fossils", "venue_name": "Old Arena Center", "concert_date": "2026-04-15", "seat_info": "Section D, Row 12, Seat 8", "template_style": "classic" } } ] }, "monitoring": { "track_usage": true, "track_performance": true, "error_reporting": true, "analytics_events": [ "ticket_generated", "pro_upgrade", "download_ticket" ] }, "security": { "input_sanitization": true, "csrf_protection": true, "rate_limiting": true, "max_input_length": 500, "allowed_file_types": ["png", "jpg", "jpeg", "svg"] }, "version": { "schema": "3.0.0", "tool": "1.0.0", "api_version": "v1" } } }``` ### FILE 2: /home/custom-concert-ticket.digitalprank.com/public_html/processor.php ```php false, 'message' => 'An unknown error occurred.', 'data' => null, 'usage' => null, 'access' => null, 'features' => null, ]; // --- Database Connection --- $db_host = 'localhost'; $db_name = 'digitalprank_db'; $db_user = 'dp_user'; $db_pass = '#$Dealer2355'; $pdo = null; try { $pdo = new PDO("mysql:host=$db_host;dbname=$db_name;charset=utf8mb4", $db_user, $db_pass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // --- Load Tool Configuration --- $config_json = file_get_contents('tool_config.json'); $config = json_decode($config_json, true)['tool']; $tool_slug = $config['identity']['slug']; // --- Security & Input --- if ($_SERVER['REQUEST_METHOD'] !== 'POST') { throw new Exception('Invalid request method.'); } if (empty($_POST['csrf_token']) || !hash_equals($_SESSION['csrf_token'], $_POST['csrf_token'])) { throw new Exception('Invalid CSRF token.'); } $input = $_POST; // --- User & Access Control --- $user_id = isset($_SESSION['user_id']) ? intval($_SESSION['user_id']) : 0; $user_ip = $_SERVER['REMOTE_ADDR']; $access = getUserAccessLevel($pdo, $user_id, $tool_slug); $response['access'] = $access; // --- Usage Limits --- $daily_limit = $config['limits']['tier_daily'][$access['tier']]; if ($daily_limit !== -1) { if (!checkDailyUsage($pdo, $tool_slug, $user_ip, $user_id, $daily_limit)) { throw new Exception('Daily usage limit exceeded. Upgrade to a higher tier for more access.'); } } // --- Field Overrides & Permissions --- $field_overrides = getToolFieldOverrides($pdo, $tool_slug); $response['features'] = $field_overrides; // --- Input Validation --- $validated_input = []; foreach ($config['fields'] as $field) { $field_id = $field['id']; // Check if field is disabled via override if (isset($field_overrides[$field_id]) && $field_overrides[$field_id]['override_type'] === 'disabled') { continue; } // Check tier access for the field if (isset($field_overrides[$field_id]) && $field_overrides[$field_id]['override_type'] === 'tier') { if (!$access['has_tier_access'][$field_overrides[$field_id]['tier_required']]) { if (isset($input[$field_id]) && !empty($input[$field_id])) { throw new Exception("You need to upgrade your plan to use the '{$field['label']}' feature."); } continue; } } if ($field['pro_only'] && !$access['has_pro_access']) { if ((isset($input[$field_id]) && $input[$field_id]) || (isset($_FILES[$field_id]) && $_FILES[$field_id]['error'] === 0)) { throw new Exception("The feature '{$field['label']}' is for Pro users only."); } } if ($field['type'] === 'file') { if (isset($_FILES[$field_id]) && $_FILES[$field_id]['error'] === 0) { $validated_input[$field_id] = $_FILES[$field_id]; } else { $validated_input[$field_id] = null; } } else { $value = isset($input[$field_id]) ? trim($input[$field_id]) : ($field['default'] ?? null); if ($field['required'] && empty($value)) { throw new Exception("Field '{$field['label']}' is required."); } if (!empty($value) && isset($field['validation'])) { if (isset($field['validation']['min_length']) && mb_strlen($value) < $field['validation']['min_length']) { throw new Exception("'{$field['label']}' must be at least {$field['validation']['min_length']} characters long."); } if (isset($field['validation']['max_length']) && mb_strlen($value) > $field['validation']['max_length']) { throw new Exception("'{$field['label']}' must not exceed {$field['validation']['max_length']} characters."); } } $validated_input[$field_id] = htmlspecialchars($value, ENT_QUOTES, 'UTF-8'); } } // Pro-only template style check if ($validated_input['template_style'] === 'vip_gold' && !$access['has_pro_access']) { throw new Exception("The 'VIP Gold Style' template is for Pro users only."); } // {{TOOL_PROCESSING_START}} $width = 800; $height = 300; $image = imagecreatetruecolor($width, $height); $artist = $validated_input['artist_name']; $venue = $validated_input['venue_name']; $date = strtoupper(date("d M Y", strtotime($validated_input['concert_date']))); $time = "08:00 PM"; $seat_info = $validated_input['seat_info']; $template = $validated_input['template_style']; $add_qr = !empty($validated_input['custom_qr']); // Define fonts - assuming they are in a known path $font_bold = '/home/cdn.digitalprank.com/public_html/assets/fonts/arialbd.ttf'; $font_regular = '/home/cdn.digitalprank.com/public_html/assets/fonts/arial.ttf'; if (!file_exists($font_bold) || !file_exists($font_regular)) { throw new Exception("Font files are missing from the server."); } // Template specific colors and layout switch($template) { case 'vip_gold': $bg_color = imagecolorallocate($image, 218, 165, 32); // Gold $text_color = imagecolorallocate($image, 0, 0, 0); $accent_color = imagecolorallocate($image, 255, 255, 255); break; case 'modern': $bg_color = imagecolorallocate($image, 18, 18, 18); // Dark Grey $text_color = imagecolorallocate($image, 255, 255, 255); $accent_color = imagecolorallocate($image, 255, 0, 0); // Red break; case 'classic': default: $bg_color = imagecolorallocate($image, 245, 245, 220); // Beige $text_color = imagecolorallocate($image, 0, 0, 0); $accent_color = imagecolorallocate($image, 50, 50, 50); break; } imagefill($image, 0, 0, $bg_color); // Draw content based on template if ($template === 'classic') { imagettftext($image, 30, 0, 25, 70, $text_color, $font_bold, $artist); imagettftext($image, 16, 0, 25, 120, $accent_color, $font_regular, 'at ' . $venue); imagettftext($image, 14, 0, 25, 180, $text_color, $font_regular, "DATE: $date"); imagettftext($image, 14, 0, 25, 210, $text_color, $font_regular, "TIME: $time"); imagettftext($image, 18, 0, 25, 260, $text_color, $font_bold, $seat_info); // Perforated line $line_color = imagecolorallocatealpha($image, 0, 0, 0, 80); for ($i = 0; $i < $height; $i += 10) { imageline($image, 580, $i, 580, $i + 5, $line_color); } imagettftext($image, 12, 90, 600, 280, $accent_color, $font_regular, "ADMIT ONE"); imagettftext($image, 20, 90, 640, 280, $text_color, $font_bold, $seat_info); } elseif ($template === 'modern') { imagettftext($image, 32, 0, 220, 70, $text_color, $font_bold, $artist); imagettftext($image, 14, 0, 220, 110, $accent_color, $font_regular, "LIVE ON STAGE"); imagettftext($image, 12, 0, 220, 160, $text_color, $font_regular, $venue); imagettftext($image, 12, 0, 220, 190, $text_color, $font_regular, "$date // $time"); imagettftext($image, 16, 0, 220, 240, $text_color, $font_bold, $seat_info); } elseif ($template === 'vip_gold') { $border_color = imagecolorallocate($image, 50, 50, 50); imagerectangle($image, 5, 5, $width - 6, $height - 6, $border_color); imagerectangle($image, 6, 6, $width - 7, $height - 7, $border_color); imagettftext($image, 35, 0, 25, 80, $text_color, $font_bold, $artist); imagettftext($image, 20, 0, 27, 120, $accent_color, $font_bold, "*** VIP ACCESS ***"); imagettftext($image, 14, 0, 25, 170, $text_color, $font_regular, $venue); imagettftext($image, 14, 0, 25, 200, $text_color, $font_regular, "$date AT $time"); imagettftext($image, 16, 0, 25, 250, $text_color, $font_bold, $seat_info); } // Add QR Code if checked if ($add_qr) { // Using a static custom QR code image for prank purposes $custom_qr_path = '/home/cdn.digitalprank.com/public_html/assets/images/custom_qr_code.png'; if(file_exists($custom_qr_path)) { $qr_img = imagecreatefrompng($custom_qr_path); if ($template === 'modern') { imagecopyresized($qr_img, $qr_img, 0, 0, 0, 0, 150, 150, imagesx($qr_img), imagesy($qr_img)); imagecopy($image, $qr_img, 30, 75, 0, 0, 150, 150); } else { imagecopyresized($qr_img, $qr_img, 0, 0, 0, 0, 120, 120, imagesx($qr_img), imagesy($qr_img)); imagecopy($image, $qr_img, $width - 150, 90, 0, 0, 120, 120); } imagedestroy($qr_img); } } // Add custom logo if uploaded and user has access $logo_path = null; if ($access['has_pro_access'] && isset($validated_input['upload_logo'])) { $file = $validated_input['upload_logo']; $allowed_types = $config['security']['allowed_file_types']; $file_ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); if (in_array($file_ext, $allowed_types)) { $logo_src = null; switch ($file_ext) { case 'png': $logo_src = imagecreatefrompng($file['tmp_name']); break; case 'jpg': case 'jpeg': $logo_src = imagecreatefromjpeg($file['tmp_name']); break; // SVG would require imagick, skipping for GD implementation simplicity } if ($logo_src) { imagecopyresized($image, $logo_src, 650, 20, 0, 0, 120, 50, imagesx($logo_src), imagesy($logo_src)); imagedestroy($logo_src); // In a real scenario, you'd move the uploaded file to a permanent location $logo_path = 'uploads/' . basename($file['name']); } } } // Add watermark if not a Pro user or if "remove watermark" is not checked $remove_watermark = $access['has_pro_access'] && !empty($validated_input['remove_watermark']); if (!$remove_watermark) { $watermark_color = imagecolorallocatealpha($image, 150, 150, 150, 80); imagettftext($image, 10, 0, $width - 165, $height - 15, $watermark_color, $font_regular, "digitalprank.com"); } // Capture image output ob_start(); imagepng($image); $image_data = ob_get_contents(); ob_end_clean(); imagedestroy($image); $base64_image = base64_encode($image_data); $output_data = ['image' => $base64_image, 'format' => 'png']; // Store in database if enabled if ($config['database']['store_results']) { $sql = "INSERT INTO custom_concert_tickets (user_id, artist_name, venue_name, concert_date, seat_info, template_style, has_qr_code, custom_logo_path, was_watermark_removed, created_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())"; $stmt = $pdo->prepare($sql); $stmt->execute([ $user_id, $validated_input['artist_name'], $validated_input['venue_name'], $validated_input['concert_date'], $validated_input['seat_info'], $validated_input['template_style'], $add_qr ? 1 : 0, $logo_path, $remove_watermark ? 1 : 0 ]); } // {{TOOL_PROCESSING_END}} $response['success'] = true; $response['message'] = 'Custom concert ticket generated successfully!'; $response['data'] = $output_data; $processing_time = microtime(true) - $start_time; logUsage($pdo, $tool_slug, $user_ip, $user_id, 'generate_success', $validated_input, ['result_size' => strlen($base64_image)], $processing_time); $response['usage'] = ['credits_used' => $config['billing']['credit_cost']]; } catch (Exception $e) { $response['success'] = false; $response['message'] = $e->getMessage(); $processing_time = microtime(true) - $start_time; $user_id = isset($_SESSION['user_id']) ? intval($_SESSION['user_id']) : 0; $user_ip = $_SERVER['REMOTE_ADDR']; $tool_slug = isset($config['identity']['slug']) ? $config['identity']['slug'] : 'unknown_tool'; $input_data = isset($validated_input) ? $validated_input : $_POST; if ($pdo) { logUsage($pdo, $tool_slug, $user_ip, $user_id, 'generate_failed', $input_data, ['error' => $e->getMessage()], $processing_time); } } echo json_encode($response); FILE 3: /home/custom-concert-ticket.digitalprank.com/public_html/tool_form.php code PHP <?php echo htmlspecialchars($config['identity']['name']); ?> - DigitalPrank

'; break; case 'select': echo ''; break; case 'checkbox': echo ''; break; case 'file': echo ''; break; } ?>
FILE 4: /home/custom-concert-ticket.digitalprank.com/public_html/diagnostic.php code PHP $description$icon$message"; } ?> System Diagnostic: Custom Concert Tickets

System Diagnostic: Custom Concert Tickets

Core Checks

='); check("PHP Version >= 8.1.0", $php_ok, "Current: " . PHP_VERSION); // Config File $config_path = 'tool_config.json'; $config_exists = file_exists($config_path); check("Configuration file exists", $config_exists, $config_path); $config_data = null; if ($config_exists) { $config_data = json_decode(file_get_contents($config_path), true); $config_valid = json_last_error() === JSON_ERROR_NONE && isset($config_data['tool']['identity']['slug']); check("Configuration file is valid JSON", $config_valid, json_last_error_msg()); } else { check("Configuration file is valid JSON", false, "File not found"); } ?>
CheckStatusDetails

Database Checks

getMessage()); } if ($db_connected) { $tables_to_check = [ 'wp_digitalprank_tools', 'wp_digitalprank_usage', 'wp_digitalprank_usage_log', 'wp_pms_member_subscriptions', 'wp_digitalprank_entitlements', 'wp_digitalprank_tool_overrides', $config_data['tool']['database']['tool_specific_table'] ?? 'custom_concert_tickets' ]; foreach ($tables_to_check as $table) { try { $result = $pdo->query("SELECT 1 FROM `$table` LIMIT 1"); check("Table '$table' exists", $result !== false); } catch (Exception $e) { check("Table '$table' exists", false, $e->getMessage()); } } } ?>
CheckStatusDetails

Dependencies Check

&1'; $output = shell_exec($command); $py_ok = empty($output); check("Python Packages: ($packages)", $py_ok, $py_ok ? "All imported successfully" : "Failed: " . $output); } } else { check("Dependencies Check", false, "Skipped due to invalid config."); } ?>
CheckStatusDetails

Tool-Specific Functionality

CheckStatusDetails
FILE 5: /home/custom-concert-ticket.digitalprank.com/public_html/help.md code Markdown # Custom Concert Ticket Generator Help Create realistic-looking custom concert tickets for fun, pranks, or party props. Customize artist, venue, seat, date, and even add a custom QR code. Perfect for birthdays, jokes, or creative projects. ## Quick Start Guide Here’s how to get your custom ticket in seconds: 1. **Step 1:** Enter artist and venue name. 2. **Step 2:** Select the date and seat info. 3. **Step 3:** Pick a template and optional logo. 4. **Step 4:** Generate your custom ticket! 5. **Step 5:** Download and share it with friends. ## Features * **Artist or Band Name:** The main act for your custom concert. * **Venue Name:** Where the event is supposedly taking place. * **Concert Date:** The date of the concert. * **Seat Info:** Specifics like Section, Row, and Seat number. * **Ticket Template:** Choose from different visual styles: * **Classic Ticket:** A retro, paper-style ticket. * **Modern E-Ticket:** A darker, more contemporary design. * **VIP Gold Style (Pro):** A premium, gold-themed design for Pro users. * **Add Custom QR Code:** Adds a generic QR code image to make the ticket look more authentic. * **Upload Custom Logo (Tour/Event) (Pro):** Pro users can upload their own logo (e.g., a tour logo) to be placed on the ticket. * **Remove Watermark (Pro):** Pro users can remove the "digitalprank.com" watermark from the generated ticket. ## Frequently Asked Questions (FAQ) ### Are these tickets real? No. These are completely custom and intended for pranks or creative use only. They will not grant you access to any event. ### Can I remove the watermark? Yes, watermark removal is a premium feature available for Pro users only. ### Can I print these tickets? Yes, they are high resolution and suitable for printing or digital use. You can download the generated image and print it at your convenience. ## Usage Examples ### 1. Taylor Swift VIP Prank **Description:** A custom VIP ticket to a sold-out Taylor Swift concert to prank a superfan. **Input:** * **Artist or Band Name:** Taylor Swift * **Venue Name:** Madison Square Garden * **Concert Date:** 2025-11-01 * **Seat Info:** VIP Zone, Row A, Seat 1 * **Ticket Template:** VIP Gold Style (Pro) ### 2. Classic Rock Comeback Tour **Description:** Design a retro-looking ticket for a custom reunion tour. **Input:** * **Artist or Band Name:** The Rocking Fossils * **Venue Name:** Old Arena Center * **Concert Date:** 2026-04-15 * **Seat Info:** Section D, Row 12, Seat 8 * **Ticket Template:** Classic Ticket ```### FILE 6: /home/digitalprank.com/public_html/blog/data/tools/custom-concert-ticket.json ```json { "slug": "custom-concert-ticket", "name": "Custom Concert Ticket Generator", "meta_title": "Custom Concert Ticket Generator | Design Prank Tickets Online", "meta_description": "Create custom concert tickets for fun! Customize artist, venue, date, seat, and QR code. Download high-res prank tickets instantly.", "canonical_url": "https://digitalprank.com/tools/custom-concert-ticket", "category": "prank", "tagline": "Design hilarious custom concert tickets with custom names, venues, and QR codes!", "long_description": "Ever wanted to prank a friend into thinking they got tickets to a sold-out show? Our Custom Concert Ticket Generator lets you do just that! Create incredibly realistic-looking tickets for any artist, at any venue. Perfect for birthday gifts, inside jokes, social media posts, or creative props. It's fast, easy, and endlessly fun.", "features_list": [ { "name": "Fully Customizable Text", "description": "Enter any artist, band, venue, date, and seating information you can imagine.", "is_pro": false }, { "name": "Multiple Ticket Templates", "description": "Choose from Classic, Modern, and our exclusive VIP Gold styles to match the vibe of your event.", "is_pro": false }, { "name": "Custom QR Code", "description": "Add a realistic-looking (but non-functional) QR code to enhance the ticket's authenticity.", "is_pro": false }, { "name": "Custom Logo Upload", "description": "Pro members can upload a custom tour or event logo for ultimate personalization.", "is_pro": true }, { "name": "Watermark Removal", "description": "Get a clean, unbranded ticket image with our Pro-only watermark removal feature.", "is_pro": true }, { "name": "High-Resolution Output", "description": "Download your ticket as a high-quality PNG, perfect for printing or sharing online.", "is_pro": false } ], "technical_details": { "output_format": "PNG (image/png)", "image_dimensions": "800x300 pixels", "dependencies": "PHP-GD for image creation, custom fonts for text rendering." }, "user_guide": { "title": "How to Create Your Custom Ticket", "steps": [ "Fill in the artist name, venue, and date fields.", "Enter the desired seat information (e.g., Section 101, Row C, Seat 5).", "Select a template from the dropdown menu. Choose 'VIP Gold Style' for a premium look (Pro only).", "Decide if you want to include the custom QR code.", "If you're a Pro user, you can upload a logo or check the 'Remove Watermark' box.", "Click 'Generate Ticket' and wait for your image to appear.", "Right-click to save or use the download link provided." ] }, "structured_data": { "@context": "https://schema.org", "@type": "WebApplication", "name": "Custom Concert Ticket Generator", "description": "Create custom concert tickets for fun! Customize artist, venue, date, seat, and QR code. Download high-res prank tickets instantly.", "applicationCategory": "EntertainmentApplication", "operatingSystem": "Any (Web-based)", "url": "https://digitalprank.com/tools/custom-concert-ticket", "offers": { "@type": "Offer", "price": "0.00", "priceCurrency": "USD" }, "publisher": { "@type": "Organization", "name": "DigitalPrank", "url": "https://digitalprank.com" } } } FILE 7: /home/custom-concert-ticket.digitalprank.com/public_html/deploy.sh code Bash #!/bin/bash set -e TOOL_SLUG="custom-concert-ticket" VHOST_DIR="/home/${TOOL_SLUG}.digitalprank.com" PUBLIC_DIR="${VHOST_DIR}/public_html" DB_NAME="digitalprank_db" DB_USER="dp_user" DB_PASS="#$Dealer2355" echo "--- Starting deployment for ${TOOL_SLUG} ---" # 1. Install System Packages echo "[1/7] Installing system packages..." sudo apt-get update sudo apt-get install -y imagemagick # 2. Install PHP Extensions echo "[2/7] Installing PHP extensions..." sudo apt-get install -y php8.1-gd php8.1-mbstring # 3. Create Python Virtual Environment and install packages echo "[3/7] Setting up Python environment..." VENV_DIR="/var/www/venvs/${TOOL_SLUG}" mkdir -p /var/www/venvs python3 -m venv "$VENV_DIR" source "${VENV_DIR}/bin/activate" pip install --upgrade pip pip install pillow reportlab deactivate echo "Python venv created at ${VENV_DIR}" # 4. Create tool-specific database table echo "[4/7] Creating database table 'custom_concert_tickets'..." SQL_CREATE=" CREATE TABLE IF NOT EXISTS \`custom_concert_tickets\` ( \`id\` BIGINT PRIMARY KEY AUTO_INCREMENT, \`user_id\` BIGINT, \`artist_name\` VARCHAR(100) NOT NULL, \`venue_name\` VARCHAR(100) NOT NULL, \`concert_date\` DATE NOT NULL, \`seat_info\` VARCHAR(50) NOT NULL, \`template_style\` VARCHAR(20) NOT NULL, \`has_qr_code\` TINYINT(1) DEFAULT 0, \`custom_logo_path\` VARCHAR(255) NULL, \`was_watermark_removed\` TINYINT(1) DEFAULT 0, \`generated_image_path\` VARCHAR(255) NULL, \`created_at\` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX \`user_id_idx\` (\`user_id\`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; " mysql -u "$DB_USER" -p"$DB_PASS" "$DB_NAME" -e "$SQL_CREATE" echo "Database table check/creation complete." # 5. Create directories and set permissions echo "[5/7] Setting up directories and permissions..." mkdir -p "$PUBLIC_DIR" mkdir -p "${VHOST_DIR}/logs" # A temporary directory for image generation or uploads, if needed by processor.php mkdir -p "${VHOST_DIR}/tmp" sudo chown -R www-data:www-data "$VHOST_DIR" sudo chmod -R 755 "$VHOST_DIR" sudo chmod -R 775 "${VHOST_DIR}/tmp" # Writable by the web server echo "Directory structure created." # 6. Configure OpenLiteSpeed Virtual Host echo "[6/7] Configuring OpenLiteSpeed vhost..." VHOST_CONF_PATH="/usr/local/lsws/conf/vhosts/${TOOL_SLUG}.conf" VHOST_CONF_CONTENT=" virtualHost ${TOOL_SLUG} { vhRoot ${PUBLIC_DIR} configFile \$SERVER_ROOT/conf/vhosts/default/vhost.conf docRoot \$VH_ROOT vhDomain ${TOOL_SLUG}.digitalprank.com rewrite { enable 1 rules """ # Standard WordPress rules if this were a WP site, but for standalone PHP it's simpler RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^/(.*)$ /index.php?/$1 [L] """ } } " # This is a simulation. In a real environment, this would be appended or managed via an API. echo "Creating vhost config at ${VHOST_CONF_PATH}" sudo sh -c "echo '${VHOST_CONF_CONTENT}' > ${VHOST_CONF_PATH}" echo "VHost configuration created. Please restart OpenLiteSpeed to apply changes." # 7. Configure Log Rotation echo "[7/7] Setting up log rotation..." LOGROTATE_CONF=" ${VHOST_DIR}/logs/*.log { daily missingok rotate 14 compress delaycompress notifempty create 640 www-data adm sharedscripts } " sudo sh -c "echo '${LOGROTATE_CONF}' > /etc/logrotate.d/${TOOL_SLUG}" echo "Log rotation configured." echo "--- Deployment for ${TOOL_SLUG} complete! ---" echo "IMPORTANT: Restart OpenLiteSpeed for the new virtual host to take effect: sudo /usr/local/lsws/bin/lswsctrl restart"