Standardize manifest.xml identity block: ensure <name> contains only
the machine identifier (PascalCase) and <display-name> contains the
human-readable label with Joomla extension type prefix. Remove duplicate
<version> tags where present. Update CONTRIBUTING.md from moko-platform
default.
Authored-by: Moko Consulting
C-1: CSRF nonce on OAuth authorize/callback flow
C-2: POST method enforcement on REST dispatch endpoint
C-5: Service credential fields now saved from form to JSON column
(collect cred_* fields, strip prefix, JSON encode on save;
expand back on load for editing)
H-1: Joomla 5 event ArrayAccess pattern for service plugin collection
(reads from Event indices instead of broken by-reference)
H-4: ServiceTable::check() with alias generation, required validation
H-9: WebhookService credential keys match form XML field names,
Bearer/Basic auth headers implemented correctly
M-4: XSS fix — escape $extraClass in ServiceIconHelper::renderIcon()
M-5: Article history HTML injection via setFieldAttribute() instead
of double-escaped XML description attribute
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Category routing rules — new DB table #__mokojoomcross_category_rules
maps Joomla categories to specific services (whitelist). Integrated
into CrossPostDispatcher before per-article filters.
2. Character counter — live JS counter in template editor shows
remaining chars per platform with color coding (green/yellow/red)
3. Service type icons — ServiceIconHelper maps 34 types to Bootstrap
icons, used in services list, posts list, and dashboard
4. Per-service analytics drill-down — ServiceStats view with stats
cards, daily trend chart, recent posts, top articles. Dashboard
service rows are now clickable links.
5. Article editor cross-post history — read-only panel in the
Cross-Posting fieldset showing last 10 post results with status
badges, service names, and timestamps
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add media capability reporting to MokoJoomCrossServiceInterface.
Each plugin now returns its supported media types:
- image, video, gif, document (per platform capability)
- Empty array for text-only services (Nostr, Ntfy, ConvertKit)
Enables the dispatcher to skip media attachments for text-only
services and choose appropriate media types per platform.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract dispatch logic from monolithic system plugin into a shared
CrossPostDispatcher helper. Each content type now has its own plugin:
- plg_content_mokojoomcross — articles (onContentAfterSave/ChangeState)
- plg_system_mokojoomcross_events — MokoJoomCalendar events
- plg_system_mokojoomcross_gallery — MokoJoomGallery galleries/images
- plg_mokojoomcross_mokojoomcalendar — calendar service enrichment
- plg_mokojoomcross_mokojoomgallery — gallery service enrichment
System plugin stripped to page-load queue processing only.
Also fixes: onContentBeforeDisplay Joomla 5/6 BeforeDisplayEvent
compatibility (was crashing with wrong argument type).
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Complete the Post CRUD that was previously stub-only:
- PostModel (AdminModel) for loading/saving individual posts
- Post HtmlView with toolbar (apply, save, cancel, dashboard)
- post.xml form with article selector, service selector, message
textarea, status dropdown, and scheduled_at calendar picker
- Post edit template with results sidebar and re-queue button
- Posts list: New button in toolbar, clickable article titles,
scheduled_at display with clock icon
- 20 new language strings for the post edit UI
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Articles can be marked as "evergreen" in the Cross-Posting fieldset,
with a configurable re-share interval (default 30 days). The queue
processor checks for due articles and re-queues them automatically,
bypassing the duplicate guard for articles whose last successful post
exceeds the interval.
- Per-article: evergreen toggle + interval (days) in article editor
- Global config: enable/disable, default interval, max per run
- QueueProcessor::processEvergreen() finds and re-queues due articles
- Task plugin calls processEvergreen() before processQueue()
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Service edit sidebar now shows a contextual "Setup Guide" button when
a service type is selected. Links to the matching KB article on the
live site (e.g., /kb/mokojoomcross/service-twitter-mokojoomcross).
All 34 service types mapped.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 13 plugins had copy-paste stub code with literal placeholder URLs
(e.g. '{site_url}/api/endpoint') that were never substituted with
actual credential values. Each plugin now has correct:
- URL construction from credentials
- Auth method (Basic Auth for WP, JWT for Ghost, GraphQL for Hashnode)
- API payload format per platform spec
- Credential validation with live API checks
Fixed: ActivityPub, Blogger, Ghost, Google Business, Hashnode, Matrix,
Medium, Nostr (stub), RSS Feed, Threads, Tumblr, WhatsApp, WordPress.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Dashboard link buttons in Logs, Posts, Services, Template, and
Templates views used Toolbar::getInstance() and Route::_ without
importing the classes — causing fatal errors on page load.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix Twitter posting by replacing Bearer token (app-only, read-only)
with OAuth 1.0a HMAC-SHA1 signing using all 4 keys. Add credential
fields for 19 previously missing services and optional fields for
7 existing services. Add Developer Guide wiki page.
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>