Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
135 changes: 135 additions & 0 deletions etc/db/migration-1.0.3.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
<?php
/**
* Migration: Create landing_page_content table for managing home page sections
* Version: 1.0.3
*/

use App\Core\Database;

$pdo = Database::connect();

// Create the landing_page_content table (DDL cannot be in a transaction)
$pdo->exec("
CREATE TABLE IF NOT EXISTS `landing_page_content` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`section` varchar(50) NOT NULL,
`field_key` varchar(100) NOT NULL,
`field_value` text DEFAULT NULL,
`field_type` enum('string','rich','image') NOT NULL DEFAULT 'string',
`created_at` timestamp NULL DEFAULT current_timestamp(),
`updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
PRIMARY KEY (`id`),
UNIQUE KEY `section_field` (`section`, `field_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
");

// Insert default content using prepared statements (handles special characters properly)
$stmt = $pdo->prepare("
INSERT INTO `landing_page_content` (`section`, `field_key`, `field_value`, `field_type`)
VALUES (:section, :field_key, :field_value, :field_type)
");

// Home Section
$stmt->execute([
'section' => 'home',
'field_key' => 'hero_subtitle',
'field_value' => 'A New Era of Chaos Begins',
'field_type' => 'string'
]);

$stmt->execute([
'section' => 'home',
'field_key' => 'hero_description',
'field_value' => 'Dive into an epic multiverse where heroes unite against the forces of chaos. From the depths of the Skibidi universe to the realms of Marvel, DC, Star Wars, and beyond.',
'field_type' => 'rich'
]);

// About Section
$stmt->execute([
'section' => 'about',
'field_key' => 'title',
'field_value' => 'The Story Unfolds',
'field_type' => 'string'
]);

$aboutText = '<h3>A New Chapter in the Skibidi Universe</h3>
<p>
Welcome to <strong>Skibidi Madness</strong> - an extraordinary animation series created by FireStormX Studios
that transcends the boundaries of the original Skibidi Toilet universe. This isn\'t just another story;
it\'s a revolutionary fusion of multiple dimensions, timelines, and realities. It\'s a celebration of creativity, imagination, and the limitless possibilities
of storytelling.
</p>
<p>
In this new saga, witness the unprecedented chaos unleashed by the malevolent forces known as the
<strong>Asotra</strong>. Unlike previous battles against entire armies, our heroes now face their
most formidable adversary yet - the mysterious and powerful <strong>Supreme Leader</strong>,
whose ambitions threaten not just one universe, but the entire multiverse fabric.
</p>
<p>
Skibidi Madness weaves together elements from beloved franchises including Marvel\'s cosmic battles,
the supernatural mysteries of Stranger Things, DC\'s legendary heroes, the epic space opera of Star Wars,
the blocky realms of Minecraft, and countless other dimensions. This is where everything you love
collides in spectacular fashion.
</p>';

$stmt->execute([
'section' => 'about',
'field_key' => 'about_text',
'field_value' => $aboutText,
'field_type' => 'rich'
]);

// About Section - Image (default to existing static image path)
$stmt->execute([
'section' => 'about',
'field_key' => 'image',
'field_value' => '/public/media/img/all-together.png',
'field_type' => 'image'
]);

// Episodes Section
$stmt->execute([
'section' => 'episodes',
'field_key' => 'title',
'field_value' => 'Featured Episodes',
'field_type' => 'string'
]);

$stmt->execute([
'section' => 'episodes',
'field_key' => 'subtitle',
'field_value' => 'Watch the epic battles and witness the chaos unfold',
'field_type' => 'rich'
]);

// Heroes Section
$stmt->execute([
'section' => 'heroes',
'field_key' => 'title',
'field_value' => 'The Legendary Heroes',
'field_type' => 'string'
]);

$stmt->execute([
'section' => 'heroes',
'field_key' => 'subtitle',
'field_value' => 'Meet the champions who stand between order and absolute chaos',
'field_type' => 'rich'
]);

// Channel Section
$stmt->execute([
'section' => 'channel',
'field_key' => 'title',
'field_value' => 'Join the FireStormX Community',
'field_type' => 'string'
]);

$stmt->execute([
'section' => 'channel',
'field_key' => 'subtitle',
'field_value' => 'Subscribe to FireStormX Studios on YouTube to never miss an episode of Skibidi Madness! Get exclusive behind-the-scenes content, character reveals, and be part of the growing community of fans exploring the multiverse.',
'field_type' => 'rich'
]);

return true;
17 changes: 17 additions & 0 deletions etc/db/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,16 @@ CREATE TABLE `heroes` (
`enabled` tinyint(1) DEFAULT 1
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `landing_page_content` (
`id` int(11) NOT NULL,
`section` varchar(50) NOT NULL,
`field_key` varchar(100) NOT NULL,
`field_value` text DEFAULT NULL,
`field_type` enum('string','rich','image') NOT NULL DEFAULT 'string',
`created_at` timestamp NULL DEFAULT current_timestamp(),
`updated_at` timestamp NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `migrations` (
`id` int(11) NOT NULL,
`version` int(11) NOT NULL,
Expand Down Expand Up @@ -128,6 +138,10 @@ ALTER TABLE `heroes`
ADD KEY `idx_slug` (`slug`),
ADD KEY `idx_order` (`display_order`);

ALTER TABLE `landing_page_content`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `section_field` (`section`, `field_key`);

ALTER TABLE `migrations`
ADD PRIMARY KEY (`id`),
ADD UNIQUE KEY `version` (`version`);
Expand Down Expand Up @@ -164,6 +178,9 @@ ALTER TABLE `episodes`
ALTER TABLE `heroes`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

ALTER TABLE `landing_page_content`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

ALTER TABLE `migrations`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

Expand Down
23 changes: 23 additions & 0 deletions src/Controller/Admin/Landing.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Controller\Admin;

use App\Controller\AdminController;
use App\Model\LandingPageContent;

class Landing extends AdminController
{
public function handle(): void
{
$sections = LandingPageContent::getAllSections();
$sectionsConfig = LandingPageContent::getSectionsConfig();

$this->render(
'admin/landing',
[
'sections' => $sections,
'sectionsConfig' => $sectionsConfig,
]
);
}
}
93 changes: 93 additions & 0 deletions src/Controller/Admin/Landing/Update.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace App\Controller\Admin\Landing;

use App\Controller\AdminController;
use App\Core\Config;
use App\Model\LandingPageContent;

class Update extends AdminController
{
public function handle(): void
{
if ($this->getRequest()->isPost()) {
$this->updateContent();
$this->redirect('/admin/landing');
}

// Redirect to landing page if accessed via GET
$this->redirect('/admin/landing');
}

protected function updateContent(): void
{
$landingData = $this->getRequest()->post('landing');

if (!is_array($landingData)) {
return;
}

$sectionsConfig = LandingPageContent::getSectionsConfig();

foreach ($landingData as $section => $fields) {
if (!isset($sectionsConfig[$section])) {
continue;
}

foreach ($fields as $fieldKey => $value) {
if (!isset($sectionsConfig[$section]['fields'][$fieldKey])) {
continue;
}

$fieldType = $sectionsConfig[$section]['fields'][$fieldKey]['type'];

// Handle image uploads
if ($fieldType === LandingPageContent::FIELD_TYPE_IMAGE) {
$uploadedImage = $this->handleImageUpload($section, $fieldKey);
if ($uploadedImage) {
$value = $uploadedImage;
}
}

LandingPageContent::setValue($section, $fieldKey, $value, $fieldType);
}
}
}

protected function handleImageUpload(string $section, string $fieldKey): ?string
{
$fileKey = "landing_image_{$section}_{$fieldKey}";
$files = $this->getRequest()->files($fileKey);

if (empty($files) || empty($files[0]['tmp_name'])) {
return null;
}

$file = $files[0];

// Validate file
$allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
if (!in_array($file['type'], $allowedTypes)) {
return null;
}

// Generate upload path
$uploadDir = Config::get('upload_dir') . 'landing/';
$fullPath = Config::get('root') . $uploadDir;

if (!is_dir($fullPath)) {
mkdir($fullPath, 0755, true);
}

// Generate unique filename
$extension = pathinfo($file['name'], PATHINFO_EXTENSION);
$filename = uniqid("{$section}_{$fieldKey}_", true) . '.' . $extension;
$filePath = $fullPath . $filename;

if (move_uploaded_file($file['tmp_name'], $filePath)) {
return $uploadDir . $filename;
}

return null;
}
}
30 changes: 23 additions & 7 deletions src/Controller/Admin/Social.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,44 @@

use App\Controller\AdminController;
use App\Core\Model\CollectionInterface;
use App\Model\Episode;
use App\Model\SocialLink;

class Social extends AdminController
{
public function handle(): void
{
$collection = $this->getSocialLinks();

// Handle pagination
$page = max(1, (int)$this->getRequest('page', 1));
$pageSize = (int)$this->getRequest('pageSize', 10);

if ($pageSize < 1) {
$pageSize = 10;
}

$collection->setPageSize($pageSize);
$collection->setPage($page);

$this->render(
'admin/episodes',
'admin/social',
[
'episodes' => $this->getPEpisodes()
'socialLinks' => $collection,
'currentPage' => $collection->getPage(),
'totalPages' => $collection->getPages(),
'pageSize' => $pageSize,
'totalCount' => $collection->count()
]
);
}

protected function getPEpisodes()
protected function getSocialLinks()
{
$episodeCollection = (new Episode())
$socialLinksCollection = (new SocialLink())
->getCollection()
->setItemMode(CollectionInterface::ITEM_MODE_OBJECT)
->sort('created_at', 'DESC');
->sort('display_order', 'ASC');

return $episodeCollection;
return $socialLinksCollection;
}
}
19 changes: 19 additions & 0 deletions src/Controller/Admin/Social/Add.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Controller\Admin\Social;

use App\Controller\AdminController;
use App\Model\SocialLink;

class Add extends AdminController
{
public function handle(): void
{
$this->render(
'admin/social/form',
[
'socialLink' => new SocialLink()
]
);
}
}
21 changes: 21 additions & 0 deletions src/Controller/Admin/Social/Delete.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace App\Controller\Admin\Social;

use App\Controller\AdminController;
use App\Model\SocialLink;

class Delete extends AdminController
{
public function handle(): void
{
$id = $this->getRequest('id');

if ($id) {
$socialLink = new SocialLink();
$socialLink->delete((int)$id);
}

$this->redirect('/admin/social');
}
}
Loading