94 Commits

Author SHA1 Message Date
gitea-actions[bot] a05a84d794 chore(version): pre-release bump to 06.00.33-dev [skip ci] 2026-06-28 19:25:31 +00:00
gitea-actions[bot] 2118280629 chore(version): pre-release bump to 06.00.32-dev [skip ci] 2026-06-28 19:23:55 +00:00
gitea-actions[bot] c0edf7f486 chore(version): pre-release bump to 06.00.31-dev [skip ci] 2026-06-28 19:21:45 +00:00
jmiller 657d4b9c8d chore: sync ci-joomla.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 11s
2026-06-28 19:21:34 +00:00
gitea-actions[bot] 805e445a9c chore(version): pre-release bump to 06.00.30-dev [skip ci] 2026-06-28 19:20:30 +00:00
gitea-actions[bot] 051c31f8a9 chore(version): pre-release bump to 06.00.29-dev [skip ci] 2026-06-28 19:19:00 +00:00
gitea-actions[bot] b3eaf8a061 chore(version): pre-release bump to 06.00.28-dev [skip ci] 2026-06-28 19:17:59 +00:00
gitea-actions[bot] d688971cef chore(version): pre-release bump to 06.00.27-dev [skip ci] 2026-06-28 19:16:39 +00:00
gitea-actions[bot] f4a6c2ccf3 chore(version): pre-release bump to 06.00.26-dev [skip ci] 2026-06-28 19:15:30 +00:00
jmiller decc8413b4 chore: sync workflow-sync-trigger.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 10s
2026-06-28 19:14:17 +00:00
gitea-actions[bot] 0efa9bb787 chore(version): pre-release bump to 06.00.25-dev [skip ci] 2026-06-28 19:14:10 +00:00
jmiller 3401113c6e chore: sync version-set.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 11s
2026-06-28 19:13:14 +00:00
jmiller 52eccb0110 chore: sync repo-health.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 12s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 15s
2026-06-28 19:12:04 +00:00
gitea-actions[bot] 73b149bf84 chore(version): pre-release bump to 06.00.24-dev [skip ci] 2026-06-28 19:11:27 +00:00
jmiller 2cacd8965c chore: sync workflow-sync-trigger.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 16s
2026-06-28 19:11:09 +00:00
gitea-actions[bot] 67b5fdb614 chore(version): pre-release bump to 06.00.23-dev [skip ci] 2026-06-28 19:11:08 +00:00
jmiller 9047966bee chore: sync version-set.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 12s
2026-06-28 19:10:05 +00:00
gitea-actions[bot] b44581ad41 chore(version): pre-release bump to 06.00.22-dev [skip ci] 2026-06-28 19:08:27 +00:00
jmiller 34ff8fc7bc chore: sync repo-health.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 12s
2026-06-28 19:08:15 +00:00
jmiller ae0e709cf4 chore: sync rc-revert.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 19s
2026-06-28 19:08:00 +00:00
gitea-actions[bot] ee9e8a02bb chore(version): pre-release bump to 06.00.21-dev [skip ci] 2026-06-28 19:07:24 +00:00
jmiller 15bf723279 chore: sync pre-release.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 13s
2026-06-28 19:06:44 +00:00
gitea-actions[bot] d2ebb49902 chore(version): pre-release bump to 06.00.20-dev [skip ci] 2026-06-28 19:06:12 +00:00
jmiller eab5d27c55 feat: add scriptfile to package manifest
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 12s
2026-06-28 19:03:05 +00:00
jmiller 9bb61a0935 feat: add license key warning on install/update
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 12s
2026-06-28 19:03:00 +00:00
jmiller 0d9417e8be chore: sync rc-revert.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 10s
2026-06-28 19:02:20 +00:00
jmiller 253898262b chore: sync pr-metadata-check.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 12s
2026-06-28 19:02:08 +00:00
jmiller 6133bcdf26 chore: sync pre-release.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 14s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 18s
2026-06-28 19:01:05 +00:00
jmiller c604068e16 chore: sync pr-check.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 14s
2026-06-28 19:01:01 +00:00
gitea-actions[bot] a154aaca42 chore(version): auto-bump patch 06.00.19-dev [skip ci] 2026-06-28 18:54:45 +00:00
jmiller 33e8ba1fe3 chore: sync pr-metadata-check.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
2026-06-28 18:54:12 +00:00
jmiller 563f37a158 chore: sync notify.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
2026-06-28 18:53:38 +00:00
jmiller 1705cca8c8 chore: sync pr-check.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 13s
2026-06-28 18:53:10 +00:00
gitea-actions[bot] b921a16345 chore(version): auto-bump patch 06.00.18-dev [skip ci] 2026-06-28 18:53:07 +00:00
jmiller 61981f85fb chore: sync issue-branch.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 12s
2026-06-28 18:52:54 +00:00
gitea-actions[bot] 7b88459d9d chore(version): auto-bump patch 06.00.17-dev [skip ci] 2026-06-28 18:50:34 +00:00
jmiller cd63008805 chore: sync gitleaks.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
2026-06-28 18:50:01 +00:00
gitea-actions[bot] 5357ade52e chore(version): auto-bump patch 06.00.16-dev [skip ci] 2026-06-28 18:49:15 +00:00
jmiller 36b358e8ad chore: sync cleanup.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
2026-06-28 18:48:44 +00:00
gitea-actions[bot] b3a7dae917 chore(version): auto-bump patch 06.00.15-dev [skip ci] 2026-06-28 18:48:13 +00:00
jmiller 90e6d04c5f chore: sync ci-issue-reporter.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
2026-06-28 18:47:41 +00:00
jmiller c4dc9df9a0 chore: sync ci-generic.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
2026-06-28 18:46:58 +00:00
gitea-actions[bot] 04e27d6a79 chore(version): auto-bump patch 06.00.14-dev [skip ci] 2026-06-28 18:46:05 +00:00
jmiller c6d7cd82ca chore: sync notify.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
2026-06-28 18:45:41 +00:00
gitea-actions[bot] 227e79323a chore(version): auto-bump patch 06.00.13-dev [skip ci] 2026-06-28 18:45:12 +00:00
jmiller 7a05fc1967 chore: sync issue-branch.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
2026-06-28 18:45:00 +00:00
gitea-actions[bot] b36718456a chore(version): auto-bump patch 06.00.12-dev [skip ci] 2026-06-28 18:44:20 +00:00
jmiller 3f6f59314d chore: sync cascade-dev.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
2026-06-28 18:44:00 +00:00
gitea-actions[bot] fafab76b12 chore(version): auto-bump patch 06.00.11-dev [skip ci] 2026-06-28 18:43:56 +00:00
jmiller d400573bb8 chore: sync branch-cleanup.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
2026-06-28 18:43:46 +00:00
gitea-actions[bot] 8da3132dfd chore(version): auto-bump patch 06.00.10-dev [skip ci] 2026-06-28 18:43:17 +00:00
jmiller 29f3db79c3 chore: sync auto-release.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
2026-06-28 18:43:09 +00:00
gitea-actions[bot] 92ef8c6169 chore(version): auto-bump patch 06.00.09-dev [skip ci] 2026-06-28 18:42:47 +00:00
jmiller a5c33c7260 chore: sync gitleaks.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
2026-06-28 18:42:37 +00:00
gitea-actions[bot] 3d1cd3ca99 chore(version): auto-bump patch 06.00.08-dev [skip ci] 2026-06-28 18:41:32 +00:00
jmiller 0f95248b91 chore: sync cleanup.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
2026-06-28 18:41:22 +00:00
gitea-actions[bot] 526602e458 chore(version): auto-bump patch 06.00.07-dev [skip ci] 2026-06-28 18:40:36 +00:00
jmiller 8b7ad6205b chore: sync ci-issue-reporter.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
2026-06-28 18:40:20 +00:00
gitea-actions[bot] bfea806bfe chore(version): auto-bump patch 06.00.06-dev [skip ci] 2026-06-28 18:39:51 +00:00
jmiller 3755a3e6b9 chore: sync ci-generic.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
2026-06-28 18:39:37 +00:00
gitea-actions[bot] c91c575dc3 chore(version): auto-bump patch 06.00.05-dev [skip ci] 2026-06-28 18:38:18 +00:00
jmiller 569516e339 chore: sync cascade-dev.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
2026-06-28 18:36:47 +00:00
jmiller d65090a02a chore: sync branch-cleanup.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
2026-06-28 18:36:32 +00:00
jmiller b1cc06df76 chore: sync auto-release.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
2026-06-28 18:35:50 +00:00
jmiller 07941bd879 chore: sync auto-bump.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
2026-06-28 18:35:41 +00:00
jmiller 9ae6fcd0c6 chore: sync version.md from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
2026-06-28 18:34:05 +00:00
jmiller 1faf6b99ea chore: sync security.md from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 12s
2026-06-28 18:33:52 +00:00
jmiller e0a09db11a chore: sync rfc.md from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 12s
2026-06-28 18:32:53 +00:00
gitea-actions[bot] 3b9e301593 chore(version): auto-bump patch 06.00.04-dev [skip ci] 2026-06-28 18:32:34 +00:00
jmiller 91ab4fca8b chore: sync question.md from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
2026-06-28 18:31:48 +00:00
gitea-actions[bot] a4a7662d0f chore(version): auto-bump patch 06.00.03-dev [skip ci] 2026-06-28 18:31:21 +00:00
jmiller 2ce9737226 chore: sync joomla_issue.md from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 10s
2026-06-28 18:31:10 +00:00
gitea-actions[bot] 5677bc1be0 chore(version): auto-bump patch 06.00.02-dev [skip ci] 2026-06-28 18:30:53 +00:00
jmiller 416940fad0 chore: sync feature_request.md from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 9s
2026-06-28 18:30:22 +00:00
gitea-actions[bot] bf71002f76 chore(version): auto-bump patch 06.00.01-dev [skip ci] 2026-06-28 18:28:42 +00:00
jmiller 613a542d1a chore: sync auto-bump.yml from Template-Joomla
Universal: Auto Version Bump / Version Bump (push) Successful in 7s
2026-06-28 18:28:30 +00:00
jmiller 214275143a chore: sync documentation.md from Template-Joomla 2026-06-28 18:27:49 +00:00
jmiller fee45caa4b chore: sync config.yml from Template-Joomla 2026-06-28 18:27:23 +00:00
jmiller 2d97003fcc chore: sync bug_report.md from Template-Joomla 2026-06-28 18:27:00 +00:00
jmiller 725668669a chore: sync adr.md from Template-Joomla 2026-06-28 18:26:22 +00:00
jmiller a865d7b6d5 chore: sync branch-protection.yml from Template-Joomla 2026-06-28 18:22:13 +00:00
jmiller 5143ae12fb chore: sync SECURITY.md from Template-Joomla 2026-06-28 18:19:09 +00:00
jmiller 2ffbe9b5ea chore: sync GOVERNANCE.md from Template-Joomla 2026-06-28 18:15:31 +00:00
jmiller 3643b6c10f chore: sync CONTRIBUTING.md from Template-Joomla 2026-06-28 18:13:33 +00:00
jmiller 394f760176 chore: sync CODE_OF_CONDUCT.md from Template-Joomla 2026-06-28 18:10:24 +00:00
jmiller 1b54dca8fb chore: sync phpstan.neon from Template-Joomla 2026-06-28 18:09:27 +00:00
jmiller 9ac62f840a chore: sync composer.json from Template-Joomla 2026-06-28 18:09:04 +00:00
jmiller 422403e06d chore: sync .editorconfig from Template-Joomla 2026-06-28 18:08:31 +00:00
jmiller 5fe72ff418 chore: remove test file 2026-06-27 20:22:26 +00:00
jmiller 5bb927d6e3 feat: complete scaffold with system plugin, component, and webservices plugin 2026-06-27 15:20:32 -05:00
jmiller 354cb35ef3 feat: scaffold batch 2 2026-06-27 20:18:37 +00:00
jmiller e66e00e700 feat: scaffold batch 1 2026-06-27 20:18:37 +00:00
jmiller 5fe27b614d feat: initial scaffold 2026-06-27 20:18:36 +00:00
jmiller 0af1d08426 feat: initial scaffold 2026-06-27 20:16:02 +00:00
52 changed files with 1748 additions and 12 deletions
+7
View File
@@ -0,0 +1,7 @@
.claude/
.mcp.json
TODO.md
*.min.css
*.min.js
vendor/
node_modules/
+110
View File
@@ -0,0 +1,110 @@
---
name: Architecture Decision Record (ADR)
about: Propose or document an architectural decision
title: '[ADR] '
labels: 'architecture, decision'
assignees: ''
---
## ADR Number
ADR-XXXX
## Status
- [ ] Proposed
- [ ] Accepted
- [ ] Deprecated
- [ ] Superseded by ADR-XXXX
## Context
Describe the issue or problem that motivates this decision.
## Decision
State the architecture decision and provide rationale.
## Consequences
### Positive
- List positive consequences
### Negative
- List negative consequences or trade-offs
### Neutral
- List neutral aspects
## Alternatives Considered
### Alternative 1
- Description
- Pros
- Cons
- Why not chosen
### Alternative 2
- Description
- Pros
- Cons
- Why not chosen
## Implementation Plan
1. Step 1
2. Step 2
3. Step 3
## Stakeholders
- **Decision Makers**: @user1, @user2
- **Consulted**: @user3, @user4
- **Informed**: team-name
## Technical Details
### Architecture Diagram
```
[Add diagram or link]
```
### Dependencies
- Dependency 1
- Dependency 2
### Impact Analysis
- **Performance**: [Impact description]
- **Security**: [Impact description]
- **Scalability**: [Impact description]
- **Maintainability**: [Impact description]
## Testing Strategy
- [ ] Unit tests
- [ ] Integration tests
- [ ] Performance tests
- [ ] Security tests
## Documentation
- [ ] Architecture documentation updated
- [ ] API documentation updated
- [ ] Developer guide updated
- [ ] Runbook created
## Migration Path
Describe how to migrate from current state to new architecture.
## Rollback Plan
Describe how to rollback if issues occur.
## Timeline
- **Proposal Date**:
- **Decision Date**:
- **Implementation Start**:
- **Expected Completion**:
## References
- Related ADRs:
- External resources:
- RFCs:
## Review Checklist
- [ ] Aligns with enterprise architecture principles
- [ ] Security implications reviewed
- [ ] Performance implications reviewed
- [ ] Cost implications reviewed
- [ ] Compliance requirements met
- [ ] Team consensus achieved
+48
View File
@@ -0,0 +1,48 @@
---
name: Bug Report
about: Report a bug or issue with the project
title: '[BUG] '
labels: 'bug'
assignees: ''
---
## Bug Description
A clear and concise description of what the bug is.
## Steps to Reproduce
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See error
## Expected Behavior
A clear and concise description of what you expected to happen.
## Actual Behavior
A clear and concise description of what actually happened.
## Screenshots
If applicable, add screenshots to help explain your problem.
## Environment
- **Project**: [e.g., MokoDoliTools, moko-cassiopeia]
- **Version**: [e.g., 1.2.3]
- **Platform**: [e.g., Dolibarr 18.0, Joomla 5.0]
- **PHP Version**: [e.g., 8.1]
- **Database**: [e.g., MySQL 8.0, PostgreSQL 14]
- **Browser** (if applicable): [e.g., Chrome 120, Firefox 121]
- **OS**: [e.g., Ubuntu 22.04, Windows 11]
## Additional Context
Add any other context about the problem here.
## Possible Solution
If you have suggestions on how to fix the issue, please describe them here.
## Checklist
- [ ] I have searched for similar issues before creating this one
- [ ] I have provided all the requested information
- [ ] I have tested this on the latest stable version
- [ ] I have checked the documentation and couldn't find a solution
+18
View File
@@ -0,0 +1,18 @@
---
blank_issues_enabled: true
contact_links:
- name: 💼 Enterprise Support
url: https://mokoconsulting.tech/enterprise
about: Enterprise-level support and consultation services
- name: 💬 Ask a Question
url: https://mokoconsulting.tech/
about: Get help or ask questions through our website
- name: 📚 MokoStandards Documentation
url: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
about: View our coding standards and best practices
- name: 🔒 Report a Security Vulnerability
url: https://git.mokoconsulting.tech/mokoconsulting-tech/.github-private/security/advisories/new
about: Report security vulnerabilities privately (for critical issues)
- name: 💡 Community Discussions
url: https://github.com/orgs/mokoconsulting-tech/discussions
about: Join community discussions and Q&A
@@ -0,0 +1,52 @@
---
name: Documentation Issue
about: Report an issue with documentation
title: '[DOCS] '
labels: 'documentation'
assignees: ''
---
## Documentation Issue
**Location**:
<!-- Specify the file, page, or section with the issue -->
## Issue Type
<!-- Mark the relevant option with an "x" -->
- [ ] Typo or grammar error
- [ ] Outdated information
- [ ] Missing documentation
- [ ] Unclear explanation
- [ ] Broken links
- [ ] Missing examples
- [ ] Other (specify below)
## Description
<!-- Clearly describe the documentation issue -->
## Current Content
<!-- Quote or describe the current documentation (if applicable) -->
```
Current text here
```
## Suggested Improvement
<!-- Provide your suggestion for how to improve the documentation -->
```
Suggested text here
```
## Additional Context
<!-- Add any other context, screenshots, or references -->
## Standards Alignment
- [ ] Follows MokoStandards documentation guidelines
- [ ] Uses en_US/en_GB localization
- [ ] Includes proper SPDX headers where applicable
## Checklist
- [ ] I have searched for similar documentation issues
- [ ] I have provided a clear description
- [ ] I have suggested an improvement (if applicable)
@@ -0,0 +1,51 @@
---
name: Feature Request
about: Suggest a new feature or enhancement
title: '[FEATURE] '
labels: 'enhancement'
assignees: ''
---
## Feature Description
A clear and concise description of the feature you'd like to see.
## Problem or Use Case
Describe the problem this feature would solve or the use case it addresses.
Ex. I'm always frustrated when [...]
## Proposed Solution
A clear and concise description of what you want to happen.
## Alternative Solutions
A clear and concise description of any alternative solutions or features you've considered.
## Benefits
Describe how this feature would benefit users:
- Who would use this feature?
- What problems does it solve?
- What value does it add?
## Implementation Details (Optional)
If you have ideas about how this could be implemented, share them here:
- Technical approach
- Files/components that might need changes
- Any concerns or challenges you foresee
## Additional Context
Add any other context, mockups, or screenshots about the feature request here.
## Relevant Standards
Does this relate to any standards in [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards)?
- [ ] Accessibility (WCAG 2.1 AA)
- [ ] Localization (en_US/en_GB)
- [ ] Security best practices
- [ ] Code quality standards
- [ ] Other: [specify]
## Checklist
- [ ] I have searched for similar feature requests before creating this one
- [ ] I have clearly described the use case and benefits
- [ ] I have considered alternative solutions
- [ ] This feature aligns with the project's goals and scope
+87
View File
@@ -0,0 +1,87 @@
---
name: Joomla Extension Issue
about: Report an issue with a Joomla extension
title: '[JOOMLA] '
labels: 'joomla'
assignees: ''
---
## Issue Type
- [ ] Component Issue
- [ ] Module Issue
- [ ] Plugin Issue
- [ ] Template Issue
## Extension Details
- **Extension Name**: [e.g., moko-cassiopeia]
- **Extension Version**: [e.g., 1.2.3]
- **Extension Type**: [Component / Module / Plugin / Template]
## Joomla Environment
- **Joomla Version**: [e.g., 4.4.0, 5.0.0]
- **PHP Version**: [e.g., 8.1.0]
- **Database**: [MySQL / PostgreSQL / MariaDB]
- **Database Version**: [e.g., 8.0]
- **Server**: [Apache / Nginx / IIS]
- **Hosting**: [Shared / VPS / Dedicated / Cloud]
## Issue Description
Provide a clear and detailed description of the issue.
## Steps to Reproduce
1. Go to '...'
2. Click on '...'
3. Configure '...'
4. See error
## Expected Behavior
What you expected to happen.
## Actual Behavior
What actually happened.
## Error Messages
```
# Paste any error messages from Joomla error logs
# Location: administrator/logs/error.php
```
## Browser Console Errors
```javascript
// Paste any JavaScript console errors (F12 in browser)
```
## Screenshots
Add screenshots to help explain the issue.
## Configuration
```ini
# Paste extension configuration (sanitize sensitive data)
```
## Installed Extensions
List other installed extensions that might conflict:
- Extension 1 (version)
- Extension 2 (version)
## Template Overrides
- [ ] Using template overrides
- [ ] Custom CSS
- [ ] Custom JavaScript
## Additional Context
- **Multilingual Site**: [Yes / No]
- **Cache Enabled**: [Yes / No]
- **Debug Mode**: [Yes / No]
- **SEF URLs**: [Yes / No]
## Checklist
- [ ] I have cleared Joomla cache
- [ ] I have disabled other extensions to test for conflicts
- [ ] I have checked Joomla error logs
- [ ] I have tested with a default Joomla template
- [ ] I have checked browser console for JavaScript errors
- [ ] I have searched for similar issues
- [ ] I am using a supported Joomla version
+82
View File
@@ -0,0 +1,82 @@
---
name: Question
about: Ask a question about usage, features, or best practices
title: '[QUESTION] '
labels: ['question']
assignees: ['jmiller']
---
## Question
**Your question:**
## Context
**What are you trying to accomplish?**
**What have you already tried?**
**Category**:
- [ ] Script usage
- [ ] Configuration
- [ ] Workflow setup
- [ ] Documentation interpretation
- [ ] Best practices
- [ ] Integration
- [ ] Other: __________
## Environment (if relevant)
**Your setup**:
- Operating System:
- Version:
## What You've Researched
**Documentation reviewed**:
- [ ] README.md
- [ ] Project documentation
- [ ] Other (specify): __________
**Similar issues/questions found**:
- #
- #
## Expected Outcome
**What result are you hoping for?**
## Code/Configuration Samples
**Relevant code or configuration** (if applicable):
```bash
# Your code here
```
## Additional Context
**Any other relevant information:**
**Screenshots** (if helpful):
## Urgency
- [ ] Urgent (blocking work)
- [ ] Normal (can work on other things meanwhile)
- [ ] Low priority (just curious)
## Checklist
- [ ] I have searched existing issues and discussions
- [ ] I have reviewed relevant documentation
- [ ] I have provided sufficient context
- [ ] I have included code/configuration samples if relevant
- [ ] This is a genuine question (not a bug report or feature request)
+126
View File
@@ -0,0 +1,126 @@
---
name: Request for Comments (RFC)
about: Propose a significant change for community discussion
title: '[RFC] '
labels: 'rfc, discussion'
assignees: ''
---
## RFC Summary
One-paragraph summary of the proposal.
## Motivation
Why are we doing this? What use cases does it support? What is the expected outcome?
## Detailed Design
### Overview
Provide a detailed explanation of the proposed change.
### API Changes (if applicable)
```php
// Before
function oldApi($param1) { }
// After
function newApi($param1, $param2) { }
```
### User Experience Changes
Describe how users will interact with this change.
### Implementation Approach
High-level implementation strategy.
## Drawbacks
Why should we *not* do this?
## Alternatives
What other designs have been considered? What is the impact of not doing this?
### Alternative 1
- Description
- Trade-offs
### Alternative 2
- Description
- Trade-offs
## Adoption Strategy
How will existing users adopt this? Is this a breaking change?
### Migration Guide
```bash
# Steps to migrate
```
### Deprecation Timeline
- **Announcement**:
- **Deprecation**:
- **Removal**:
## Unresolved Questions
- Question 1
- Question 2
## Future Possibilities
What future work does this enable?
## Impact Assessment
### Performance
Expected performance impact.
### Security
Security considerations and implications.
### Compatibility
- **Backward Compatible**: [Yes / No]
- **Breaking Changes**: [List]
### Maintenance
Long-term maintenance considerations.
## Community Input
### Stakeholders
- [ ] Core team
- [ ] Module developers
- [ ] End users
- [ ] Enterprise customers
### Feedback Period
**Duration**: [e.g., 2 weeks]
**Deadline**: [date]
## Implementation Timeline
### Phase 1: Design
- [ ] RFC discussion
- [ ] Design finalization
- [ ] Approval
### Phase 2: Implementation
- [ ] Core implementation
- [ ] Tests
- [ ] Documentation
### Phase 3: Release
- [ ] Beta release
- [ ] Feedback collection
- [ ] Stable release
## Success Metrics
How will we measure success?
- Metric 1
- Metric 2
## References
- Related RFCs:
- External documentation:
- Prior art:
## Open Questions for Community
1. Question 1?
2. Question 2?
---
**Note**: This RFC is open for community discussion. Please provide feedback in the comments below.
+51
View File
@@ -0,0 +1,51 @@
---
name: Security Vulnerability Report
about: Report a security vulnerability (use only for non-critical issues)
title: '[SECURITY] '
labels: 'security'
assignees: ''
---
## ⚠️ IMPORTANT: Private Disclosure Required
**For critical security vulnerabilities, DO NOT use this template.**
Follow the process in [SECURITY.md](../SECURITY.md) for responsible disclosure.
Use this template only for:
- Security improvements
- Non-critical security suggestions
- Security documentation updates
---
## Security Issue
**Severity**:
<!-- Low, Medium, or informational only -->
## Description
<!-- Describe the security concern or improvement suggestion -->
## Affected Components
<!-- List the affected files, features, or components -->
## Suggested Mitigation
<!-- Describe how this could be addressed -->
## Standards Reference
Does this relate to security standards in [MokoStandards](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards)?
- [ ] SPDX license identifiers
- [ ] Secret management
- [ ] Dependency security
- [ ] Access control
- [ ] Other: [specify]
## Additional Context
<!-- Add any other context about the security concern -->
## Checklist
- [ ] This is NOT a critical vulnerability requiring private disclosure
- [ ] I have reviewed the SECURITY.md policy
- [ ] I have provided sufficient detail for evaluation
+24
View File
@@ -0,0 +1,24 @@
---
name: Version Bump
about: Request or track a version change
title: '[VERSION] '
labels: 'version, type: version'
assignees: 'jmiller'
---
## Version Change
**Current version**: <!-- e.g., 01.02.03 -->
**Requested version**: <!-- e.g., 01.03.00 -->
**Change type**: <!-- patch / minor / major -->
## Reason
<!-- Why is this version bump needed? -->
## Checklist
- [ ] README.md `VERSION:` field updated
- [ ] CHANGELOG.md entry added
- [ ] Module descriptor version updated (Dolibarr: `$this->version`, Joomla: `<version>`)
- [ ] All file headers will be auto-propagated by `sync-version-on-merge` workflow
+251
View File
@@ -0,0 +1,251 @@
# Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
# SPDX-License-Identifier: GPL-3.0-or-later
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: moko-platform.Automation
# REPO: https://git.mokoconsulting.tech/MokoConsulting/moko-platform
# PATH: /.gitea/workflows/branch-protection.yml
# BRIEF: Apply standardised branch protection rules to all governed repositories
#
# +========================================================================+
# | BRANCH PROTECTION SETUP |
# +========================================================================+
# | |
# | Applies protection rules for: main, dev, rc, beta, alpha |
# | |
# | main — Require PR, block rejected reviews, no force push |
# | dev — Allow push, no force push, no delete |
# | rc — Allow push, no force push, no delete |
# | beta — Allow push, no force push, no delete |
# | alpha — Allow push, no force push, no delete |
# | |
# | jmiller has override authority on all branches. |
# | |
# +========================================================================+
name: Branch Protection Setup
on:
schedule:
- cron: '0 2 * * 1' # Weekly Monday 02:00 UTC
workflow_dispatch:
inputs:
dry_run:
description: 'Preview mode (no changes)'
required: false
type: boolean
default: false
repos:
description: 'Comma-separated repo names (empty = all governed repos)'
required: false
type: string
default: ''
env:
GITEA_URL: https://git.mokoconsulting.tech
GITEA_ORG: MokoConsulting
permissions:
contents: read
jobs:
protect:
name: Apply Branch Protection Rules
runs-on: ubuntu-latest
steps:
- name: Determine target repos
id: repos
env:
GA_TOKEN: ${{ secrets.GA_TOKEN }}
run: |
API="${GITEA_URL}/api/v1"
# Platform/standards/infra repos to exclude
EXCLUDE="gitea-org-config org-profile gitea-private .mokogitea-private MokoStandards moko-platform MokoTesting"
EXCLUDE="$EXCLUDE MokoStandards-Template-Client MokoStandards-Template-Dolibarr MokoStandards-Template-Generic MokoStandards-Template-Joomla MokoDoliProjTemplate"
if [ -n "${{ inputs.repos }}" ]; then
# User-specified repos
REPOS=$(echo "${{ inputs.repos }}" | tr ',' ' ')
else
# Fetch all org repos
PAGE=1
REPOS=""
while true; do
BATCH=$(curl -sS \
-H "Authorization: token ${GA_TOKEN}" \
"${API}/orgs/${GITEA_ORG}/repos?page=${PAGE}&limit=50" \
| jq -r '.[].name // empty')
[ -z "$BATCH" ] && break
REPOS="$REPOS $BATCH"
PAGE=$((PAGE + 1))
done
# Filter out excluded repos
FILTERED=""
for REPO in $REPOS; do
SKIP=false
for EX in $EXCLUDE; do
if [ "$REPO" = "$EX" ]; then
SKIP=true
break
fi
done
if [ "$SKIP" = "false" ]; then
FILTERED="$FILTERED $REPO"
fi
done
REPOS="$FILTERED"
fi
echo "repos=$REPOS" >> "$GITHUB_OUTPUT"
COUNT=$(echo "$REPOS" | wc -w)
echo "📋 Target repos (${COUNT}): $REPOS"
- name: Apply protection rules
env:
GA_TOKEN: ${{ secrets.GA_TOKEN }}
DRY_RUN: ${{ inputs.dry_run || 'false' }}
run: |
API="${GITEA_URL}/api/v1"
REPOS="${{ steps.repos.outputs.repos }}"
SUCCESS=0
FAILED=0
SKIPPED=0
# ── Rule definitions ──────────────────────────────────────
# Only the CI bot (jmiller token) can push directly.
# All human contributors must use PRs.
# Force push disabled on all branches.
RULE_MAIN='{
"rule_name": "main",
"enable_push": true,
"enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"],
"enable_force_push": false,
"enable_force_push_allowlist": false,
"force_push_allowlist_usernames": [],
"enable_merge_whitelist": false,
"required_approvals": 0,
"dismiss_stale_approvals": true,
"block_on_rejected_reviews": true,
"block_on_outdated_branch": false,
"priority": 1
}'
RULE_DEV='{
"rule_name": "dev",
"enable_push": true,
"enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"],
"enable_force_push": false,
"enable_force_push_allowlist": false,
"force_push_allowlist_usernames": [],
"enable_merge_whitelist": false,
"required_approvals": 0,
"block_on_rejected_reviews": false,
"priority": 2
}'
RULE_RC='{
"rule_name": "rc",
"enable_push": true,
"enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"],
"enable_force_push": false,
"enable_force_push_allowlist": false,
"force_push_allowlist_usernames": [],
"enable_merge_whitelist": false,
"required_approvals": 0,
"block_on_rejected_reviews": false,
"priority": 3
}'
RULE_BETA='{
"rule_name": "beta",
"enable_push": true,
"enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"],
"enable_force_push": false,
"enable_force_push_allowlist": false,
"force_push_allowlist_usernames": [],
"enable_merge_whitelist": false,
"required_approvals": 0,
"block_on_rejected_reviews": false,
"priority": 4
}'
RULE_ALPHA='{
"rule_name": "alpha",
"enable_push": true,
"enable_push_whitelist": true,
"push_whitelist_usernames": ["jmiller"],
"enable_force_push": false,
"enable_force_push_allowlist": false,
"force_push_allowlist_usernames": [],
"enable_merge_whitelist": false,
"required_approvals": 0,
"block_on_rejected_reviews": false,
"priority": 5
}'
RULES=("$RULE_MAIN" "$RULE_DEV" "$RULE_RC" "$RULE_BETA" "$RULE_ALPHA")
RULE_NAMES=("main" "dev" "rc" "beta" "alpha")
# ── Apply rules to each repo ──────────────────────────────
for REPO in $REPOS; do
echo ""
echo "═══ ${REPO} ═══"
for i in "${!RULES[@]}"; do
RULE="${RULES[$i]}"
NAME="${RULE_NAMES[$i]}"
if [ "$DRY_RUN" = "true" ]; then
echo " [DRY RUN] Would apply rule: ${NAME}"
SKIPPED=$((SKIPPED + 1))
continue
fi
# Delete existing rule if present (idempotent recreate)
ENCODED_NAME=$(echo "$NAME" | sed 's|/|%2F|g')
curl -sS -o /dev/null -w "" \
-X DELETE \
-H "Authorization: token ${GA_TOKEN}" \
"${API}/repos/${GITEA_ORG}/${REPO}/branch_protections/${ENCODED_NAME}" 2>/dev/null || true
# Create rule
RESPONSE=$(curl -sS -w "\n%{http_code}" \
-X POST \
-H "Authorization: token ${GA_TOKEN}" \
-H "Content-Type: application/json" \
-d "$RULE" \
"${API}/repos/${GITEA_ORG}/${REPO}/branch_protections")
HTTP=$(echo "$RESPONSE" | tail -1)
BODY=$(echo "$RESPONSE" | sed '$d')
if [ "$HTTP" = "201" ]; then
echo " ✅ ${NAME}"
SUCCESS=$((SUCCESS + 1))
else
echo " ❌ ${NAME} (HTTP ${HTTP}): $(echo "$BODY" | jq -r '.message // .' 2>/dev/null | head -1)"
FAILED=$((FAILED + 1))
fi
done
done
# ── Summary ───────────────────────────────────────────────
echo ""
echo "════════════════════════════════════════"
echo " ✅ Success: ${SUCCESS}"
echo " ❌ Failed: ${FAILED}"
echo " ⏭️ Skipped: ${SKIPPED}"
echo "════════════════════════════════════════"
if [ "$FAILED" -gt 0 ]; then
echo "::warning::${FAILED} rule(s) failed to apply"
fi
+1 -3
View File
@@ -7,7 +7,7 @@
# INGROUP: mokocli.Release # INGROUP: mokocli.Release
# REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli # REPO: https://git.mokoconsulting.tech/mokoconsulting-tech/mokocli
# PATH: /templates/workflows/universal/auto-release.yml.template # PATH: /templates/workflows/universal/auto-release.yml.template
# VERSION: 05.01.00 # VERSION: 05.00.00
# BRIEF: Universal build & release detects platform from manifest.xml # BRIEF: Universal build & release detects platform from manifest.xml
# #
# +=======================================================================+ # +=======================================================================+
@@ -75,7 +75,6 @@ jobs:
with: with:
token: ${{ secrets.MOKOGITEA_TOKEN }} token: ${{ secrets.MOKOGITEA_TOKEN }}
fetch-depth: 1 fetch-depth: 1
submodules: recursive
- name: Setup mokocli tools - name: Setup mokocli tools
env: env:
@@ -174,7 +173,6 @@ jobs:
with: with:
token: ${{ secrets.MOKOGITEA_TOKEN }} token: ${{ secrets.MOKOGITEA_TOKEN }}
fetch-depth: 0 fetch-depth: 0
submodules: recursive
- name: Configure git for bot pushes - name: Configure git for bot pushes
run: | run: |
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION # FILE INFORMATION
# DEFGROUP: Gitea.Workflow # DEFGROUP: Gitea.Workflow
# INGROUP: mokocli.Automation # INGROUP: mokocli.Automation
# VERSION: 01.00.00 # VERSION: 06.00.33
# BRIEF: Auto-create feature branch when an issue is opened # BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch" name: "Universal: Issue Branch"
+17
View File
@@ -0,0 +1,17 @@
<!--
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later
-->
# Changelog
## [Unreleased]
### Added
- **Repository** -- initial scaffold
- **System Plugin** -- Extension class, service provider
- **SQL Schema** -- 9 tables
- **Admin Component** -- 6 views
- **Webservices Plugin** -- API routes
- **Configuration** -- plugin settings
- **Access Control** -- granular permissions
+18
View File
@@ -0,0 +1,18 @@
# MokoSuiteGym
Fitness and gym membership management for Joomla 6.
## Quick Reference
| Field | Value |
|---|---|
| **Package** | `pkg_mokosuitegym` |
| **Layer** | 2 (requires: Client, CRM) |
| **Language** | PHP 8.3+ |
| **Branch** | develop on `dev`, merge to `main` (protected) |
## Rules
- **Never commit** `.claude/`, `.mcp.json`, `TODO.md`, `*.min.css`/`*.min.js`
- **Attribution**: `Authored-by: Moko Consulting`
- **Changelog**: `[Unreleased]` only
+1 -1
View File
@@ -14,7 +14,7 @@
DEFGROUP: Template-Joomla DEFGROUP: Template-Joomla
INGROUP: Template-Joomla.Documentation INGROUP: Template-Joomla.Documentation
REPO: https://github.com/mokoconsulting-tech/Template-Joomla/ REPO: https://github.com/mokoconsulting-tech/Template-Joomla/
VERSION: 01.01.00 VERSION: 06.00.33
PATH: ./CODE_OF_CONDUCT.md PATH: ./CODE_OF_CONDUCT.md
BRIEF: Community expectations and enforcement guidelines BRIEF: Community expectations and enforcement guidelines
NOTE: Adapted with attribution from the Contributor Covenant v2.1 NOTE: Adapted with attribution from the Contributor Covenant v2.1
+1 -1
View File
@@ -19,7 +19,7 @@
DEFGROUP: mokoconsulting-tech.Template-Joomla DEFGROUP: mokoconsulting-tech.Template-Joomla
INGROUP: MokoStandards.Governance INGROUP: MokoStandards.Governance
REPO: https://github.com/mokoconsulting-tech/Template-Joomla REPO: https://github.com/mokoconsulting-tech/Template-Joomla
VERSION: 01.01.00 VERSION: 06.00.33
PATH: /GOVERNANCE.md PATH: /GOVERNANCE.md
BRIEF: Project governance rules, roles, and decision process for Template-Joomla BRIEF: Project governance rules, roles, and decision process for Template-Joomla
--> -->
+21 -1
View File
@@ -1,3 +1,23 @@
<!--
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
SPDX-License-Identifier: GPL-3.0-or-later
-->
# MokoSuite Gym # MokoSuite Gym
MokoSuite Gym — fitness center memberships, class scheduling, check-ins, personal training, progress tracking for Joomla 6 Fitness and gym membership management for MokoSuite on Joomla 6.
## Overview
MokoSuiteGym is a **Layer 2** extension in the MokoSuite platform.
## Requirements
- Joomla 6.x
- PHP 8.3+
- MokoSuiteClient (Layer 0)
- MokoSuiteCRM (Layer 1)
## License
GNU General Public License v3.0 or later.
+1 -1
View File
@@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla
INGROUP: Template-Joomla.Documentation INGROUP: Template-Joomla.Documentation
REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
PATH: /SECURITY.md PATH: /SECURITY.md
VERSION: 01.01.00 VERSION: 06.00.33
BRIEF: Security vulnerability reporting and handling policy BRIEF: Security vulnerability reporting and handling policy
--> -->
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<access component="com_mokosuitegym">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" />
<action name="core.options" title="JACTION_OPTIONS" />
<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="core.edit.own" title="JACTION_EDITOWN" />
<action name="gym.manage.members" title="Manage Members" />
<action name="gym.manage.classes" title="Manage Classes" />
<action name="gym.manage.trainers" title="Manage Trainers" />
<action name="gym.manage.equipment" title="Manage Equipment" />
<action name="gym.view.reports" title="View Reports" />
</section>
</access>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<config>
<fieldset name="permissions" label="JCONFIG_PERMISSIONS_LABEL" description="JCONFIG_PERMISSIONS_DESC">
<field name="rules" type="rules" label="JCONFIG_PERMISSIONS_LABEL" validate="rules" filter="rules" component="com_mokosuitegym" section="component" />
</fieldset>
</config>
@@ -0,0 +1,9 @@
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
; SPDX-License-Identifier: GPL-3.0-or-later
COM_MOKOSUITEGYM="MokoSuite Gym"
COM_MOKOSUITEGYM_DASHBOARD="Dashboard"
COM_MOKOSUITEGYM_MEMBERS="Members"
COM_MOKOSUITEGYM_MEMBERSHIPS="Memberships"
COM_MOKOSUITEGYM_CLASSES="Classes"
COM_MOKOSUITEGYM_TRAINERS="Trainers"
COM_MOKOSUITEGYM_EQUIPMENT="Equipment"
@@ -0,0 +1,4 @@
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
; SPDX-License-Identifier: GPL-3.0-or-later
COM_MOKOSUITEGYM="MokoSuite Gym"
COM_MOKOSUITEGYM_XML_DESCRIPTION="Fitness and gym membership management"
@@ -0,0 +1,28 @@
<?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\ComponentInterface;
use Joomla\CMS\Extension\MVCComponent;
use Joomla\CMS\Dispatcher\ComponentDispatcherFactoryInterface;
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) {
$c = new MVCComponent($container->get(ComponentDispatcherFactoryInterface::class));
$c->setMVCFactory($container->get(MVCFactoryInterface::class));
$c->setRouterFactory($container->get(RouterFactoryInterface::class));
return $c;
});
}
};
@@ -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\MokoSuiteGym\Administrator\Controller;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\BaseController;
class DisplayController extends BaseController
{
protected $default_view = 'gymdashboard';
}
@@ -0,0 +1,17 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteGym\Administrator\Model;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
class GymDashboardModel extends BaseDatabaseModel
{
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteGym\Administrator\View\GymClasses;
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('MokoSuite Gym - Classes');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteGym\Administrator\View\GymDashboard;
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('MokoSuite Gym - Dashboard');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteGym\Administrator\View\GymEquipment;
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('MokoSuite Gym - Equipment');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteGym\Administrator\View\GymMembers;
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('MokoSuite Gym - Members');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteGym\Administrator\View\GymMemberships;
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('MokoSuite Gym - Memberships');
parent::display($tpl);
}
}
@@ -0,0 +1,23 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
* Authored-by: Moko Consulting
*/
namespace Moko\Component\MokoSuiteGym\Administrator\View\GymTrainers;
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('MokoSuite Gym - Trainers');
parent::display($tpl);
}
}
@@ -0,0 +1,11 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
defined('_JEXEC') or die;
?>
<div class="container">
<h2>Classes</h2>
<p>Coming soon.</p>
</div>
@@ -0,0 +1,11 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
defined('_JEXEC') or die;
?>
<div class="container">
<h2>Dashboard</h2>
<p>Coming soon.</p>
</div>
@@ -0,0 +1,11 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
defined('_JEXEC') or die;
?>
<div class="container">
<h2>Equipment</h2>
<p>Coming soon.</p>
</div>
@@ -0,0 +1,11 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
defined('_JEXEC') or die;
?>
<div class="container">
<h2>Members</h2>
<p>Coming soon.</p>
</div>
@@ -0,0 +1,11 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
defined('_JEXEC') or die;
?>
<div class="container">
<h2>Memberships</h2>
<p>Coming soon.</p>
</div>
@@ -0,0 +1,11 @@
<?php
/**
* Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
* SPDX-License-Identifier: GPL-3.0-or-later
*/
defined('_JEXEC') or die;
?>
<div class="container">
<h2>Trainers</h2>
<p>Coming soon.</p>
</div>
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" method="upgrade">
<name>MokoSuite Gym</name>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<creationDate>2026-06-27</creationDate>
<copyright>Copyright (C) 2026 Moko Consulting.</copyright>
<license>GPL-3.0-or-later</license>
<version>06.00.33</version>
<description>Fitness and gym membership management</description>
<namespace path="src">Moko\Component\MokoSuiteGym</namespace>
<administration>
<files folder="admin">
<filename>access.xml</filename>
<filename>config.xml</filename>
<folder>language</folder>
<folder>services</folder>
<folder>src</folder>
<folder>tmpl</folder>
</files>
<languages folder="admin/language">
<language tag="en-GB">en-GB/com_mokosuitegym.ini</language>
<language tag="en-GB">en-GB/com_mokosuitegym.sys.ini</language>
</languages>
<menu>COM_MOKOSUITEGYM</menu>
<submenu>
<menu link="option=com_mokosuitegym&amp;view=gymdashboard">COM_MOKOSUITEGYM_DASHBOARD</menu>
<menu link="option=com_mokosuitegym&amp;view=gymmembers">COM_MOKOSUITEGYM_MEMBERS</menu>
<menu link="option=com_mokosuitegym&amp;view=gymmemberships">COM_MOKOSUITEGYM_MEMBERSHIPS</menu>
<menu link="option=com_mokosuitegym&amp;view=gymclasses">COM_MOKOSUITEGYM_CLASSES</menu>
<menu link="option=com_mokosuitegym&amp;view=gymtrainers">COM_MOKOSUITEGYM_TRAINERS</menu>
<menu link="option=com_mokosuitegym&amp;view=gymequipment">COM_MOKOSUITEGYM_EQUIPMENT</menu>
</submenu>
</administration>
</extension>
@@ -0,0 +1,4 @@
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
; SPDX-License-Identifier: GPL-3.0-or-later
PLG_SYSTEM_MOKOSUITEGYM="System - MokoSuite Gym"
PLG_SYSTEM_MOKOSUITEGYM_DESC="Fitness and gym membership management helpers and schema"
@@ -0,0 +1,4 @@
; Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
; SPDX-License-Identifier: GPL-3.0-or-later
PLG_SYSTEM_MOKOSUITEGYM="System - MokoSuite Gym"
PLG_SYSTEM_MOKOSUITEGYM_DESC="Fitness and gym membership management helpers and schema"
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>System - MokoSuite Gym</name>
<element>mokosuitegym</element>
<author>Moko Consulting</author>
<creationDate>2026-06-27</creationDate>
<copyright>Copyright (C) 2026 Moko Consulting. All rights reserved.</copyright>
<license>GPL-3.0-or-later</license>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<version>06.00.33</version>
<php_minimum>8.3</php_minimum>
<description>PLG_SYSTEM_MOKOSUITEGYM_DESC</description>
<namespace path="src">Moko\Plugin\System\MokoSuiteGym</namespace>
<files><folder>src</folder><folder>services</folder><folder>language</folder><folder>sql</folder></files>
<languages folder="language">
<language tag="en-GB">en-GB/plg_system_mokosuitegym.ini</language>
<language tag="en-GB">en-GB/plg_system_mokosuitegym.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="Gym Defaults"><field name="default_currency" type="text" default="USD" label="Default Currency" /><field name="timezone" type="timezone" default="America/New_York" label="Default Timezone" /></fieldset><fieldset name="membership" label="Membership"><field name="trial_days" type="number" default="7" label="Trial Period (days)" /><field name="grace_period_days" type="number" default="5" label="Grace Period (days)" /><field name="auto_renew" type="radio" default="1" label="Auto-Renew Default" class="btn-group btn-group-yesno"><option value="1">JYES</option><option value="0">JNO</option></field></fieldset><fieldset name="notifications" label="Notifications"><field name="expiry_warning_days" type="number" default="14" label="Expiry Warning (days before)" /></fieldset><fieldset name="display" label="Display"><field name="dashboard_default_view" type="list" default="overview" label="Default Dashboard View"><option value="overview">Overview</option><option value="calendar">Calendar</option><option value="check_ins">Check-Ins</option></field></fieldset></fields></config>
</extension>
@@ -0,0 +1,27 @@
<?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\MokoSuiteGym\Extension\Gym;
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 Gym($dispatcher, (array) PluginHelper::getPlugin('system', 'mokosuitegym'));
$plugin->setApplication(\Joomla\CMS\Factory::getApplication());
return $plugin;
});
}
};
@@ -0,0 +1,176 @@
--
-- MokoSuite Gym Tables
--
CREATE TABLE IF NOT EXISTS `#__mokosuitegym_members` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`contact_id` INT DEFAULT NULL,
`user_id` INT DEFAULT NULL,
`member_number` VARCHAR(20) NOT NULL DEFAULT '',
`first_name` VARCHAR(100) NOT NULL,
`last_name` VARCHAR(100) NOT NULL,
`email` VARCHAR(255) NOT NULL DEFAULT '',
`phone` VARCHAR(50) NOT NULL DEFAULT '',
`date_of_birth` DATE DEFAULT NULL,
`gender` ENUM('male','female','other','prefer_not_to_say') DEFAULT NULL,
`emergency_contact` VARCHAR(255) NOT NULL DEFAULT '',
`emergency_phone` VARCHAR(50) NOT NULL DEFAULT '',
`health_notes` TEXT,
`photo` VARCHAR(500) NOT NULL DEFAULT '',
`status` ENUM('active','inactive','suspended','cancelled') NOT NULL DEFAULT 'active',
`joined_date` DATE NOT NULL,
`notes` TEXT,
`published` TINYINT NOT NULL DEFAULT 1,
`created` DATETIME NOT NULL,
`created_by` INT NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_contact` (`contact_id`),
KEY `idx_user` (`user_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuitegym_membership_plans` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`description` TEXT,
`duration_months` TINYINT UNSIGNED NOT NULL DEFAULT 1,
`price` DECIMAL(10,2) NOT NULL,
`currency` VARCHAR(3) NOT NULL DEFAULT 'USD',
`signup_fee` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`billing_cycle` ENUM('monthly','quarterly','semi_annual','annual','one_time') NOT NULL DEFAULT 'monthly',
`max_classes_per_month` INT DEFAULT NULL,
`guest_passes_per_month` TINYINT UNSIGNED NOT NULL DEFAULT 0,
`features_json` JSON DEFAULT NULL,
`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 `#__mokosuitegym_memberships` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`member_id` INT UNSIGNED NOT NULL,
`plan_id` INT UNSIGNED NOT NULL,
`status` ENUM('trial','active','frozen','expired','cancelled') NOT NULL DEFAULT 'active',
`start_date` DATE NOT NULL,
`end_date` DATE DEFAULT NULL,
`renewal_date` DATE DEFAULT NULL,
`auto_renew` TINYINT NOT NULL DEFAULT 1,
`amount_paid` DECIMAL(10,2) NOT NULL DEFAULT 0.00,
`payment_method` ENUM('cash','card','bank_transfer','online') NOT NULL DEFAULT 'card',
`frozen_at` DATE DEFAULT NULL,
`frozen_until` DATE DEFAULT NULL,
`cancellation_reason` VARCHAR(500) NOT NULL DEFAULT '',
`notes` TEXT,
`created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_member` (`member_id`),
KEY `idx_plan` (`plan_id`),
KEY `idx_status` (`status`),
KEY `idx_dates` (`start_date`, `end_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuitegym_classes` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`description` TEXT,
`category` ENUM('cardio','strength','flexibility','martial_arts','dance','cycling','swimming','yoga','pilates','group_fitness','other') NOT NULL DEFAULT 'group_fitness',
`difficulty` ENUM('beginner','intermediate','advanced','all_levels') NOT NULL DEFAULT 'all_levels',
`duration_minutes` SMALLINT UNSIGNED NOT NULL DEFAULT 60,
`max_capacity` SMALLINT UNSIGNED NOT NULL DEFAULT 20,
`requires_booking` TINYINT NOT NULL DEFAULT 1,
`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 `#__mokosuitegym_class_schedules` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`class_id` INT UNSIGNED NOT NULL,
`trainer_id` INT UNSIGNED DEFAULT NULL,
`day_of_week` TINYINT UNSIGNED NOT NULL,
`start_time` TIME NOT NULL,
`end_time` TIME NOT NULL,
`room` VARCHAR(100) NOT NULL DEFAULT '',
`effective_from` DATE DEFAULT NULL,
`effective_until` DATE DEFAULT NULL,
`published` TINYINT NOT NULL DEFAULT 1,
PRIMARY KEY (`id`),
KEY `idx_class` (`class_id`),
KEY `idx_trainer` (`trainer_id`),
KEY `idx_day` (`day_of_week`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuitegym_class_enrollments` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`schedule_id` INT UNSIGNED NOT NULL,
`member_id` INT UNSIGNED NOT NULL,
`enrollment_date` DATE NOT NULL,
`status` ENUM('enrolled','attended','cancelled','no_show') NOT NULL DEFAULT 'enrolled',
`cancelled_at` DATETIME DEFAULT NULL,
`notes` TEXT,
`created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_schedule` (`schedule_id`),
KEY `idx_member` (`member_id`),
KEY `idx_date` (`enrollment_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuitegym_trainers` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`contact_id` INT DEFAULT NULL,
`user_id` INT DEFAULT NULL,
`display_name` VARCHAR(255) NOT NULL,
`title` VARCHAR(100) NOT NULL DEFAULT '',
`specialties` VARCHAR(500) NOT NULL DEFAULT '',
`certifications` TEXT,
`bio` TEXT,
`email` VARCHAR(255) NOT NULL DEFAULT '',
`phone` VARCHAR(50) NOT NULL DEFAULT '',
`photo` VARCHAR(500) NOT NULL DEFAULT '',
`hourly_rate` DECIMAL(10,2) DEFAULT NULL,
`published` TINYINT NOT NULL DEFAULT 1,
`ordering` INT NOT NULL DEFAULT 0,
`created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_contact` (`contact_id`),
KEY `idx_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuitegym_equipment` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NOT NULL,
`category` ENUM('cardio','strength','free_weights','machines','flexibility','functional','other') NOT NULL DEFAULT 'machines',
`brand` VARCHAR(100) NOT NULL DEFAULT '',
`model` VARCHAR(100) NOT NULL DEFAULT '',
`serial_number` VARCHAR(100) NOT NULL DEFAULT '',
`location` VARCHAR(100) NOT NULL DEFAULT '',
`purchase_date` DATE DEFAULT NULL,
`warranty_until` DATE DEFAULT NULL,
`status` ENUM('active','maintenance','out_of_order','retired') NOT NULL DEFAULT 'active',
`last_maintenance` DATE DEFAULT NULL,
`next_maintenance` DATE DEFAULT NULL,
`maintenance_notes` TEXT,
`photo` VARCHAR(500) NOT NULL DEFAULT '',
`published` TINYINT NOT NULL DEFAULT 1,
`created` DATETIME NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_category` (`category`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE IF NOT EXISTS `#__mokosuitegym_check_ins` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`member_id` INT UNSIGNED NOT NULL,
`check_in_time` DATETIME NOT NULL,
`check_out_time` DATETIME DEFAULT NULL,
`check_in_method` ENUM('scan','manual','app','kiosk') NOT NULL DEFAULT 'scan',
`notes` TEXT,
PRIMARY KEY (`id`),
KEY `idx_member` (`member_id`),
KEY `idx_time` (`check_in_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
@@ -0,0 +1,13 @@
--
-- MokoSuite Gym — Uninstall
--
DROP TABLE IF EXISTS `#__mokosuitegym_check_ins`;
DROP TABLE IF EXISTS `#__mokosuitegym_equipment`;
DROP TABLE IF EXISTS `#__mokosuitegym_trainers`;
DROP TABLE IF EXISTS `#__mokosuitegym_class_enrollments`;
DROP TABLE IF EXISTS `#__mokosuitegym_class_schedules`;
DROP TABLE IF EXISTS `#__mokosuitegym_classes`;
DROP TABLE IF EXISTS `#__mokosuitegym_memberships`;
DROP TABLE IF EXISTS `#__mokosuitegym_membership_plans`;
DROP TABLE IF EXISTS `#__mokosuitegym_members`;
@@ -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\MokoSuiteGym\Extension;
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\SubscriberInterface;
class Gym extends CMSPlugin implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [];
}
}
@@ -0,0 +1,15 @@
<?xml version="1.0"?>
<extension type="plugin" group="webservices" method="upgrade">
<name>Web Services - MokoSuite Gym</name>
<element>mokosuitegym</element>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
<authorUrl>https://mokoconsulting.tech</authorUrl>
<creationDate>2026-06-27</creationDate>
<copyright>Copyright (C) 2026 Moko Consulting.</copyright>
<version>06.00.33</version>
<license>GPL-3.0-or-later</license>
<description>REST API routes for MokoSuite Gym operations</description>
<namespace path="src">Moko\Plugin\WebServices\MokoSuiteGym</namespace>
<files><folder>src</folder><folder>services</folder></files>
</extension>
@@ -0,0 +1,25 @@
<?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\MokoSuiteGym\Extension\MokoSuiteGym;
return new class implements ServiceProviderInterface {
public function register(Container $container): void {
$container->set(PluginInterface::class, function (Container $container) {
$dispatcher = $container->get(DispatcherInterface::class);
return new MokoSuiteGym($dispatcher, (array) PluginHelper::getPlugin('webservices', 'mokosuitegym'));
});
}
};
@@ -0,0 +1,31 @@
<?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\MokoSuiteGym\Extension;
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Router\ApiRouter;
use Joomla\Event\SubscriberInterface;
class MokoSuiteGym extends CMSPlugin implements SubscriberInterface
{
public static function getSubscribedEvents(): array
{
return ['onBeforeApiRoute' => 'onBeforeApiRoute'];
}
public function onBeforeApiRoute($event): void
{
$router = $event->getArgument('router');
foreach (['members', 'memberships', 'plans', 'classes', 'schedules', 'trainers', 'equipment', 'check-ins'] as $route) {
$router->createCRUDRoutes("v1/gym/{$route}", $route, ['component' => 'com_mokosuitegym']);
}
}
}
+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<extension type="package" method="upgrade">
<name>Package - MokoSuite Gym</name>
<packagename>mokosuitegym</packagename>
<version>06.00.33</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. All rights reserved.</copyright>
<license>GNU General Public License version 3 or later; see LICENSE</license>
<description>Fitness and gym membership management</description>
<php_minimum>8.3</php_minimum>
<dlid prefix="dlid=" suffix=""/>
<blockChildUninstall>true</blockChildUninstall>
<scriptfile>script.php</scriptfile>
<files folder="packages">
<file type="plugin" id="plg_system_mokosuitegym" group="system">plg_system_mokosuitegym.zip</file>
<file type="component" id="com_mokosuitegym">com_mokosuitegym.zip</file>
<file type="plugin" id="plg_webservices_mokosuitegym" group="webservices">plg_webservices_mokosuitegym.zip</file>
</files>
<updateservers>
<server type="extension" priority="1" name="Package - MokoSuite Gym">https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteGym/updates.xml</server>
</updateservers>
</extension>
+71
View File
@@ -0,0 +1,71 @@
<?php
/**
* @package MokoSuiteGym
* @subpackage pkg_mokosuitegym
* @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;
class Pkg_MokoSuiteGymInstallerScript
{
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('%MokoSuiteGym%')
. ' OR ' . $db->quoteName('location') . ' LIKE ' . $db->quote('%MokoSuiteGym%') . ')')
->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
}
}
}