Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 121de98f5c | |||
| 7333892881 | |||
| 1c5cd4007f | |||
| 8bd3650fe5 | |||
| c6844ab101 | |||
| fd7de03582 | |||
| 38274a9f08 | |||
| a4be802d31 | |||
| 1b6443aa2b | |||
| a3a73f708c | |||
| 118e82e2bd | |||
| feb1bc0135 | |||
| 5bb89ac946 | |||
| 6f1a52f0ca | |||
| df5661f366 | |||
| bba92ebc27 | |||
| 913f557c4e | |||
| cec6cfdfa0 | |||
| bf6fee62f0 | |||
| 14a6ccd796 | |||
| 942cd0e98b | |||
| 51520f3a92 | |||
| 3f885d8492 | |||
| 25e73e100c | |||
| 41f48a8559 | |||
| c0b43c4eab | |||
| 0e2ad74d02 | |||
| 3c59e6f2da | |||
| 0dc03eacc7 | |||
| 18f139a4a8 | |||
| b59c6f6cc4 | |||
| 9f0947abae | |||
| a8fe17bd4d | |||
| 2aa7b638e9 | |||
| 22eb21deb0 | |||
| d44190450c | |||
| 1210137d73 |
@@ -0,0 +1,7 @@
|
||||
.claude/
|
||||
.mcp.json
|
||||
TODO.md
|
||||
*.min.css
|
||||
*.min.js
|
||||
vendor/
|
||||
node_modules/
|
||||
@@ -0,0 +1,21 @@
|
||||
<!--
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
Authored-by: Moko Consulting
|
||||
-->
|
||||
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- **Repository** -- initial scaffold for MokoSuiteBooking
|
||||
- **System Plugin** (`plg_system_mokosuitebooking`) -- configuration and schema management
|
||||
- **SQL Schema** -- services, staff, staff_services, schedules, bookings, locations, waitlist, booking_history tables
|
||||
- **Admin Component** (`com_mokosuitebooking`) -- Dashboard, Services, Staff, Schedules, Bookings, Locations, Waitlist views
|
||||
- **Webservices Plugin** (`plg_webservices_mokosuitebooking`) -- REST API route stubs
|
||||
- **Configuration** -- basic, booking, notifications, display fieldsets
|
||||
@@ -0,0 +1,31 @@
|
||||
# MokoSuiteBooking
|
||||
|
||||
Appointment and resource booking for service businesses
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| **Package** | `pkg_mokosuitebooking` |
|
||||
| **Layer** | 2 (requires: Client, CRM) |
|
||||
| **Language** | PHP 8.3+ |
|
||||
| **Branch** | develop on `dev`, merge to `main` (protected) |
|
||||
| **Wiki** | [MokoSuiteBooking Wiki](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteBooking/wiki) |
|
||||
|
||||
## Architecture
|
||||
|
||||
Joomla **package** -- Layer 2 add-on. Manages services, staff, schedules, bookings, locations, and waitlist.
|
||||
|
||||
## Rules
|
||||
|
||||
- **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js`
|
||||
- **Attribution**: `Authored-by: Moko Consulting`
|
||||
- **Workflow directory**: `.mokogitea/`
|
||||
- **Standards**: [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoCLI/wiki)
|
||||
- **Changelog**: `[Unreleased]` only -- release system assigns versions
|
||||
|
||||
## Coding Standards
|
||||
|
||||
- PHP 8.3+ / Joomla 6 patterns
|
||||
- `$this->getDatabase()` in models, `Factory::getContainer()->get(DatabaseInterface::class)` in helpers
|
||||
- `Factory::getApplication()->getIdentity()` for user
|
||||
@@ -1,3 +1,32 @@
|
||||
# MokoSuiteBooking
|
||||
|
||||
MokoSuite Booking — appointment and resource booking for service businesses on Joomla 6
|
||||
Appointment and resource booking for service businesses for Joomla 6.
|
||||
|
||||
## Overview
|
||||
|
||||
MokoSuiteBooking provides appointment scheduling, staff management, calendar schedules, booking lifecycle, multi-location support, and waitlist functionality as a Layer 2 MokoSuite extension.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Joomla 6+
|
||||
- PHP 8.3+
|
||||
- MokoSuiteClient (Layer 1)
|
||||
- MokoSuiteCRM (Layer 1)
|
||||
|
||||
## Installation
|
||||
|
||||
Install via the Joomla extension manager. The package includes:
|
||||
|
||||
- **System Plugin** (`plg_system_mokosuitebooking`) -- database schema and configuration
|
||||
- **Component** (`com_mokosuitebooking`) -- admin interface
|
||||
- **Webservices Plugin** (`plg_webservices_mokosuitebooking`) -- REST API routes
|
||||
|
||||
## License
|
||||
|
||||
GPL-3.0-or-later
|
||||
|
||||
## Links
|
||||
|
||||
- [Wiki](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteBooking/wiki)
|
||||
- [Issues](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteBooking/issues)
|
||||
- [MokoSuite](https://mokoconsulting.tech)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<access component="com_mokosuitebooking">
|
||||
<section name="component">
|
||||
<action name="core.admin" title="JACTION_ADMIN" />
|
||||
<action name="core.manage" title="JACTION_MANAGE" />
|
||||
<action name="core.create" title="JACTION_CREATE" />
|
||||
<action name="core.delete" title="JACTION_DELETE" />
|
||||
<action name="core.edit" title="JACTION_EDIT" />
|
||||
<action name="core.edit.state" title="JACTION_EDITSTATE" />
|
||||
<action name="booking.manage.services" title="COM_MOKOSUITEBOOKING_ACTION_MANAGE_SERVICES" />
|
||||
<action name="booking.manage.staff" title="COM_MOKOSUITEBOOKING_ACTION_MANAGE_STAFF" />
|
||||
<action name="booking.manage.bookings" title="COM_MOKOSUITEBOOKING_ACTION_MANAGE_BOOKINGS" />
|
||||
<action name="booking.view.waitlist" title="COM_MOKOSUITEBOOKING_ACTION_VIEW_WAITLIST" />
|
||||
</section>
|
||||
</access>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<config>
|
||||
<fieldset name="component"
|
||||
label="COM_MOKOSUITEBOOKING"
|
||||
description="COM_MOKOSUITEBOOKING_CONFIG_DESCRIPTION">
|
||||
</fieldset>
|
||||
</config>
|
||||
@@ -0,0 +1,14 @@
|
||||
COM_MOKOSUITEBOOKING="MokoSuiteBooking"
|
||||
COM_MOKOSUITEBOOKING_DESCRIPTION="Appointment and resource booking for service businesses"
|
||||
COM_MOKOSUITEBOOKING_CONFIG_DESCRIPTION="Configuration is managed in the system plugin."
|
||||
COM_MOKOSUITEBOOKING_MENU_DASHBOARD="Dashboard"
|
||||
COM_MOKOSUITEBOOKING_MENU_SERVICES="Services"
|
||||
COM_MOKOSUITEBOOKING_MENU_STAFF="Staff"
|
||||
COM_MOKOSUITEBOOKING_MENU_SCHEDULES="Schedules"
|
||||
COM_MOKOSUITEBOOKING_MENU_BOOKINGS="Bookings"
|
||||
COM_MOKOSUITEBOOKING_MENU_LOCATIONS="Locations"
|
||||
COM_MOKOSUITEBOOKING_MENU_WAITLIST="Waitlist"
|
||||
COM_MOKOSUITEBOOKING_ACTION_MANAGE_SERVICES="Manage Services"
|
||||
COM_MOKOSUITEBOOKING_ACTION_MANAGE_STAFF="Manage Staff"
|
||||
COM_MOKOSUITEBOOKING_ACTION_MANAGE_BOOKINGS="Manage Bookings"
|
||||
COM_MOKOSUITEBOOKING_ACTION_VIEW_WAITLIST="View Waitlist"
|
||||
@@ -0,0 +1,9 @@
|
||||
COM_MOKOSUITEBOOKING="MokoSuiteBooking"
|
||||
COM_MOKOSUITEBOOKING_DESCRIPTION="Appointment and resource booking for service businesses"
|
||||
COM_MOKOSUITEBOOKING_MENU_DASHBOARD="Dashboard"
|
||||
COM_MOKOSUITEBOOKING_MENU_SERVICES="Services"
|
||||
COM_MOKOSUITEBOOKING_MENU_STAFF="Staff"
|
||||
COM_MOKOSUITEBOOKING_MENU_SCHEDULES="Schedules"
|
||||
COM_MOKOSUITEBOOKING_MENU_BOOKINGS="Bookings"
|
||||
COM_MOKOSUITEBOOKING_MENU_LOCATIONS="Locations"
|
||||
COM_MOKOSUITEBOOKING_MENU_WAITLIST="Waitlist"
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
|
||||
use Joomla\CMS\Extension\ComponentInterface;
|
||||
use Joomla\CMS\Extension\MVCComponent;
|
||||
use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
|
||||
use Joomla\CMS\Component\Router\RouterFactoryInterface;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
|
||||
return new class implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->set(
|
||||
ComponentInterface::class,
|
||||
function (Container $container) {
|
||||
$component = new MVCComponent($container->get(ComponentDispatcherFactoryInterface::class));
|
||||
$component->setMVCFactory($container->get(MVCFactoryInterface::class));
|
||||
$component->setRouterFactory($container->get(RouterFactoryInterface::class));
|
||||
|
||||
return $component;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\Controller\BaseController;
|
||||
|
||||
class DisplayController extends BaseController
|
||||
{
|
||||
protected $default_view = 'bookingdashboard';
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\View\BookingDashboard;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
public function display($tpl = null): void
|
||||
{
|
||||
ToolbarHelper::title('Dashboard', 'home');
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\View\Bookings;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
public function display($tpl = null): void
|
||||
{
|
||||
ToolbarHelper::title('Bookings', 'book');
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\View\Locations;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
public function display($tpl = null): void
|
||||
{
|
||||
ToolbarHelper::title('Locations', 'location');
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\View\Schedules;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
public function display($tpl = null): void
|
||||
{
|
||||
ToolbarHelper::title('Schedules', 'calendar');
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\View\Services;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
public function display($tpl = null): void
|
||||
{
|
||||
ToolbarHelper::title('Services', 'list');
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\View\Staff;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
public function display($tpl = null): void
|
||||
{
|
||||
ToolbarHelper::title('Staff', 'users');
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Component\MokoSuiteBooking\View\Waitlist;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\HtmlView as BaseHtmlView;
|
||||
use Joomla\CMS\Toolbar\ToolbarHelper;
|
||||
|
||||
class HtmlView extends BaseHtmlView
|
||||
{
|
||||
public function display($tpl = null): void
|
||||
{
|
||||
ToolbarHelper::title('Waitlist', 'clock');
|
||||
|
||||
parent::display($tpl);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Dashboard</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Bookings</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Locations</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Schedules</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Services</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Staff</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
?>
|
||||
<div class="container">
|
||||
<h2>Waitlist</h2>
|
||||
<p>Coming soon.</p>
|
||||
</div>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<extension type="component" method="upgrade">
|
||||
<name>com_mokosuitebooking</name>
|
||||
<version>06.00.00</version>
|
||||
<creationDate>2026-06-27</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
<authorUrl>https://mokoconsulting.tech</authorUrl>
|
||||
<copyright>Copyright (C) 2026 Moko Consulting</copyright>
|
||||
<license>GPL-3.0-or-later</license>
|
||||
<description>COM_MOKOSUITEBOOKING_DESCRIPTION</description>
|
||||
<namespace path="admin/src">Moko\Component\MokoSuiteBooking</namespace>
|
||||
<administration>
|
||||
<menu>COM_MOKOSUITEBOOKING</menu>
|
||||
<submenu>
|
||||
<menu link="option=com_mokosuitebooking&view=bookingdashboard">COM_MOKOSUITEBOOKING_MENU_DASHBOARD</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=services">COM_MOKOSUITEBOOKING_MENU_SERVICES</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=staff">COM_MOKOSUITEBOOKING_MENU_STAFF</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=schedules">COM_MOKOSUITEBOOKING_MENU_SCHEDULES</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=bookings">COM_MOKOSUITEBOOKING_MENU_BOOKINGS</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=locations">COM_MOKOSUITEBOOKING_MENU_LOCATIONS</menu>
|
||||
<menu link="option=com_mokosuitebooking&view=waitlist">COM_MOKOSUITEBOOKING_MENU_WAITLIST</menu>
|
||||
</submenu>
|
||||
<files folder="admin">
|
||||
<folder>language</folder>
|
||||
<folder>services</folder>
|
||||
<folder>src</folder>
|
||||
<folder>tmpl</folder>
|
||||
</files>
|
||||
</administration>
|
||||
<languages folder="admin/language">
|
||||
<language tag="en-GB">en-GB/com_mokosuitebooking.ini</language>
|
||||
<language tag="en-GB">en-GB/com_mokosuitebooking.sys.ini</language>
|
||||
</languages>
|
||||
</extension>
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING="System - MokoSuiteBooking"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_DESCRIPTION="MokoSuiteBooking system plugin — schema and configuration management"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_FIELDSET_BASIC="Basic"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_BUSINESS_NAME="Business Name"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_CURRENCY="Currency"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_TIMEZONE="Timezone"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_TIME_SLOT_MINUTES="Time Slot (Minutes)"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_FIELDSET_BOOKING="Booking"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_MAX_ADVANCE_DAYS="Max Advance Booking (Days)"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_CANCELLATION_WINDOW="Cancellation Window (Hours)"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_AUTO_CONFIRM="Auto-Confirm"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_ALLOW_WALK_INS="Allow Walk-Ins"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_FIELDSET_NOTIFICATIONS="Notifications"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_CONFIRMATION_EMAIL="Confirmation Email"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_REMINDER_HOURS="Reminder (Hours Before)"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_NOSHOW_THRESHOLD="No-Show Threshold (Minutes)"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_FIELDSET_DISPLAY="Display"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_CALENDAR_START="Calendar Start Hour"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_CALENDAR_END="Calendar End Hour"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_SLOTS_PER_PAGE="Slots Per Page"
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING="System - MokoSuiteBooking"
|
||||
PLG_SYSTEM_MOKOSUITEBOOKING_DESCRIPTION="MokoSuiteBooking system plugin — schema and configuration management"
|
||||
@@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<extension type="plugin" group="system" method="upgrade">
|
||||
<name>plg_system_mokosuitebooking</name>
|
||||
<version>06.00.00</version>
|
||||
<creationDate>2026-06-27</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
<authorUrl>https://mokoconsulting.tech</authorUrl>
|
||||
<copyright>Copyright (C) 2026 Moko Consulting</copyright>
|
||||
<license>GPL-3.0-or-later</license>
|
||||
<description>PLG_SYSTEM_MOKOSUITEBOOKING_DESCRIPTION</description>
|
||||
<namespace path="src">Moko\Plugin\System\MokoSuiteBooking</namespace>
|
||||
<files>
|
||||
<folder plugin="mokosuitebooking">services</folder>
|
||||
<folder>src</folder>
|
||||
</files>
|
||||
<languages folder="language">
|
||||
<language tag="en-GB">en-GB/plg_system_mokosuitebooking.ini</language>
|
||||
<language tag="en-GB">en-GB/plg_system_mokosuitebooking.sys.ini</language>
|
||||
</languages>
|
||||
<install>
|
||||
<sql><file driver="mysql" charset="utf8">sql/install.mysql.sql</file></sql>
|
||||
</install>
|
||||
<uninstall>
|
||||
<sql><file driver="mysql" charset="utf8">sql/uninstall.mysql.sql</file></sql>
|
||||
</uninstall>
|
||||
<config>
|
||||
<fields name="params">
|
||||
<fieldset name="basic" label="PLG_SYSTEM_MOKOSUITEBOOKING_FIELDSET_BASIC">
|
||||
<field name="business_name" type="text" label="PLG_SYSTEM_MOKOSUITEBOOKING_BUSINESS_NAME" default="" />
|
||||
<field name="currency" type="text" label="PLG_SYSTEM_MOKOSUITEBOOKING_CURRENCY" default="USD" />
|
||||
<field name="timezone" type="timezone" label="PLG_SYSTEM_MOKOSUITEBOOKING_TIMEZONE" default="America/New_York" />
|
||||
<field name="time_slot_minutes" type="number" label="PLG_SYSTEM_MOKOSUITEBOOKING_TIME_SLOT_MINUTES" default="30" min="5" max="120" step="5" />
|
||||
</fieldset>
|
||||
<fieldset name="booking" label="PLG_SYSTEM_MOKOSUITEBOOKING_FIELDSET_BOOKING">
|
||||
<field name="max_advance_days" type="number" label="PLG_SYSTEM_MOKOSUITEBOOKING_MAX_ADVANCE_DAYS" default="90" min="1" max="365" />
|
||||
<field name="cancellation_window_hours" type="number" label="PLG_SYSTEM_MOKOSUITEBOOKING_CANCELLATION_WINDOW" default="24" min="0" max="168" />
|
||||
<field name="auto_confirm" type="radio" label="PLG_SYSTEM_MOKOSUITEBOOKING_AUTO_CONFIRM" default="0" class="btn-group"><option value="0">JNO</option><option value="1">JYES</option></field>
|
||||
<field name="allow_walk_ins" type="radio" label="PLG_SYSTEM_MOKOSUITEBOOKING_ALLOW_WALK_INS" default="1" class="btn-group"><option value="0">JNO</option><option value="1">JYES</option></field>
|
||||
</fieldset>
|
||||
<fieldset name="notifications" label="PLG_SYSTEM_MOKOSUITEBOOKING_FIELDSET_NOTIFICATIONS">
|
||||
<field name="confirmation_email" type="radio" label="PLG_SYSTEM_MOKOSUITEBOOKING_CONFIRMATION_EMAIL" default="1" class="btn-group"><option value="0">JNO</option><option value="1">JYES</option></field>
|
||||
<field name="reminder_hours_before" type="number" label="PLG_SYSTEM_MOKOSUITEBOOKING_REMINDER_HOURS" default="24" min="0" max="72" />
|
||||
<field name="noshow_threshold_minutes" type="number" label="PLG_SYSTEM_MOKOSUITEBOOKING_NOSHOW_THRESHOLD" default="15" min="5" max="60" />
|
||||
</fieldset>
|
||||
<fieldset name="display" label="PLG_SYSTEM_MOKOSUITEBOOKING_FIELDSET_DISPLAY">
|
||||
<field name="calendar_start_hour" type="number" label="PLG_SYSTEM_MOKOSUITEBOOKING_CALENDAR_START" default="8" min="0" max="12" />
|
||||
<field name="calendar_end_hour" type="number" label="PLG_SYSTEM_MOKOSUITEBOOKING_CALENDAR_END" default="18" min="12" max="23" />
|
||||
<field name="slots_per_page" type="number" label="PLG_SYSTEM_MOKOSUITEBOOKING_SLOTS_PER_PAGE" default="20" min="5" max="50" />
|
||||
</fieldset>
|
||||
</fields>
|
||||
</config>
|
||||
</extension>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Extension\PluginInterface;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Moko\Plugin\System\MokoSuiteBooking\Extension\Booking;
|
||||
|
||||
return new class implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->set(
|
||||
PluginInterface::class,
|
||||
function (Container $container) {
|
||||
$dispatcher = $container->get(DispatcherInterface::class);
|
||||
$plugin = new Booking($dispatcher, (array) PluginHelper::getPlugin('system', 'mokosuitebooking'));
|
||||
$plugin->setApplication(\Joomla\CMS\Factory::getApplication());
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,150 @@
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_services` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT,
|
||||
`category` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`duration_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 60,
|
||||
`buffer_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
`price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`max_participants` TINYINT UNSIGNED NOT NULL DEFAULT 1,
|
||||
`requires_deposit` TINYINT NOT NULL DEFAULT 0,
|
||||
`deposit_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`color` VARCHAR(7) NOT NULL DEFAULT '#3788d8',
|
||||
`photo` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
`published` TINYINT NOT NULL DEFAULT 1,
|
||||
`ordering` INT NOT NULL DEFAULT 0,
|
||||
`created` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_category` (`category`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_staff` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`contact_id` INT DEFAULT NULL,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`email` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`phone` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`title` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`bio` TEXT,
|
||||
`photo` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
`color` VARCHAR(7) NOT NULL DEFAULT '#3788d8',
|
||||
`max_daily_bookings` TINYINT UNSIGNED NOT NULL DEFAULT 20,
|
||||
`rating` DECIMAL(3,2) NOT NULL DEFAULT 5.00,
|
||||
`total_bookings` INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
`published` TINYINT NOT NULL DEFAULT 1,
|
||||
`ordering` INT NOT NULL DEFAULT 0,
|
||||
`created` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_contact` (`contact_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_staff_services` (
|
||||
`staff_id` INT UNSIGNED NOT NULL,
|
||||
`service_id` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`staff_id`, `service_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_schedules` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`staff_id` INT UNSIGNED NOT NULL,
|
||||
`location_id` INT UNSIGNED DEFAULT NULL,
|
||||
`day_of_week` TINYINT UNSIGNED NOT NULL,
|
||||
`start_time` TIME NOT NULL,
|
||||
`end_time` TIME NOT NULL,
|
||||
`is_recurring` TINYINT NOT NULL DEFAULT 1,
|
||||
`specific_date` DATE DEFAULT NULL,
|
||||
`override_type` ENUM('available','unavailable') DEFAULT NULL,
|
||||
`created` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_staff` (`staff_id`),
|
||||
KEY `idx_location` (`location_id`),
|
||||
KEY `idx_day` (`day_of_week`),
|
||||
KEY `idx_date` (`specific_date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_bookings` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`booking_ref` VARCHAR(20) NOT NULL,
|
||||
`service_id` INT UNSIGNED NOT NULL,
|
||||
`staff_id` INT UNSIGNED DEFAULT NULL,
|
||||
`location_id` INT UNSIGNED DEFAULT NULL,
|
||||
`customer_contact_id` INT DEFAULT NULL,
|
||||
`customer_name` VARCHAR(255) NOT NULL,
|
||||
`customer_email` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`customer_phone` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`status` ENUM('pending','confirmed','checked_in','in_progress','completed','cancelled','no_show') NOT NULL DEFAULT 'pending',
|
||||
`booking_date` DATE NOT NULL,
|
||||
`start_time` TIME NOT NULL,
|
||||
`end_time` TIME NOT NULL,
|
||||
`participants` TINYINT UNSIGNED NOT NULL DEFAULT 1,
|
||||
`price` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`deposit_paid` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
|
||||
`payment_status` ENUM('pending','deposit_paid','paid','refunded') NOT NULL DEFAULT 'pending',
|
||||
`source` ENUM('admin','online','phone','walk_in') NOT NULL DEFAULT 'online',
|
||||
`notes` TEXT,
|
||||
`customer_notes` TEXT,
|
||||
`reminder_sent` TINYINT NOT NULL DEFAULT 0,
|
||||
`created` DATETIME NOT NULL,
|
||||
`created_by` INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `idx_ref` (`booking_ref`),
|
||||
KEY `idx_service` (`service_id`),
|
||||
KEY `idx_staff` (`staff_id`),
|
||||
KEY `idx_customer` (`customer_contact_id`),
|
||||
KEY `idx_status` (`status`),
|
||||
KEY `idx_date` (`booking_date`),
|
||||
KEY `idx_datetime` (`booking_date`, `start_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_locations` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`address` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
`city` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`state` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
`postal_code` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
`phone` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`email` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`timezone` VARCHAR(50) NOT NULL DEFAULT 'America/New_York',
|
||||
`published` TINYINT NOT NULL DEFAULT 1,
|
||||
`ordering` INT NOT NULL DEFAULT 0,
|
||||
`created` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_waitlist` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`service_id` INT UNSIGNED NOT NULL,
|
||||
`staff_id` INT UNSIGNED DEFAULT NULL,
|
||||
`location_id` INT UNSIGNED DEFAULT NULL,
|
||||
`customer_contact_id` INT DEFAULT NULL,
|
||||
`customer_name` VARCHAR(255) NOT NULL,
|
||||
`customer_phone` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`customer_email` VARCHAR(255) NOT NULL DEFAULT '',
|
||||
`preferred_date` DATE DEFAULT NULL,
|
||||
`preferred_time` TIME DEFAULT NULL,
|
||||
`status` ENUM('waiting','offered','booked','expired','cancelled') NOT NULL DEFAULT 'waiting',
|
||||
`position` INT UNSIGNED NOT NULL DEFAULT 0,
|
||||
`notes` TEXT,
|
||||
`created` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_service` (`service_id`),
|
||||
KEY `idx_customer` (`customer_contact_id`),
|
||||
KEY `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `#__mokosuitebooking_booking_history` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`booking_id` INT UNSIGNED NOT NULL,
|
||||
`action` ENUM('created','confirmed','rescheduled','cancelled','completed','no_show','reminder_sent') NOT NULL,
|
||||
`old_date` DATE DEFAULT NULL,
|
||||
`old_time` TIME DEFAULT NULL,
|
||||
`new_date` DATE DEFAULT NULL,
|
||||
`new_time` TIME DEFAULT NULL,
|
||||
`note` TEXT,
|
||||
`created` DATETIME NOT NULL,
|
||||
`created_by` INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_booking` (`booking_id`),
|
||||
KEY `idx_action` (`action`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@@ -0,0 +1,8 @@
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_booking_history`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_waitlist`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_locations`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_bookings`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_schedules`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_staff_services`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_staff`;
|
||||
DROP TABLE IF EXISTS `#__mokosuitebooking_services`;
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Plugin\System\MokoSuiteBooking\Extension;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
use Joomla\Event\SubscriberInterface;
|
||||
|
||||
final class Booking extends CMSPlugin implements SubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<extension type="plugin" group="webservices" method="upgrade">
|
||||
<name>plg_webservices_mokosuitebooking</name>
|
||||
<version>06.00.00</version>
|
||||
<creationDate>2026-06-27</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
<authorUrl>https://mokoconsulting.tech</authorUrl>
|
||||
<copyright>Copyright (C) 2026 Moko Consulting</copyright>
|
||||
<license>GPL-3.0-or-later</license>
|
||||
<description>PLG_WEBSERVICES_MOKOSUITEBOOKING_DESCRIPTION</description>
|
||||
<namespace path="src">Moko\Plugin\Webservices\MokoSuiteBooking</namespace>
|
||||
<files>
|
||||
<folder plugin="mokosuitebooking">services</folder>
|
||||
<folder>src</folder>
|
||||
</files>
|
||||
</extension>
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Extension\PluginInterface;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Moko\Plugin\Webservices\MokoSuiteBooking\Extension\MokoSuiteBooking;
|
||||
|
||||
return new class implements ServiceProviderInterface
|
||||
{
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->set(
|
||||
PluginInterface::class,
|
||||
function (Container $container) {
|
||||
$dispatcher = $container->get(DispatcherInterface::class);
|
||||
$plugin = new MokoSuiteBooking($dispatcher, (array) PluginHelper::getPlugin('webservices', 'mokosuitebooking'));
|
||||
$plugin->setApplication(\Joomla\CMS\Factory::getApplication());
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* Authored-by: Moko Consulting
|
||||
*/
|
||||
|
||||
namespace Moko\Plugin\Webservices\MokoSuiteBooking\Extension;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
use Joomla\CMS\Router\ApiRouter;
|
||||
use Joomla\Event\SubscriberInterface;
|
||||
|
||||
final class MokoSuiteBooking extends CMSPlugin implements SubscriberInterface
|
||||
{
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
'onBeforeApiRoute' => 'onBeforeApiRoute',
|
||||
];
|
||||
}
|
||||
|
||||
public function onBeforeApiRoute(&$router): void
|
||||
{
|
||||
// Route registrations will be added during development
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<extension type="package" method="upgrade">
|
||||
<name>pkg_mokosuitebooking</name>
|
||||
<packagename>mokosuitebooking</packagename>
|
||||
<version>06.00.00</version>
|
||||
<creationDate>2026-06-27</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
<authorUrl>https://mokoconsulting.tech</authorUrl>
|
||||
<copyright>Copyright (C) 2026 Moko Consulting</copyright>
|
||||
<license>GPL-3.0-or-later</license>
|
||||
<description>Appointment and resource booking for service businesses</description>
|
||||
<php_minimum>8.3</php_minimum>
|
||||
<dlid prefix="dlid=" suffix=""/>
|
||||
<blockChildUninstall>true</blockChildUninstall>
|
||||
<scriptfile>script.php</scriptfile>
|
||||
<files>
|
||||
<file type="plugin" id="mokosuitebooking" group="system">packages/plg_system_mokosuitebooking</file>
|
||||
<file type="component" id="com_mokosuitebooking">packages/com_mokosuitebooking</file>
|
||||
<file type="plugin" id="mokosuitebooking" group="webservices">packages/plg_webservices_mokosuitebooking</file>
|
||||
</files>
|
||||
<updateservers>
|
||||
<server type="extension" name="MokoSuiteBooking Updates">https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteBooking/updates.xml</server>
|
||||
</updateservers>
|
||||
</extension>
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @package MokoSuiteBooking
|
||||
* @subpackage pkg_mokosuitebooking
|
||||
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
* @license GNU General Public License version 3 or later; see LICENSE
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Installer\InstallerAdapter;
|
||||
use Joomla\CMS\Log\Log;
|
||||
|
||||
/**
|
||||
* Package installation script for MokoSuiteBooking.
|
||||
*/
|
||||
class Pkg_MokoSuiteBookingInstallerScript
|
||||
{
|
||||
public function postflight(string $type, InstallerAdapter $adapter): void
|
||||
{
|
||||
$this->warnMissingLicenseKey();
|
||||
}
|
||||
|
||||
private function warnMissingLicenseKey(): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$db = Factory::getDbo();
|
||||
$app = Factory::getApplication();
|
||||
|
||||
$query = $db->getQuery(true)
|
||||
->select([$db->quoteName('update_site_id'), $db->quoteName('extra_query')])
|
||||
->from($db->quoteName('#__update_sites'))
|
||||
->where('(' . $db->quoteName('name') . ' LIKE ' . $db->quote('%MokoSuiteBooking%')
|
||||
. ' OR ' . $db->quoteName('location') . ' LIKE ' . $db->quote('%MokoSuiteBooking%') . ')')
|
||||
->setLimit(1);
|
||||
$db->setQuery($query);
|
||||
$site = $db->loadObject();
|
||||
|
||||
if ($site)
|
||||
{
|
||||
$extraQuery = (string) ($site->extra_query ?? '');
|
||||
|
||||
if (!empty($extraQuery) && strpos($extraQuery, 'dlid=') !== false)
|
||||
{
|
||||
parse_str($extraQuery, $parsed);
|
||||
|
||||
if (!empty($parsed['dlid']))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$editUrl = 'index.php?option=com_installer&task=updatesite.edit&update_site_id=' . (int) $site->update_site_id;
|
||||
}
|
||||
else
|
||||
{
|
||||
$editUrl = 'index.php?option=com_installer&view=updatesites';
|
||||
}
|
||||
|
||||
$app->enqueueMessage(
|
||||
'<strong>Moko Consulting License Key Required</strong> — '
|
||||
. 'No download key is configured. Updates will not be available until a valid license key is entered. '
|
||||
. '<a href="' . $editUrl . '" class="btn btn-sm btn-warning ms-2">Enter License Key</a>',
|
||||
'warning'
|
||||
);
|
||||
}
|
||||
catch (\Throwable $e)
|
||||
{
|
||||
// Silent — avoid breaking install if update_sites query fails
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user