diff --git a/src/media/css/colors/dark/colors_alternative.css b/src/media/css/colors/dark/colors_alternative.css index 988b0a9..6545599 100644 --- a/src/media/css/colors/dark/colors_alternative.css +++ b/src/media/css/colors/dark/colors_alternative.css @@ -9,7 +9,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/css/global/dark/colors_alternative.css - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Alternative dark mode color definitions for Moko-Cassiopeia template */ diff --git a/src/media/css/colors/dark/colors_standard.css b/src/media/css/colors/dark/colors_standard.css index f95e635..0ee864c 100644 --- a/src/media/css/colors/dark/colors_standard.css +++ b/src/media/css/colors/dark/colors_standard.css @@ -9,7 +9,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/css/global/dark/colors_standard.css - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Standard dark mode color definitions for Moko-Cassiopeia template */ diff --git a/src/media/css/colors/light/colors_alternative.css b/src/media/css/colors/light/colors_alternative.css index 49b5675..efb3765 100644 --- a/src/media/css/colors/light/colors_alternative.css +++ b/src/media/css/colors/light/colors_alternative.css @@ -9,7 +9,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/css/global/light/colors_alternative.css - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Alternative light mode color definitions for Moko-Cassiopeia template */ diff --git a/src/media/css/colors/light/colors_standard.css b/src/media/css/colors/light/colors_standard.css index ac6a85c..735c2c1 100644 --- a/src/media/css/colors/light/colors_standard.css +++ b/src/media/css/colors/light/colors_standard.css @@ -9,7 +9,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/css/global/light/colors_standard.css - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Standard light mode color definitions for Moko-Cassiopeia template */ diff --git a/src/media/css/editor.css b/src/media/css/editor.css index 426b3a5..5ff97fc 100644 --- a/src/media/css/editor.css +++ b/src/media/css/editor.css @@ -9,7 +9,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/css/editor.css - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Stylesheet for Joomla editor content within Moko-Cassiopeia template */ diff --git a/src/media/css/system/searchtools/searchtools.css b/src/media/css/system/searchtools/searchtools.css index 33281d5..da3ccef 100644 --- a/src/media/css/system/searchtools/searchtools.css +++ b/src/media/css/system/searchtools/searchtools.css @@ -9,7 +9,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/css/system/searchtools/searchtools.css - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Stylesheet for Joomla search tools integration in Moko-Cassiopeia template */ diff --git a/src/media/css/template-rtl.css b/src/media/css/template-rtl.css index 55e8898..35d5797 100644 --- a/src/media/css/template-rtl.css +++ b/src/media/css/template-rtl.css @@ -9,7 +9,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/css/template-rtl.css - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Right-to-left (RTL) layout stylesheet for Moko-Cassiopeia template */ diff --git a/src/media/css/template.css b/src/media/css/template.css index e025344..c28b77d 100644 --- a/src/media/css/template.css +++ b/src/media/css/template.css @@ -9,7 +9,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/css/template.css - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Main stylesheet providing layout, typography, and component styles for Moko-Cassiopeia */ diff --git a/src/media/js/darkmode-toggle.js b/src/media/js/darkmode-toggle.js index 84b8281..664d66d 100644 --- a/src/media/js/darkmode-toggle.js +++ b/src/media/js/darkmode-toggle.js @@ -8,7 +8,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/js/darkmode-toggle.js - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: JavaScript logic for dark mode toggle functionality in Moko-Cassiopeia */ diff --git a/src/media/js/mod_menu/menu-metismenu-es5.js b/src/media/js/mod_menu/menu-metismenu-es5.js index e17e87a..7b621ee 100644 --- a/src/media/js/mod_menu/menu-metismenu-es5.js +++ b/src/media/js/mod_menu/menu-metismenu-es5.js @@ -8,7 +8,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/js/mod_menu/menu-metismenu-es5.js - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: ES5-compatible MetisMenu script for Joomla mod_menu in Moko-Cassiopeia */ diff --git a/src/media/js/mod_menu/menu-metismenu.js b/src/media/js/mod_menu/menu-metismenu.js index 4133a5a..66f0bbf 100644 --- a/src/media/js/mod_menu/menu-metismenu.js +++ b/src/media/js/mod_menu/menu-metismenu.js @@ -8,7 +8,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/js/mod_menu/menu-metismenu.js - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Modern MetisMenu script for Joomla mod_menu in Moko-Cassiopeia */ diff --git a/src/media/js/template.js b/src/media/js/template.js index 0d0639f..c748445 100644 --- a/src/media/js/template.js +++ b/src/media/js/template.js @@ -8,7 +8,7 @@ DEFGROUP: Joomla.Template.Site INGROUP: Moko-Cassiopeia PATH: ./media/templates/site/moko-cassiopeia/js/template.js - VERSION: 03.05.00 + VERSION: 03.07.00 BRIEF: Core JavaScript utilities and behaviors for Moko-Cassiopeia template */ !function(a){"use strict";window.Toc={helpers:{findOrFilter:function(e,t){var n=e.find(t);return e.filter(t).add(n).filter(":not([data-toc-skip])")},generateUniqueIdBase:function(e){return a(e).text().trim().replace(/\'/gi,"").replace(/[& +$,:;=?@"#{}|^~[`%!'<>\]\.\/\(\)\*\\\n\t\b\v]/g,"-").replace(/-{2,}/g,"-").substring(0,64).replace(/^-+|-+$/gm,"").toLowerCase()||e.tagName.toLowerCase()},generateUniqueId:function(e){for(var t=this.generateUniqueIdBase(e),n=0;;n++){var r=t;if(0')},createChildNavList:function(e){var t=this.createNavList();return e.append(t),t},generateNavEl:function(e,t){var n=a('');n.attr("href","#"+e),n.text(t);var r=a("
  • ");return r.append(n),r},generateNavItem:function(e){var t=this.generateAnchor(e),n=a(e),r=n.data("toc-text")||n.text();return this.generateNavEl(t,r)},getTopLevel:function(e){for(var t=1;t<=6;t++){if(1 + * @license GNU General Public License version 3 or later; see LICENSE.txt + * + * SPDX-License-Identifier: GPL-3.0-or-later + * + * FILE INFORMATION + * DEFGROUP: Joomla.Template.Site + * INGROUP: Moko-Cassiopeia + * PATH: ./templates/moko-cassiopeia/script.php + * VERSION: 03.07.00 + * BRIEF: Installation and update script for Moko-Cassiopeia template + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\Filesystem\File; +use Joomla\CMS\Filesystem\Folder; +use Joomla\CMS\Installer\InstallerAdapter; +use Joomla\CMS\Installer\InstallerScriptInterface; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Log\Log; + +/** + * Installation script for Moko-Cassiopeia template + * + * @since 03.07.00 + */ +return new class () implements InstallerScriptInterface { + /** + * The template's minimum supported Joomla version + * + * @var string + * @since 03.07.00 + */ + private $minimumJoomla = '4.0'; + + /** + * The template's minimum supported PHP version + * + * @var string + * @since 03.07.00 + */ + private $minimumPhp = '7.4'; + + /** + * List of files to be removed during update (old/deprecated files) + * + * @var array + * @since 03.07.00 + */ + private $filesToRemove = [ + // Add deprecated files here as needed + // Example: 'media/templates/site/moko-cassiopeia/js/old-script.js', + ]; + + /** + * List of folders to be removed during update (old/deprecated folders) + * + * @var array + * @since 03.07.00 + */ + private $foldersToRemove = [ + // Add deprecated folders here as needed + // Example: 'media/templates/site/moko-cassiopeia/old-assets', + ]; + + /** + * Function called before extension installation/update/removal procedure commences + * + * @param string $type The type of change (install or discover_install, update, uninstall) + * @param InstallerAdapter $parent The class calling this method + * + * @return boolean True on success + * + * @since 03.07.00 + */ + public function preflight(string $type, InstallerAdapter $parent): bool + { + // Check minimum Joomla version + if (version_compare(JVERSION, $this->minimumJoomla, '<')) { + Factory::getApplication()->enqueueMessage( + sprintf( + Text::_('JLIB_INSTALLER_MINIMUM_JOOMLA'), + $this->minimumJoomla + ), + 'error' + ); + return false; + } + + // Check minimum PHP version + if (version_compare(PHP_VERSION, $this->minimumPhp, '<')) { + Factory::getApplication()->enqueueMessage( + sprintf( + Text::_('JLIB_INSTALLER_MINIMUM_PHP'), + $this->minimumPhp + ), + 'error' + ); + return false; + } + + return true; + } + + /** + * Function called after extension installation/update/removal procedure completes + * + * @param string $type The type of change (install or discover_install, update, uninstall) + * @param InstallerAdapter $parent The class calling this method + * + * @return boolean True on success + * + * @since 03.07.00 + */ + public function postflight(string $type, InstallerAdapter $parent): bool + { + // Only run cleanup on update + if ($type === 'update') { + $this->cleanupMediaFolder(); + } + + // Display success message + if ($type === 'install') { + Factory::getApplication()->enqueueMessage( + 'Moko-Cassiopeia template has been successfully installed!', + 'success' + ); + } elseif ($type === 'update') { + Factory::getApplication()->enqueueMessage( + 'Moko-Cassiopeia template has been successfully updated to version 03.07.00!', + 'success' + ); + } + + return true; + } + + /** + * Function called when extension is installed + * + * @param InstallerAdapter $parent The class calling this method + * + * @return boolean True on success + * + * @since 03.07.00 + */ + public function install(InstallerAdapter $parent): bool + { + return true; + } + + /** + * Function called when extension is updated + * + * @param InstallerAdapter $parent The class calling this method + * + * @return boolean True on success + * + * @since 03.07.00 + */ + public function update(InstallerAdapter $parent): bool + { + return true; + } + + /** + * Function called when extension is uninstalled + * + * @param InstallerAdapter $parent The class calling this method + * + * @return boolean True on success + * + * @since 03.07.00 + */ + public function uninstall(InstallerAdapter $parent): bool + { + return true; + } + + /** + * Clean up the media folder by removing old and deprecated files + * + * @return void + * + * @since 03.07.00 + */ + private function cleanupMediaFolder(): void + { + $app = Factory::getApplication(); + $mediaPath = JPATH_ROOT . '/media/templates/site/moko-cassiopeia'; + $removedFiles = 0; + $removedFolders = 0; + $errors = []; + + // Set up logging + Log::addLogger( + ['text_file' => 'moko_cassiopeia_cleanup.php'], + Log::ALL, + ['moko-cassiopeia-cleanup'] + ); + + Log::add('Starting media folder cleanup', Log::INFO, 'moko-cassiopeia-cleanup'); + + // Remove deprecated files + foreach ($this->filesToRemove as $file) { + $filePath = JPATH_ROOT . '/' . $file; + + if (File::exists($filePath)) { + try { + if (File::delete($filePath)) { + $removedFiles++; + Log::add("Removed file: {$file}", Log::INFO, 'moko-cassiopeia-cleanup'); + } else { + $errors[] = "Failed to remove file: {$file}"; + Log::add("Failed to remove file: {$file}", Log::WARNING, 'moko-cassiopeia-cleanup'); + } + } catch (\Exception $e) { + $errors[] = "Error removing file {$file}: " . $e->getMessage(); + Log::add("Error removing file {$file}: " . $e->getMessage(), Log::ERROR, 'moko-cassiopeia-cleanup'); + } + } + } + + // Remove deprecated folders + foreach ($this->foldersToRemove as $folder) { + $folderPath = JPATH_ROOT . '/' . $folder; + + if (Folder::exists($folderPath)) { + try { + if (Folder::delete($folderPath)) { + $removedFolders++; + Log::add("Removed folder: {$folder}", Log::INFO, 'moko-cassiopeia-cleanup'); + } else { + $errors[] = "Failed to remove folder: {$folder}"; + Log::add("Failed to remove folder: {$folder}", Log::WARNING, 'moko-cassiopeia-cleanup'); + } + } catch (\Exception $e) { + $errors[] = "Error removing folder {$folder}: " . $e->getMessage(); + Log::add("Error removing folder {$folder}: " . $e->getMessage(), Log::ERROR, 'moko-cassiopeia-cleanup'); + } + } + } + + // Clean up empty directories in media folder + if (is_dir($mediaPath)) { + $this->removeEmptyDirectories($mediaPath); + } + + // Display cleanup summary + if ($removedFiles > 0 || $removedFolders > 0) { + $message = sprintf( + 'Media folder cleanup: Removed %d file(s) and %d folder(s).', + $removedFiles, + $removedFolders + ); + $app->enqueueMessage($message, 'info'); + Log::add($message, Log::INFO, 'moko-cassiopeia-cleanup'); + } + + // Display errors if any + foreach ($errors as $error) { + $app->enqueueMessage($error, 'warning'); + } + + Log::add('Media folder cleanup completed', Log::INFO, 'moko-cassiopeia-cleanup'); + } + + /** + * Recursively remove empty directories + * + * @param string $path The directory path to check + * + * @return boolean True if directory was removed, false otherwise + * + * @since 03.07.00 + */ + private function removeEmptyDirectories(string $path): bool + { + if (!is_dir($path)) { + return false; + } + + $empty = true; + $items = glob($path . '/{,.}*', GLOB_BRACE); + + foreach ($items as $item) { + $basename = basename($item); + + // Skip . and .. + if ($basename === '.' || $basename === '..') { + continue; + } + + if (is_dir($item)) { + if (!$this->removeEmptyDirectories($item)) { + $empty = false; + } + } else { + $empty = false; + } + } + + // Remove directory if it's empty + if ($empty && $path !== JPATH_ROOT . '/media/templates/site/moko-cassiopeia') { + try { + if (Folder::delete($path)) { + Log::add("Removed empty directory: {$path}", Log::INFO, 'moko-cassiopeia-cleanup'); + return true; + } + } catch (\Exception $e) { + Log::add("Error removing empty directory {$path}: " . $e->getMessage(), Log::WARNING, 'moko-cassiopeia-cleanup'); + } + } + + return $empty; + } +}; diff --git a/src/templates/templateDetails.xml b/src/templates/templateDetails.xml index a011596..c0600eb 100644 --- a/src/templates/templateDetails.xml +++ b/src/templates/templateDetails.xml @@ -11,7 +11,7 @@ DEFGROUP: Joomla INGROUP: Moko-Cassiopeia PATH: templates/moko-cassiopeia/templateDetails.xml - VERSION: 03.06.00 + VERSION: 03.07.00 BRIEF: Template manifest XML file for Moko-Cassiopeia ========================================================================= --> @@ -22,7 +22,7 @@ moko-cassiopeia - 03.06.00 + 03.07.00 2025-12-23 Jonathan Miller || Moko Consulting hello@mokoconsulting.tech diff --git a/updates.xml b/updates.xml index 91b0a15..5e7abe3 100644 --- a/updates.xml +++ b/updates.xml @@ -10,7 +10,7 @@ INGROUP: Moko-Cassiopeia REPO: https://github.com/mokoconsulting-tech/moko-cassiopeia PATH: ./updates.xml - VERSION: 03.06.00 + VERSION: 03.07.00 BRIEF: Update manifest XML file for Moko-Cassiopeia --> @@ -22,7 +22,7 @@ template site - 03.06.00 + 03.07.00 2025-12-12 Jonathan Miller || Moko Consulting hello@mokoconsulting.tech