Compare commits

...

10 Commits

Author SHA1 Message Date
gitea-actions[bot] e92a963088 chore: promote changelog [Unreleased] → [01.06.00] 2026-06-23 17:09:39 +00:00
gitea-actions[bot] f3a8246e34 chore(release): build 01.06.00 [skip ci]
Publish to Composer / Publish Package (release) Failing after 5s
2026-06-23 17:09:35 +00:00
jmiller c9f50e452b Fix: duplicate license warning, wiki folder cleanup 2026-06-23 17:07:59 +00:00
Jonathan Miller c820d015e7 Merge remote-tracking branch 'origin/main' into dev
Joomla: Extension CI / Tests (PHP 8.2) (pull_request) Blocked by required conditions
Joomla: Extension CI / Tests (PHP 8.3) (pull_request) Blocked by required conditions
Joomla: Extension CI / PHPStan Analysis (pull_request) Blocked by required conditions
Joomla: Extension CI / Build RC Pre-Release (pull_request) Blocked by required conditions
Universal: PR Check / Build RC Package (pull_request) Blocked by required conditions
Universal: PR Check / Report Issues (pull_request) Blocked by required conditions
Generic: Repo Health / Scripts governance (pull_request) Blocked by required conditions
Generic: Repo Health / Repository health (pull_request) Blocked by required conditions
Generic: Repo Health / Report Issues (pull_request) Blocked by required conditions
Universal: Auto Version Bump / Version Bump (push) Successful in 11s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 27s
Universal: Build & Release / Promote to RC (pull_request) Has been skipped
Universal: Build & Release / Build & Release Pipeline (pull_request) Successful in 23s
Universal: PR Check / Branch Policy (pull_request) Successful in 1s
Joomla: Extension CI / Release Readiness Check (pull_request) Failing after 3s
Joomla: Extension CI / Lint & Validate (pull_request) Failing after 7s
Generic: Repo Health / Access control (pull_request) Successful in 3s
Universal: PR Check / Secret Scan (pull_request) Successful in 8s
Generic: Repo Health / Site Health (pull_request) Has been skipped
Branch Cleanup / Delete merged branch (pull_request) Has been skipped
RC Revert / Rename rc/ back to dev/ (pull_request) Has been skipped
Joomla: Metadata Validation / Validate Joomla Metadata (pull_request) Successful in 16s
Universal: PR Check / Validate PR (pull_request) Failing after 45s
Universal: Workflow Sync Trigger / Sync workflows to live repos (pull_request) Failing after 3m46s
2026-06-23 12:07:01 -05:00
gitea-actions[bot] 78cbd1f370 chore(version): pre-release bump to 01.05.02-dev [skip ci]
Publish to Composer / Publish Package (release) Failing after 38s
2026-06-23 17:01:51 +00:00
Jonathan Miller 70d2bab52d fix: remove duplicate license warning from system plugin
Universal: Auto Version Bump / Version Bump (push) Successful in 8s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 18s
The license key warning was firing twice:
1. Package install script (source/script.php) - has direct "Enter Key" button
2. System plugin (onAfterRoute) - every admin session, less actionable

Removed #2 entirely. The install script version is better UX (button links
directly to update site edit page) and only fires during install/update.
Also eliminates the uninstall bug where the warning fired during removal.
2026-06-23 11:59:56 -05:00
gitea-actions[bot] 166a6366f8 chore(version): pre-release bump to 01.05.01-dev [skip ci]
Publish to Composer / Publish Package (release) Failing after 33s
2026-06-23 16:45:37 +00:00
Jonathan Miller ac8a64c4c1 fix: license key warning no longer shows during uninstall
Universal: Auto Version Bump / Version Bump (push) Successful in 12s
Universal: Pre-Release / Build Pre-Release (${{ inputs.stability || github.ref_name }}) (push) Successful in 12s
Check if com_mokosuitecross is still in #__extensions before warning
about missing license key. Prevents the warning from firing during
package uninstall when the update site row is already deleted.
2026-06-23 11:45:05 -05:00
Jonathan Miller 2ee8a5e286 chore: remove wiki/ folder -- content migrated to Gitea wiki feature 2026-06-23 11:45:04 -05:00
jmiller 9d2620faea chore: sync issue-branch.yml from Template-Joomla [skip ci] 2026-06-23 16:23:09 +00:00
61 changed files with 54 additions and 961 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
<display-name>Package - MokoSuiteCross</display-name>
<org>MokoConsulting</org>
<description>Cross-posting Joomla content to social media, email marketing, and chat platforms</description>
<version>01.05.00</version>
<version>01.06.00</version>
<license spdx="GPL-3.0-or-later">GNU General Public License v3</license>
</identity>
<governance>
+1 -1
View File
@@ -5,7 +5,7 @@
# FILE INFORMATION
# DEFGROUP: Gitea.Workflow
# INGROUP: mokocli.Automation
# VERSION: 01.05.00
# VERSION: 01.06.00
# BRIEF: Auto-create feature branch when an issue is opened
name: "Universal: Issue Branch"
+5 -16
View File
@@ -1,6 +1,10 @@
# Changelog
## [Unreleased]
## [01.06.00] --- 2026-06-23
## [01.06.00] --- 2026-06-23
## [01.05.00] --- 2026-06-23
## [01.05.00] --- 2026-06-23
@@ -35,24 +39,9 @@
- **Medium**: Fixed getUserId() returning array instead of string on error
- **Bluesky**: Replaced md5() with hash('sha256', ...) for cache key
- **ServiceController**: Exception details no longer exposed to client
- **License warning**: Removed duplicate from system plugin -- install script already shows it with direct edit link
## [01.04.01] --- 2026-06-21
## [01.04.01] --- 2026-06-21
## [01.04.00] --- 2026-06-21
### Fixed
- **Package manifest**: Added missing `plg_system_mokosuitecross_events` and `plg_system_mokosuitecross_gallery` to `pkg_mokosuitecross.xml` — these system plugins were not installed with the package
- **Cleanup**: Removed old `src/` directory (pre-rename cruft with `mokojoomcross` files)
## [01.03.00] --- 2026-06-21
<!-- VERSION: 01.05.00 -->
All notable changes to MokoSuiteCross will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
+1 -1
View File
@@ -1,6 +1,6 @@
# MokoSuiteCross
<!-- VERSION: 01.05.00 -->
<!-- VERSION: 01.06.00 -->
Cross-posting Joomla content to social media, email marketing, and chat platforms for Joomla 5/6.
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="component" method="upgrade">
<name>com_mokosuitecross</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="content" method="upgrade">
<name>Content - MokoSuiteCross</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - ActivityPub (Fediverse)</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Google Blogger</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Bluesky</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Brevo (Sendinblue)</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Constant Contact</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - ConvertKit</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Dev.to</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Discord</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Facebook / Meta</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Ghost</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Google Business Profile</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Google Chat</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Hashnode</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Instagram</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-06-23</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - LinkedIn</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Mailchimp</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Mastodon</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Matrix / Element</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Medium</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - MokoSuiteCalendar Events</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - MokoSuiteGallery</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Nostr</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Ntfy Push Notifications</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Pinterest</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Reddit</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - RSS Feed</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - SendGrid</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Slack</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Microsoft Teams</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Telegram</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Threads (Meta)</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - TikTok</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Tumblr</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - X / Twitter</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Generic Webhook</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - WhatsApp Business</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - WordPress</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>MokoSuiteCross - Youtube</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-06-23</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>System - MokoSuiteCross</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -34,20 +34,10 @@ class MokoSuiteCross extends CMSPlugin implements SubscriberInterface
public static function getSubscribedEvents(): array
{
return [
'onAfterRoute' => 'onAfterRoute',
'onAfterRender' => 'onAfterRender',
];
}
public function onAfterRoute(): void
{
$app = $this->getApplication();
if ($app->isClient('administrator')) {
$this->warnMissingLicenseKey();
}
}
/**
* Process queued posts on page load (backend and/or frontend).
*
@@ -93,59 +83,6 @@ class MokoSuiteCross extends CMSPlugin implements SubscriberInterface
\Joomla\Component\MokoSuiteCross\Administrator\Helper\QueueProcessor::processQueue(5);
}
/**
* Warn administrators once per session when no license key is configured.
*
* @return void
*/
private function warnMissingLicenseKey(): void
{
$session = Factory::getSession();
if ($session->get('mokosuitecross.license_warned', false)) {
return;
}
$user = Factory::getUser();
if ($user->guest || !$user->authorise('core.manage')) {
return;
}
$session->set('mokosuitecross.license_warned', true);
try {
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select($db->quoteName('extra_query'))
->from($db->quoteName('#__update_sites'))
->where($db->quoteName('name') . ' = ' . $db->quote('MokoSuiteCross Updates'))
->setLimit(1);
$db->setQuery($query);
$extraQuery = (string) $db->loadResult();
if (!empty($extraQuery)) {
parse_str($extraQuery, $parsed);
if (!empty($parsed['dlid']) && preg_match('/^MOKO-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/', $parsed['dlid'])) {
return;
}
}
$this->getApplication()->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. '
. 'Go to <a href="index.php?option=com_installer&view=updatesites">System → Update Sites</a> '
. 'and enter your license key (<code>MOKO-XXXX-XXXX-XXXX-XXXX</code>) in the Download Key field '
. 'for the MokoSuiteCross update site.',
'warning'
);
} catch (\Throwable $e) {
// Don't break admin over a license check
}
}
/**
* Store the last page-load run timestamp.
*/
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>System - MokoSuiteCross Events</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="system" method="upgrade">
<name>System - MokoSuiteCross Gallery</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="task" method="upgrade">
<name>Task - MokoSuiteCross Queue Processor</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="webservices" method="upgrade">
<name>Web Services - MokoSuiteCross</name>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
+1 -1
View File
@@ -2,7 +2,7 @@
<extension type="package" method="upgrade">
<name>MokoSuiteCross</name>
<packagename>mokosuitecross</packagename>
<version>01.05.00</version>
<version>01.06.00</version>
<creationDate>2026-05-28</creationDate>
<author>Moko Consulting</author>
<authorEmail>hello@mokoconsulting.tech</authorEmail>
-46
View File
@@ -1,46 +0,0 @@
# MokoSuiteCross Wiki
**MokoSuiteCross** — Cross-posting Joomla content to social media, email marketing, and chat platforms.
## Quick Start
1. Install `pkg_mokosuitecross-*.zip` via Joomla Extensions → Install
2. Navigate to **Components → MokoSuiteCross → Services**
3. Add your first service (e.g., Telegram, Discord, Facebook)
4. Publish an article — it's automatically cross-posted to all active services
## Getting Started
- [Installation](getting-started/Installation)
- [Configuration](getting-started/Configuration)
## User Guide
- [Services](user-guide/Services)
- [Telegram](services/Telegram)
- [Message Templates](user-guide/Message-Templates)
- [Troubleshooting](user-guide/Troubleshooting)
## Developer
- [Developer Guide](developer/Developer-Guide)
- [Adding Custom Services](developer/Adding-Custom-Services)
- [REST API](developer/REST-API)
## Architecture
MokoSuiteCross uses a **plugin-based service architecture**. Each social platform is a separate Joomla plugin in the custom `mokosuitecross` plugin group. This means:
- Install only the platforms you need
- Third-party developers can add new platforms as plugins
- Each service plugin implements `MokoSuiteCrossServiceInterface`
- Services support both **default bot/app** mode (pre-configured by Moko) and **custom** mode (bring your own API keys)
## Database Tables
| Table | Purpose |
|-------|---------|
| `#__mokosuitecross_services` | Connected service accounts |
| `#__mokosuitecross_posts` | Cross-post queue and history |
| `#__mokosuitecross_templates` | Per-platform message templates |
| `#__mokosuitecross_logs` | Activity and error logs |
-74
View File
@@ -1,74 +0,0 @@
# Adding Custom Services
MokoSuiteCross uses a plugin-based architecture. Any developer can create a new service plugin.
## Plugin Structure
Create a Joomla plugin in the `mokosuitecross` group:
```
plg_mokosuitecross_myservice/
├── myservice.xml # Plugin manifest (group="mokosuitecross")
├── myservice.php # Legacy stub (empty)
├── src/
│ └── Extension/
│ └── MyserviceService.php # Implements MokoSuiteCrossServiceInterface
├── services/
│ └── provider.php # DI container registration
└── language/
└── en-GB/
├── plg_mokosuitecross_myservice.ini
└── plg_mokosuitecross_myservice.sys.ini
```
## Implement the Interface
Your Extension class must implement `MokoSuiteCrossServiceInterface`:
```php
namespace Joomla\Plugin\MokoSuiteCross\Myservice\Extension;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Component\MokoSuiteCross\Administrator\Service\MokoSuiteCrossServiceInterface;
use Joomla\Event\SubscriberInterface;
class MyserviceService extends CMSPlugin implements SubscriberInterface, MokoSuiteCrossServiceInterface
{
public static function getSubscribedEvents(): array
{
return ['onMokoSuiteCrossGetServices' => 'onMokoSuiteCrossGetServices'];
}
public function onMokoSuiteCrossGetServices(&$services): void
{
$services[] = $this;
}
public function getServiceType(): string { return 'myservice'; }
public function getServiceName(): string { return 'My Service'; }
public function getMaxLength(): int { return 500; }
public function supportsMedia(): bool { return true; }
public function publish(string $message, array $media, array $credentials, array $params): array
{
// Your API integration here
return ['success' => true, 'platform_post_id' => '...', 'response' => [...]];
}
public function validateCredentials(array $credentials): array
{
return ['valid' => true, 'message' => 'OK', 'account_name' => '...'];
}
}
```
## Required Methods
| Method | Returns | Purpose |
|--------|---------|---------|
| `getServiceType()` | string | Unique identifier (lowercase, no spaces) |
| `getServiceName()` | string | Display name in admin UI |
| `publish()` | array | Send content to the platform |
| `validateCredentials()` | array | Test if credentials work |
| `getMaxLength()` | int | Character limit (0 = no limit) |
| `supportsMedia()` | bool | Whether images can be attached |
-337
View File
@@ -1,337 +0,0 @@
# Developer Guide
This guide covers building new service plugins for MokoSuiteCross — from directory structure through testing.
## Plugin Directory Structure
Each service plugin lives in its own package under `source/packages/`:
```
plg_mokosuitecross_myservice/
├── myservice.xml ← Joomla manifest (type="plugin", group="mokosuitecross")
├── myservice.php ← Legacy loader stub (empty, required by Joomla)
├── services/
│ └── provider.php ← DI container: registers the Extension class
└── src/
└── Extension/
└── MyServiceService.php ← Main class: implements the interface
```
## MokoSuiteCrossServiceInterface
Every service plugin **must** implement `MokoSuiteCrossServiceInterface`. The interface defines 5 methods:
```php
namespace Joomla\Component\MokoSuiteCross\Administrator\Service;
interface MokoSuiteCrossServiceInterface
{
/**
* Unique identifier matching the service_type in service.xml.
* Must match exactly (e.g. 'mastodon', 'telegram').
*/
public function getServiceType(): string;
/**
* Human-readable display name (e.g. 'Mastodon', 'Telegram').
*/
public function getServiceName(): string;
/**
* Post content to the platform.
*
* @param string $message Rendered message text (already template-processed)
* @param array $media Array of media file paths (images)
* @param array $credentials Decrypted credential key-value pairs from the service record
* @param array $params Plugin params + service params merged
* @return array ['success' => bool, 'platform_post_id' => string, 'response' => array]
*/
public function publish(string $message, array $media, array $credentials, array $params): array;
/**
* Test whether the stored credentials are valid.
*
* @param array $credentials Decrypted credential key-value pairs
* @return array ['valid' => bool, 'message' => string, 'account_name' => string]
*/
public function validateCredentials(array $credentials): array;
/**
* Platform character limit (0 = unlimited).
*/
public function getMaxLength(): int;
/**
* Whether this service supports image/media attachments.
*/
public function supportsMedia(): bool;
}
```
## Step-by-Step: Creating a New Service Plugin
### 1. Create the manifest (`myservice.xml`)
```xml
<?xml version="1.0" encoding="UTF-8"?>
<extension type="plugin" group="mokosuitecross" method="upgrade">
<name>plg_mokosuitecross_myservice</name>
<author>Moko Consulting</author>
<version>1.0.0</version>
<description>MyService integration for MokoSuiteCross</description>
<namespace path="src">Joomla\Plugin\MokoSuiteCross\MyService</namespace>
<files>
<filename plugin="myservice">myservice.php</filename>
<folder>services</folder>
<folder>src</folder>
</files>
<!-- Optional: plugin-level params (e.g. default bot tokens) -->
<config>
<fields name="params">
<fieldset name="basic">
<field name="default_token" type="password"
label="Default Bot Token"
description="Pre-configured token for default mode" />
</fieldset>
</fields>
</config>
</extension>
```
### 2. Create the legacy stub (`myservice.php`)
```php
<?php
// Legacy stub — required by Joomla plugin loader. Intentionally empty.
```
### 3. Create the DI provider (`services/provider.php`)
```php
<?php
defined('_JEXEC') or die;
use Joomla\CMS\Extension\PluginInterface;
use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use Joomla\Event\DispatcherInterface;
use Joomla\Plugin\MokoSuiteCross\MyService\Extension\MyServiceService;
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 MyServiceService($dispatcher, (array) PluginHelper::getPlugin('mokosuitecross', 'myservice'));
$plugin->setApplication(Factory::getApplication());
return $plugin;
}
);
}
};
```
### 4. Create the Extension class
```php
<?php
namespace Joomla\Plugin\MokoSuiteCross\MyService\Extension;
defined('_JEXEC') or die;
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Component\MokoSuiteCross\Administrator\Service\MokoSuiteCrossServiceInterface;
use Joomla\Event\SubscriberInterface;
class MyServiceService extends CMSPlugin implements SubscriberInterface, MokoSuiteCrossServiceInterface
{
public static function getSubscribedEvents(): array
{
return [
'onMokoSuiteCrossGetServices' => 'onMokoSuiteCrossGetServices',
];
}
public function onMokoSuiteCrossGetServices(&$services): void
{
$services[] = $this;
}
public function getServiceType(): string
{
return 'myservice';
}
public function getServiceName(): string
{
return 'My Service';
}
public function publish(string $message, array $media, array $credentials, array $params): array
{
// Your API integration here
// $credentials contains the decrypted values from service.xml fields
// e.g. $credentials['api_key'], $credentials['webhook_url']
return [
'success' => true,
'platform_post_id' => 'abc123',
'response' => ['status' => 'ok'],
];
}
public function validateCredentials(array $credentials): array
{
// Test the credentials against the platform API
return [
'valid' => true,
'message' => 'Connected',
'account_name' => 'MyAccount',
];
}
public function getMaxLength(): int
{
return 0; // 0 = no limit
}
public function supportsMedia(): bool
{
return false;
}
}
```
### 5. Add credential fields to `service.xml`
In `source/packages/com_mokosuitecross/forms/service.xml`, add your fields with `showon`:
```xml
<!-- ======== MY SERVICE ======== -->
<field
name="cred_myservice_api_key"
type="password"
label="COM_MOKOSUITECROSS_CRED_MYSERVICE_KEY"
showon="service_type:myservice"
size="60"
/>
```
### 6. Add language strings to `com_mokosuitecross.ini`
```ini
COM_MOKOSUITECROSS_CRED_MYSERVICE_KEY="API Key"
```
### 7. Add to the service_type dropdown (if not already listed)
In the `<field name="service_type">` list in `service.xml`, add:
```xml
<option value="myservice">My Service</option>
```
## How `showon` Credential Fields Work
Joomla's `showon` attribute controls field visibility client-side via JavaScript:
| Pattern | Meaning |
|---------|---------|
| `showon="service_type:telegram"` | Show when service type is Telegram |
| `showon="service_type:telegram[AND]cred_mode:custom"` | Show when Telegram AND custom mode |
| `showon="service_type:webhook[AND]cred_webhook_auth_type:bearer,basic"` | Show when webhook AND auth is bearer or basic |
Fields are hidden/shown without page reloads. The form data for hidden fields is still submitted but ignored by the component.
## Dispatch Pipeline
The cross-posting flow works like this:
1. **Article published** → System plugin (`plg_system_mokosuitecross`) catches `onContentAfterSave`
2. **Queue creation** → For each enabled service, a `#__mokosuitecross_posts` row is created with status `queued`
3. **Queue processing** → Either the Scheduled Task or page-load fallback picks up queued posts
4. **Service dispatch**`QueueProcessor` fires `onMokoSuiteCrossGetServices` event in the `mokosuitecross` plugin group
5. **Plugin response** → Each registered service plugin adds itself to the `$services` array
6. **Matching** → The processor finds the plugin whose `getServiceType()` matches the service record's `service_type`
7. **Publishing**`publish()` is called with the rendered message, media paths, decrypted credentials, and params
8. **Result** → The post record is updated with `posted`/`failed` status and the platform response
## Default Bot Mode
Some services (Telegram, Discord, Slack, Teams, Facebook, Threads) support a **default mode** where pre-configured MokoSuite credentials are used. This is controlled by:
1. The `cred_mode` field in `service.xml` (shown for services listed in its `showon`)
2. Plugin-level params in the plugin manifest (`<config>` section) that store default tokens
3. The service plugin's `publish()` method checks `$credentials['mode']`:
- `'default'` → use plugin params (`$this->params->get('default_token')`)
- `'custom'` → use the per-service credentials from `$credentials`
## OAuth Integration
For services requiring OAuth (Facebook, LinkedIn, Twitter, Pinterest, etc.):
1. **OAuthHelper** (`source/packages/com_mokosuitecross/src/Helper/OAuthHelper.php`) handles:
- Authorization URL generation with state parameter
- Code-to-token exchange
- Token storage back to the service record's credentials
2. **OauthController** provides two endpoints:
- `task=oauth.authorize` → redirects to the platform's auth page
- `task=oauth.callback` → handles the redirect, exchanges code for token
3. Plugin params store the OAuth Client ID and Secret (set in Extensions → Plugins)
4. In `edit.php`, services listed in `$oauthServices` get a "Connect to {Service}" button
## Testing Your Plugin
1. **Syntax check**: `php -l source/packages/plg_mokosuitecross_myservice/src/Extension/MyServiceService.php`
2. **Install**: Include the plugin in `pkg_mokosuitecross.xml` or install the plugin ZIP standalone
3. **Enable**: Extensions → Plugins → search "mokosuitecross myservice" → Enable
4. **Add service**: Components → MokoSuiteCross → Services → New → select your service type
5. **Verify fields**: Confirm your credential fields appear when your service type is selected
6. **Test post**: Publish an article and check the Post Queue for results
## Example: Building a "Fediverse" Service
Imagine building a service for a Mastodon-compatible platform:
```php
public function publish(string $message, array $media, array $credentials, array $params): array
{
$instanceUrl = rtrim($credentials['instance_url'] ?? '', '/');
$token = $credentials['access_token'] ?? '';
$ch = curl_init($instanceUrl . '/api/v1/statuses');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['status' => $message]),
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'Authorization: Bearer ' . $token,
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true) ?: [];
if ($httpCode === 200 && !empty($data['id'])) {
return ['success' => true, 'platform_post_id' => $data['id'], 'response' => $data];
}
return ['success' => false, 'platform_post_id' => '', 'response' => $data];
}
```
This pattern — curl to API, check response code, return structured result — is the same for every service plugin. The only differences are the API endpoint, authentication method, and payload format.
-57
View File
@@ -1,57 +0,0 @@
# REST API
MokoSuiteCross includes a WebServices plugin that provides REST API endpoints via Joomla's API application.
## Authentication
All endpoints require a Joomla API token. Generate one in **Users → Manage → [User] → API Tokens**.
Include the token in the `Authorization` header:
```
Authorization: Bearer YOUR_API_TOKEN
```
## Base URL
```
https://yoursite.com/api/index.php/v1/mokosuitecross/
```
## Endpoints
### Posts
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/v1/mokosuitecross/posts` | List all cross-posts |
| GET | `/v1/mokosuitecross/posts/:id` | Get single post details |
| POST | `/v1/mokosuitecross/posts` | Create a cross-post entry |
| DELETE | `/v1/mokosuitecross/posts/:id` | Delete a post |
### Services
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/v1/mokosuitecross/services` | List connected services |
| GET | `/v1/mokosuitecross/services/:id` | Get service details |
## Example
```bash
# List all posts
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://yoursite.com/api/index.php/v1/mokosuitecross/posts
# List services
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://yoursite.com/api/index.php/v1/mokosuitecross/services
```
## Filtering
Posts support query parameters:
- `filter[status]=posted` — Filter by status (queued, posting, posted, failed, scheduled)
- `filter[service_id]=5` — Filter by service
- `page[limit]=20` — Pagination limit
- `page[offset]=0` — Pagination offset
-39
View File
@@ -1,39 +0,0 @@
# Configuration
Navigate to **Components → MokoSuiteCross** to access the admin panel.
## Global Settings
Go to **Options** (toolbar gear icon) to configure:
| Setting | Default | Description |
|---------|---------|-------------|
| Auto-post on Publish | Yes | Automatically cross-post when articles are published |
| Max Retries | 3 | How many times to retry a failed post |
| Retry Delay | 300s | Seconds between retry attempts |
| Log Retention | 90 days | How long to keep activity logs |
| Default Template | `{title}\n\n{introtext}\n\n{url}` | Fallback message template |
## Message Templates
Templates use placeholders that are replaced with article data:
| Placeholder | Description |
|-------------|-------------|
| `{title}` | Article title |
| `{url}` | Full article URL |
| `{introtext}` | Article intro text (stripped of HTML, max 280 chars) |
| `{image}` | Article intro image URL |
| `{category}` | Article category name |
| `{author}` | Article author name |
You can create per-platform templates. The system checks for a platform-specific template first, then falls back to the default.
## Service Modes
Services that support universal bots offer two modes:
- **Default Mode** — Uses the pre-configured MokoSuite bot/app. API keys are stored in the component's encrypted global params and never exposed in the individual service record.
- **Custom Mode** — You provide your own API keys, tokens, and credentials.
Services supporting default mode: **Telegram** (@mokosuite_bot), **Facebook**, **Discord**, **Slack**
-33
View File
@@ -1,33 +0,0 @@
# Installation
## Requirements
- Joomla 5.x or 6.x
- PHP 8.1+
- cURL extension enabled
## Install
1. Download the latest `pkg_mokosuitecross-*.zip` from [Releases](https://git.mokoconsulting.tech/MokoConsulting/MokoSuiteCross/releases)
2. In Joomla Administrator → **Extensions → Install → Upload Package File**
3. Upload and install the package
The installer automatically:
- Enables the system plugin (triggers cross-posting on article publish)
- Enables the content plugin (shows cross-post status badges in admin)
- Enables the webservices plugin (REST API)
- Enables all service plugins in the `mokosuitecross` group
## Migrating from Perfect Publisher Pro
If Perfect Publisher Pro is installed, MokoSuiteCross detects it and offers one-click migration:
1. Install MokoSuiteCross (PP Pro can remain installed)
2. Navigate to **Components → MokoSuiteCross → Dashboard**
3. Click **"Migrate from Perfect Publisher Pro"**
4. Review detected services and confirm import
5. Imported services are created in **disabled** state — verify credentials before enabling
## Uninstall
Uninstalling the package removes all MokoSuiteCross database tables and data. Export any needed data before uninstalling.
-62
View File
@@ -1,62 +0,0 @@
# Telegram Service
Cross-post Joomla articles to Telegram channels, groups, or users.
## Setup
### Default Bot (@mokosuite_bot)
1. Add MokoSuiteCross service with type **Telegram**
2. Set mode to **Default**
3. Enter your **Chat ID** (channel, group, or user)
4. Add @mokosuite_bot to your channel/group as admin
The default bot token is embedded in the plugin and hidden from the admin UI. No API key configuration is needed.
### Custom Bot
1. Create a bot via [@BotFather](https://t.me/BotFather)
2. Add MokoSuiteCross service with type **Telegram**
3. Set mode to **Custom**
4. Enter your Bot Token and Chat ID
5. Add your bot to the target channel/group as admin
## Credentials Format
```json
{
"mode": "default",
"chat_id": "-100xxxxxxxxxx"
}
```
Or for custom bot:
```json
{
"mode": "custom",
"bot_token": "123456:ABC-DEF...",
"chat_id": "-100xxxxxxxxxx"
}
```
## Finding Your Chat ID
- **Channel**: Forward a message from your channel to @userinfobot
- **Group**: Add @userinfobot to the group temporarily
- **User**: Send a message to @userinfobot
Channel IDs typically start with `-100`.
## Plugin Settings
Configure defaults in **Extensions → Plugins → MokoSuiteCross - Telegram**:
| Setting | Default | Description |
|---------|---------|-------------|
| Message Format | HTML | Parse mode (HTML, Markdown, MarkdownV2) |
| Disable Link Preview | No | Disable automatic link preview |
## Character Limit
Telegram supports up to **4,096 characters** per message.
-77
View File
@@ -1,77 +0,0 @@
# Message Templates
MokoSuiteCross uses message templates to format the content sent to each platform. Templates support placeholders that are replaced with article data at post time.
## Managing Templates
Navigate to **Components → MokoSuiteCross → Templates** to create and edit templates.
## Template Priority
When cross-posting, the system looks for templates in this order:
1. **Platform-specific template** — matches the service type exactly (e.g., "twitter")
2. **Default template** — fallback used when no platform-specific template exists
## Available Placeholders
| Placeholder | Description | Example |
|-------------|-------------|---------|
| `{title}` | Article title | "New Product Launch" |
| `{url}` | Full article URL | "https://example.com/article/123" |
| `{introtext}` | Intro text (280 chars, HTML stripped) | "We're excited to announce..." |
| `{fulltext}` | Full text (500 chars, HTML stripped) | Extended content |
| `{image}` | Intro image full URL | "https://example.com/images/photo.jpg" |
| `{category}` | Article category name | "News" |
| `{author}` | Author display name | "John Smith" |
| `{date}` | Publish date (YYYY-MM-DD) | "2026-05-28" |
## Example Templates
### Default (all platforms)
```
{title}
{introtext}
{url}
```
### Twitter / X (280 char limit)
```
{title}
{url}
```
### Mastodon (with hashtags)
```
{title}
{introtext}
{url}
#Joomla #{category}
```
### Mailchimp (HTML email)
```html
<h1>{title}</h1>
<p>{introtext}</p>
<p><a href="{url}">Read the full article</a></p>
```
### Telegram (HTML format)
```html
<b>{title}</b>
{introtext}
<a href="{url}">Read more</a>
```
## Per-Article Override
In the article editor, the **Cross-Posting** tab lets you:
- Skip cross-posting entirely for a specific article
- Select which services to post to (instead of all enabled services)
-60
View File
@@ -1,60 +0,0 @@
# Services
MokoSuiteCross supports 9 platforms. Each is a separate plugin that can be enabled or disabled independently.
## Social Media
| Platform | Plugin | Character Limit | Media | Default Bot |
|----------|--------|----------------|-------|-------------|
| **Facebook** | plg_mokosuitecross_facebook | No limit | Yes | Yes |
| **X / Twitter** | plg_mokosuitecross_twitter | 280 | Yes | No |
| **LinkedIn** | plg_mokosuitecross_linkedin | 3,000 | Yes | No |
| **Mastodon** | plg_mokosuitecross_mastodon | 500 | Yes | No |
| **Bluesky** | plg_mokosuitecross_bluesky | 300 | Yes | No |
## Email Marketing
| Platform | Plugin | Character Limit | Media | Default Bot |
|----------|--------|----------------|-------|-------------|
| **Mailchimp** | plg_mokosuitecross_mailchimp | No limit | Yes | No |
## Chat / Messaging
| Platform | Plugin | Character Limit | Media | Default Bot |
|----------|--------|----------------|-------|-------------|
| **Telegram** | plg_mokosuitecross_telegram | 4,096 | Yes | Yes (@mokosuite_bot) |
| **Discord** | plg_mokosuitecross_discord | 2,000 | Yes | Yes (webhook) |
| **Slack** | plg_mokosuitecross_slack | 40,000 | Yes | Yes (webhook) |
## Default vs Custom Mode
Services with "Default Bot" support offer two operating modes:
- **Default Mode**: Uses a pre-configured bot/app token managed by Moko. The admin only needs to provide a destination (chat ID, page ID, etc.). The API key is stored in the plugin's configuration and never visible in the service record.
- **Custom Mode**: The admin provides their own API keys, tokens, or webhook URLs. Full control, but requires setting up your own app/bot on the platform.
Configure default tokens in **Extensions → Plugins → MokoSuiteCross - [Platform]**.
## Adding a Service
1. Go to **Components → MokoSuiteCross → Services**
2. Click **New**
3. Select the service type
4. Enter a title and choose credentials mode
5. For **Default mode**: enter only the destination (chat ID, channel, etc.)
6. For **Custom mode**: enter your full API credentials as JSON
7. Save and enable
## Credentials Format
Each service expects specific JSON fields. See the individual service pages:
- [[Telegram]] — bot_token, chat_id
- [[Facebook]] — page_access_token, page_id
- [[Discord]] — webhook_url
- [[Slack]] — webhook_url
- [[LinkedIn]] — access_token, organization_id
- [[Mastodon]] — instance_url, access_token
- [[Bluesky]] — handle, app_password
- [[Mailchimp]] — api_key, list_id
- [[Twitter (X)]] — bearer_token, api_key, api_secret
-48
View File
@@ -1,48 +0,0 @@
# Troubleshooting
## Posts Stuck in "Queued" Status
**Cause**: The queue processor isn't running.
**Fix**:
1. Check **Components → MokoSuiteCross → Options → Queue Processing** — ensure it's set to "Scheduler" or "Both"
2. If using Scheduler: verify a task exists in **System → Scheduled Tasks** of type "MokoSuiteCross - Process Queue"
3. If using Page-load: ensure the system plugin is enabled and check the throttle interval
## Posts Failing
**Cause**: Invalid credentials or platform API changes.
**Fix**:
1. Check the error message in **Components → MokoSuiteCross → Post Queue** (hover over the red "Failed" badge)
2. Check **Activity Logs** for detailed error messages
3. Go to **Services** and verify credentials
4. For services using Default mode, check the plugin params in **Extensions → Plugins**
## "No service plugin found" Warning
**Cause**: The service plugin for that platform is disabled.
**Fix**: Go to **Extensions → Plugins**, search for "MokoSuiteCross", and enable the relevant service plugin.
## Cross-posting Not Triggering on Publish
**Cause**: Auto-post is disabled or system plugin is inactive.
**Fix**:
1. Check **Components → MokoSuiteCross → Options** — "Auto-post on Publish" should be "Yes"
2. Verify **Extensions → Plugins → System - MokoSuiteCross** is enabled
3. Check that at least one service is configured and enabled
## Duplicate Posts
MokoSuiteCross has a built-in duplicate guard. If you're seeing duplicates:
1. Check if the article was saved multiple times in quick succession
2. Check if both page-load and scheduler are running (shouldn't cause duplicates, but verify)
3. Review the **Activity Logs** for the article in question
## OAuth Connection Failing
1. Verify the OAuth Client ID and Secret are correct in the plugin params
2. Check that the redirect URI matches: `https://yoursite.com/administrator/index.php?option=com_mokosuitecross&task=oauth.callback`
3. Ensure your Joomla site uses HTTPS (required by most OAuth providers)