From d951d86b3aa5e433399dd400ba8d3f1db99eecd2 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sun, 28 Jun 2026 11:43:09 -0500 Subject: [PATCH 1/2] feat: add social image generator with PHP GD for OG images (#157) - SocialImageHelper: generates 1200x630 OG images with title overlay - SocialImageController: AJAX endpoint to generate from article data - Config fields: bg color, text color, overlay style, site name override - Supports background image scaling, dark/light overlay, TTF fonts Closes #157 Authored-by: Moko Consulting --- CHANGELOG.md | 2 + source/packages/com_mokosuitecross/config.xml | 34 +++ .../language/en-GB/com_mokosuitecross.ini | 14 ++ .../src/Controller/SocialImageController.php | 98 ++++++++ .../src/Helper/SocialImageHelper.php | 230 ++++++++++++++++++ 5 files changed, 378 insertions(+) create mode 100644 source/packages/com_mokosuitecross/src/Controller/SocialImageController.php create mode 100644 source/packages/com_mokosuitecross/src/Helper/SocialImageHelper.php diff --git a/CHANGELOG.md b/CHANGELOG.md index c2e982e7..29119572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] ### Added +- **Social image generator**: Generate Open Graph images with article title overlay using PHP GD library (#157) +- **Social image config**: Background color, text color, overlay style, and site name override in component options (#157) - **AI caption generation**: Generate platform-optimized cross-post captions from article content using Claude or OpenAI (#161) - **AI provider config**: New "AI Caption Generation" fieldset in component options with provider, API key, model, and tone settings - **AI Generate button**: One-click AI generation button in the Share Content panel that fills all caption fields diff --git a/source/packages/com_mokosuitecross/config.xml b/source/packages/com_mokosuitecross/config.xml index 2df31bfe..75415a0d 100644 --- a/source/packages/com_mokosuitecross/config.xml +++ b/source/packages/com_mokosuitecross/config.xml @@ -266,6 +266,40 @@ +
+ + + + + + + + +
+
+ * @copyright Copyright (C) 2026 Moko Consulting. All rights reserved. + * @license GNU General Public License version 3 or later; see LICENSE + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +namespace Joomla\Component\MokoSuiteCross\Administrator\Controller; + +defined('_JEXEC') or die; + +use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Factory; +use Joomla\CMS\MVC\Controller\BaseController; +use Joomla\CMS\Session\Session; +use Joomla\CMS\Uri\Uri; +use Joomla\Component\MokoSuiteCross\Administrator\Helper\SocialImageHelper; + +class SocialImageController extends BaseController +{ + public function generate(): void + { + if (!Session::checkToken('get')) { + echo json_encode(['success' => false, 'error' => 'Invalid token']); + $this->app->close(); + + return; + } + + $user = $this->app->getIdentity(); + + if (!$user->authorise('core.manage', 'com_mokosuitecross')) { + echo json_encode(['success' => false, 'error' => 'Permission denied']); + $this->app->close(); + + return; + } + + $articleId = $this->input->getInt('article_id', 0); + + if ($articleId < 1) { + echo json_encode(['success' => false, 'error' => 'Missing article ID']); + $this->app->close(); + + return; + } + + $db = Factory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName(['id', 'title', 'images'])) + ->from($db->quoteName('#__content')) + ->where($db->quoteName('id') . ' = ' . $articleId); + $db->setQuery($query); + $article = $db->loadObject(); + + if (!$article) { + echo json_encode(['success' => false, 'error' => 'Article not found']); + $this->app->close(); + + return; + } + + $params = ComponentHelper::getParams('com_mokosuitecross'); + $siteName = $params->get('social_image_site_name', '') ?: Factory::getApplication()->get('sitename', ''); + + $options = [ + 'bg_color' => $params->get('social_image_bg_color', '#1a1a2e'), + 'text_color' => $params->get('social_image_text_color', '#ffffff'), + 'overlay' => $params->get('social_image_overlay', 'dark'), + ]; + + $backgroundPath = null; + $images = json_decode($article->images ?? '{}', true); + + if (!empty($images['image_intro'])) { + $backgroundPath = JPATH_ROOT . '/' . ltrim($images['image_intro'], '/'); + } elseif (!empty($images['image_fulltext'])) { + $backgroundPath = JPATH_ROOT . '/' . ltrim($images['image_fulltext'], '/'); + } + + try { + $imagePath = SocialImageHelper::generate($article->title, $siteName, $backgroundPath, $options); + $imageUrl = str_replace(JPATH_ROOT, Uri::root(true), str_replace('\\', '/', $imagePath)); + + $result = ['success' => true, 'image_url' => $imageUrl, 'image_path' => $imagePath]; + } catch (\Throwable $e) { + $result = ['success' => false, 'error' => $e->getMessage()]; + } + + $this->app->setHeader('Content-Type', 'application/json; charset=utf-8'); + echo json_encode($result); + $this->app->close(); + } +} diff --git a/source/packages/com_mokosuitecross/src/Helper/SocialImageHelper.php b/source/packages/com_mokosuitecross/src/Helper/SocialImageHelper.php new file mode 100644 index 00000000..0f7e4831 --- /dev/null +++ b/source/packages/com_mokosuitecross/src/Helper/SocialImageHelper.php @@ -0,0 +1,230 @@ + + * @copyright Copyright (C) 2026 Moko Consulting. All rights reserved. + * @license GNU General Public License version 3 or later; see LICENSE + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +namespace Joomla\Component\MokoSuiteCross\Administrator\Helper; + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; + +class SocialImageHelper +{ + private const WIDTH = 1200; + private const HEIGHT = 630; + private const PADDING = 60; + private const MAX_TITLE_CHARS_PER_LINE = 30; + + public static function generate(string $title, string $siteName, ?string $backgroundPath = null, array $options = []): string + { + if (!\function_exists('imagecreatetruecolor')) { + throw new \RuntimeException('PHP GD extension is required for social image generation.'); + } + + $bgColor = $options['bg_color'] ?? '#1a1a2e'; + $textColor = $options['text_color'] ?? '#ffffff'; + $overlayType = $options['overlay'] ?? 'dark'; + $fontSize = (int) ($options['font_size'] ?? 36); + + $image = imagecreatetruecolor(self::WIDTH, self::HEIGHT); + + if ($image === false) { + throw new \RuntimeException('Failed to create image canvas.'); + } + + $bgRgb = self::hexToRgb($bgColor); + $bg = imagecolorallocate($image, $bgRgb[0], $bgRgb[1], $bgRgb[2]); + imagefill($image, 0, 0, $bg); + + if ($backgroundPath !== null && is_file($backgroundPath)) { + self::drawBackground($image, $backgroundPath); + } + + if ($overlayType !== 'none') { + self::drawOverlay($image, $overlayType); + } + + $textRgb = self::hexToRgb($textColor); + $textCol = imagecolorallocate($image, $textRgb[0], $textRgb[1], $textRgb[2]); + + $fontPath = self::findFont(); + + if ($fontPath !== null) { + self::drawTextTtf($image, $title, $siteName, $fontPath, $fontSize, $textCol); + } else { + self::drawTextFallback($image, $title, $siteName, $textCol); + } + + $tmpDir = Factory::getApplication()->get('tmp_path', JPATH_ROOT . '/tmp'); + $outPath = $tmpDir . '/social_' . md5($title . $siteName . microtime()) . '.png'; + + imagepng($image, $outPath, 6); + imagedestroy($image); + + return $outPath; + } + + private static function drawBackground(\GdImage $image, string $path): void + { + $info = @getimagesize($path); + + if ($info === false) { + return; + } + + $source = match ($info[2]) { + IMAGETYPE_JPEG => @imagecreatefromjpeg($path), + IMAGETYPE_PNG => @imagecreatefrompng($path), + IMAGETYPE_WEBP => \function_exists('imagecreatefromwebp') ? @imagecreatefromwebp($path) : false, + default => false, + }; + + if ($source === false) { + return; + } + + $srcW = imagesx($source); + $srcH = imagesy($source); + + $scale = max(self::WIDTH / $srcW, self::HEIGHT / $srcH); + $newW = (int) ($srcW * $scale); + $newH = (int) ($srcH * $scale); + $dstX = (int) ((self::WIDTH - $newW) / 2); + $dstY = (int) ((self::HEIGHT - $newH) / 2); + + imagecopyresampled($image, $source, $dstX, $dstY, 0, 0, $newW, $newH, $srcW, $srcH); + imagedestroy($source); + } + + private static function drawOverlay(\GdImage $image, string $type): void + { + $opacity = ($type === 'light') ? 80 : 160; + $color = imagecolorallocatealpha($image, 0, 0, 0, 127 - (int) ($opacity * 127 / 255)); + + if ($color === false) { + return; + } + + imagesavealpha($image, true); + imagefilledrectangle($image, 0, 0, self::WIDTH - 1, self::HEIGHT - 1, $color); + } + + private static function drawTextTtf(\GdImage $image, string $title, string $siteName, string $fontPath, int $fontSize, int $color): void + { + $lines = self::wordWrap($title, $fontPath, $fontSize, self::WIDTH - self::PADDING * 2); + $lineH = (int) ($fontSize * 1.4); + $totalH = \count($lines) * $lineH; + $startY = (int) ((self::HEIGHT - $totalH) / 2) + $fontSize; + + foreach ($lines as $i => $line) { + $box = imagettfbbox($fontSize, 0, $fontPath, $line); + $lineW = abs($box[2] - $box[0]); + $x = (int) ((self::WIDTH - $lineW) / 2); + imagettftext($image, $fontSize, 0, $x, $startY + $i * $lineH, $color, $fontPath, $line); + } + + $siteSize = (int) ($fontSize * 0.5); + $box = imagettfbbox($siteSize, 0, $fontPath, $siteName); + $siteW = abs($box[2] - $box[0]); + $siteX = (int) ((self::WIDTH - $siteW) / 2); + $siteY = self::HEIGHT - self::PADDING; + + $siteCol = imagecolorallocatealpha($image, 255, 255, 255, 40); + + if ($siteCol !== false) { + imagettftext($image, $siteSize, 0, $siteX, $siteY, $siteCol, $fontPath, $siteName); + } + } + + private static function drawTextFallback(\GdImage $image, string $title, string $siteName, int $color): void + { + $maxChars = (int) (self::WIDTH / 10); + $wrapped = wordwrap($title, $maxChars, "\n", true); + $lines = explode("\n", $wrapped); + $lineH = 20; + $totalH = \count($lines) * $lineH; + $startY = (int) ((self::HEIGHT - $totalH) / 2); + + foreach ($lines as $i => $line) { + $lineW = \strlen($line) * 9; + $x = max(self::PADDING, (int) ((self::WIDTH - $lineW) / 2)); + imagestring($image, 5, $x, $startY + $i * $lineH, $line, $color); + } + + $siteW = \strlen($siteName) * 7; + $siteX = max(self::PADDING, (int) ((self::WIDTH - $siteW) / 2)); + $siteY = self::HEIGHT - 40; + + $gray = imagecolorallocate($image, 180, 180, 180); + + if ($gray !== false) { + imagestring($image, 3, $siteX, $siteY, $siteName, $gray); + } + } + + private static function wordWrap(string $text, string $fontPath, int $fontSize, int $maxWidth): array + { + $words = explode(' ', $text); + $lines = []; + $line = ''; + + foreach ($words as $word) { + $test = ($line === '') ? $word : $line . ' ' . $word; + $box = imagettfbbox($fontSize, 0, $fontPath, $test); + $testW = abs($box[2] - $box[0]); + + if ($testW > $maxWidth && $line !== '') { + $lines[] = $line; + $line = $word; + } else { + $line = $test; + } + } + + if ($line !== '') { + $lines[] = $line; + } + + return $lines ?: [$text]; + } + + private static function findFont(): ?string + { + $candidates = [ + JPATH_ROOT . '/media/com_mokosuitecross/fonts/OpenSans-Bold.ttf', + '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', + '/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf', + 'C:/Windows/Fonts/arialbd.ttf', + ]; + + foreach ($candidates as $path) { + if (is_file($path)) { + return $path; + } + } + + return null; + } + + private static function hexToRgb(string $hex): array + { + $hex = ltrim($hex, '#'); + + if (\strlen($hex) === 3) { + $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; + } + + return [ + (int) hexdec(substr($hex, 0, 2)), + (int) hexdec(substr($hex, 2, 2)), + (int) hexdec(substr($hex, 4, 2)), + ]; + } +} -- 2.52.0 From a169ea4967564e253975ee094aa578880162db75 Mon Sep 17 00:00:00 2001 From: "gitea-actions[bot]" Date: Sun, 28 Jun 2026 16:43:40 +0000 Subject: [PATCH 2/2] chore(version): auto-bump patch 01.08.52-dev [skip ci] --- .mokogitea/workflows/issue-branch.yml | 2 +- CHANGELOG.md | 2 +- CODE_OF_CONDUCT.md | 2 +- README.md | 2 +- SECURITY.md | 2 +- source/packages/com_mokosuitecross/mokosuitecross.xml | 2 +- .../packages/com_mokosuitecross/sql/updates/mysql/01.08.52.sql | 1 + source/packages/plg_content_mokosuitecross/mokosuitecross.xml | 2 +- source/packages/plg_mokosuitecross_activitypub/activitypub.xml | 2 +- source/packages/plg_mokosuitecross_blogger/blogger.xml | 2 +- source/packages/plg_mokosuitecross_bluesky/bluesky.xml | 2 +- source/packages/plg_mokosuitecross_brevo/brevo.xml | 2 +- .../plg_mokosuitecross_constantcontact/constantcontact.xml | 2 +- source/packages/plg_mokosuitecross_convertkit/convertkit.xml | 2 +- source/packages/plg_mokosuitecross_devto/devto.xml | 2 +- source/packages/plg_mokosuitecross_discord/discord.xml | 2 +- source/packages/plg_mokosuitecross_facebook/facebook.xml | 2 +- source/packages/plg_mokosuitecross_ghost/ghost.xml | 2 +- .../plg_mokosuitecross_googlebusiness/googlebusiness.xml | 2 +- source/packages/plg_mokosuitecross_googlechat/googlechat.xml | 2 +- source/packages/plg_mokosuitecross_hashnode/hashnode.xml | 2 +- source/packages/plg_mokosuitecross_instagram/instagram.xml | 2 +- source/packages/plg_mokosuitecross_linkedin/linkedin.xml | 2 +- source/packages/plg_mokosuitecross_mailchimp/mailchimp.xml | 2 +- source/packages/plg_mokosuitecross_mastodon/mastodon.xml | 2 +- source/packages/plg_mokosuitecross_matrix/matrix.xml | 2 +- source/packages/plg_mokosuitecross_medium/medium.xml | 2 +- .../plg_mokosuitecross_mokosuitecalendar/mokosuitecalendar.xml | 2 +- .../plg_mokosuitecross_mokosuitegallery/mokosuitegallery.xml | 2 +- source/packages/plg_mokosuitecross_nostr/nostr.xml | 2 +- source/packages/plg_mokosuitecross_ntfy/ntfy.xml | 2 +- source/packages/plg_mokosuitecross_pinterest/pinterest.xml | 2 +- source/packages/plg_mokosuitecross_reddit/reddit.xml | 2 +- source/packages/plg_mokosuitecross_rssfeed/rssfeed.xml | 2 +- source/packages/plg_mokosuitecross_sendgrid/sendgrid.xml | 2 +- source/packages/plg_mokosuitecross_slack/slack.xml | 2 +- source/packages/plg_mokosuitecross_teams/teams.xml | 2 +- source/packages/plg_mokosuitecross_telegram/telegram.xml | 2 +- source/packages/plg_mokosuitecross_threads/threads.xml | 2 +- source/packages/plg_mokosuitecross_tiktok/tiktok.xml | 2 +- source/packages/plg_mokosuitecross_tumblr/tumblr.xml | 2 +- source/packages/plg_mokosuitecross_twitter/twitter.xml | 2 +- source/packages/plg_mokosuitecross_webhook/webhook.xml | 2 +- source/packages/plg_mokosuitecross_whatsapp/whatsapp.xml | 2 +- source/packages/plg_mokosuitecross_wordpress/wordpress.xml | 2 +- source/packages/plg_mokosuitecross_youtube/youtube.xml | 2 +- source/packages/plg_system_mokosuitecross/mokosuitecross.xml | 2 +- .../plg_system_mokosuitecross_events/mokosuitecross_events.xml | 2 +- .../mokosuitecross_gallery.xml | 2 +- source/packages/plg_task_mokosuitecross/mokosuitecross.xml | 2 +- .../packages/plg_webservices_mokosuitecross/mokosuitecross.xml | 2 +- source/pkg_mokosuitecross.xml | 2 +- 52 files changed, 52 insertions(+), 51 deletions(-) create mode 100644 source/packages/com_mokosuitecross/sql/updates/mysql/01.08.52.sql diff --git a/.mokogitea/workflows/issue-branch.yml b/.mokogitea/workflows/issue-branch.yml index f097d228..46d5c13d 100644 --- a/.mokogitea/workflows/issue-branch.yml +++ b/.mokogitea/workflows/issue-branch.yml @@ -5,7 +5,7 @@ # FILE INFORMATION # DEFGROUP: Gitea.Workflow # INGROUP: mokocli.Automation -# VERSION: 01.08.51 +# VERSION: 01.08.52 # BRIEF: Auto-create feature branch when an issue is opened name: "Universal: Issue Branch" diff --git a/CHANGELOG.md b/CHANGELOG.md index 29119572..c789dcd0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -98,7 +98,7 @@ ## [01.03.00] --- 2026-06-21 - + All notable changes to MokoSuiteCross will be documented in this file. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 33b9816c..c4ba4175 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -14,7 +14,7 @@ DEFGROUP: Template-Joomla INGROUP: Template-Joomla.Documentation REPO: https://github.com/mokoconsulting-tech/Template-Joomla/ - VERSION: 01.08.51 + VERSION: 01.08.52 PATH: ./CODE_OF_CONDUCT.md BRIEF: Community expectations and enforcement guidelines NOTE: Adapted with attribution from the Contributor Covenant v2.1 diff --git a/README.md b/README.md index 048ccb79..704252a2 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # MokoSuiteCross - + Cross-posting Joomla content to social media, email marketing, and chat platforms for Joomla 5/6. diff --git a/SECURITY.md b/SECURITY.md index 9fc9c8d2..b521ee49 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla INGROUP: Template-Joomla.Documentation REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla PATH: /SECURITY.md -VERSION: 01.08.51 +VERSION: 01.08.52 BRIEF: Security vulnerability reporting and handling policy --> diff --git a/source/packages/com_mokosuitecross/mokosuitecross.xml b/source/packages/com_mokosuitecross/mokosuitecross.xml index 88e65050..9e3798a6 100644 --- a/source/packages/com_mokosuitecross/mokosuitecross.xml +++ b/source/packages/com_mokosuitecross/mokosuitecross.xml @@ -1,7 +1,7 @@ com_mokosuitecross - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/com_mokosuitecross/sql/updates/mysql/01.08.52.sql b/source/packages/com_mokosuitecross/sql/updates/mysql/01.08.52.sql new file mode 100644 index 00000000..059d891b --- /dev/null +++ b/source/packages/com_mokosuitecross/sql/updates/mysql/01.08.52.sql @@ -0,0 +1 @@ +/* 01.08.52 — no schema changes */ diff --git a/source/packages/plg_content_mokosuitecross/mokosuitecross.xml b/source/packages/plg_content_mokosuitecross/mokosuitecross.xml index bf076695..b51d370f 100644 --- a/source/packages/plg_content_mokosuitecross/mokosuitecross.xml +++ b/source/packages/plg_content_mokosuitecross/mokosuitecross.xml @@ -1,7 +1,7 @@ Content - MokoSuiteCross - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_activitypub/activitypub.xml b/source/packages/plg_mokosuitecross_activitypub/activitypub.xml index 47605670..41ee90ed 100644 --- a/source/packages/plg_mokosuitecross_activitypub/activitypub.xml +++ b/source/packages/plg_mokosuitecross_activitypub/activitypub.xml @@ -1,7 +1,7 @@ MokoSuiteCross - ActivityPub (Fediverse) - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_blogger/blogger.xml b/source/packages/plg_mokosuitecross_blogger/blogger.xml index c9247ae1..978ff853 100644 --- a/source/packages/plg_mokosuitecross_blogger/blogger.xml +++ b/source/packages/plg_mokosuitecross_blogger/blogger.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Google Blogger - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_bluesky/bluesky.xml b/source/packages/plg_mokosuitecross_bluesky/bluesky.xml index 5f35c932..5db12199 100644 --- a/source/packages/plg_mokosuitecross_bluesky/bluesky.xml +++ b/source/packages/plg_mokosuitecross_bluesky/bluesky.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Bluesky - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_brevo/brevo.xml b/source/packages/plg_mokosuitecross_brevo/brevo.xml index 5586029d..10b44c11 100644 --- a/source/packages/plg_mokosuitecross_brevo/brevo.xml +++ b/source/packages/plg_mokosuitecross_brevo/brevo.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Brevo (Sendinblue) - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_constantcontact/constantcontact.xml b/source/packages/plg_mokosuitecross_constantcontact/constantcontact.xml index 7c5c8212..64a6f375 100644 --- a/source/packages/plg_mokosuitecross_constantcontact/constantcontact.xml +++ b/source/packages/plg_mokosuitecross_constantcontact/constantcontact.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Constant Contact - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_convertkit/convertkit.xml b/source/packages/plg_mokosuitecross_convertkit/convertkit.xml index f0e067f9..37029349 100644 --- a/source/packages/plg_mokosuitecross_convertkit/convertkit.xml +++ b/source/packages/plg_mokosuitecross_convertkit/convertkit.xml @@ -1,7 +1,7 @@ MokoSuiteCross - ConvertKit - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_devto/devto.xml b/source/packages/plg_mokosuitecross_devto/devto.xml index be1bc42c..d1ffb830 100644 --- a/source/packages/plg_mokosuitecross_devto/devto.xml +++ b/source/packages/plg_mokosuitecross_devto/devto.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Dev.to - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_discord/discord.xml b/source/packages/plg_mokosuitecross_discord/discord.xml index 359e47e0..776e0502 100644 --- a/source/packages/plg_mokosuitecross_discord/discord.xml +++ b/source/packages/plg_mokosuitecross_discord/discord.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Discord - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_facebook/facebook.xml b/source/packages/plg_mokosuitecross_facebook/facebook.xml index 4e610f8a..652bc2e7 100644 --- a/source/packages/plg_mokosuitecross_facebook/facebook.xml +++ b/source/packages/plg_mokosuitecross_facebook/facebook.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Facebook / Meta - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_ghost/ghost.xml b/source/packages/plg_mokosuitecross_ghost/ghost.xml index 4fdee20c..6a28ea24 100644 --- a/source/packages/plg_mokosuitecross_ghost/ghost.xml +++ b/source/packages/plg_mokosuitecross_ghost/ghost.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Ghost - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_googlebusiness/googlebusiness.xml b/source/packages/plg_mokosuitecross_googlebusiness/googlebusiness.xml index 75d52138..6f6f5b78 100644 --- a/source/packages/plg_mokosuitecross_googlebusiness/googlebusiness.xml +++ b/source/packages/plg_mokosuitecross_googlebusiness/googlebusiness.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Google Business Profile - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_googlechat/googlechat.xml b/source/packages/plg_mokosuitecross_googlechat/googlechat.xml index 0f436670..f36d1976 100644 --- a/source/packages/plg_mokosuitecross_googlechat/googlechat.xml +++ b/source/packages/plg_mokosuitecross_googlechat/googlechat.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Google Chat - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_hashnode/hashnode.xml b/source/packages/plg_mokosuitecross_hashnode/hashnode.xml index a0d58dca..09f1a32f 100644 --- a/source/packages/plg_mokosuitecross_hashnode/hashnode.xml +++ b/source/packages/plg_mokosuitecross_hashnode/hashnode.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Hashnode - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_instagram/instagram.xml b/source/packages/plg_mokosuitecross_instagram/instagram.xml index 761d5cbe..6fd8c317 100644 --- a/source/packages/plg_mokosuitecross_instagram/instagram.xml +++ b/source/packages/plg_mokosuitecross_instagram/instagram.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Instagram - 01.08.51 + 01.08.52 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_linkedin/linkedin.xml b/source/packages/plg_mokosuitecross_linkedin/linkedin.xml index 6b4a652e..b7013a41 100644 --- a/source/packages/plg_mokosuitecross_linkedin/linkedin.xml +++ b/source/packages/plg_mokosuitecross_linkedin/linkedin.xml @@ -1,7 +1,7 @@ MokoSuiteCross - LinkedIn - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_mailchimp/mailchimp.xml b/source/packages/plg_mokosuitecross_mailchimp/mailchimp.xml index 0fce6f79..acb33123 100644 --- a/source/packages/plg_mokosuitecross_mailchimp/mailchimp.xml +++ b/source/packages/plg_mokosuitecross_mailchimp/mailchimp.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Mailchimp - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_mastodon/mastodon.xml b/source/packages/plg_mokosuitecross_mastodon/mastodon.xml index a019aa91..48907f28 100644 --- a/source/packages/plg_mokosuitecross_mastodon/mastodon.xml +++ b/source/packages/plg_mokosuitecross_mastodon/mastodon.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Mastodon - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_matrix/matrix.xml b/source/packages/plg_mokosuitecross_matrix/matrix.xml index 59fdf6c2..8c398caa 100644 --- a/source/packages/plg_mokosuitecross_matrix/matrix.xml +++ b/source/packages/plg_mokosuitecross_matrix/matrix.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Matrix / Element - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_medium/medium.xml b/source/packages/plg_mokosuitecross_medium/medium.xml index 6671249b..8c6890b3 100644 --- a/source/packages/plg_mokosuitecross_medium/medium.xml +++ b/source/packages/plg_mokosuitecross_medium/medium.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Medium - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_mokosuitecalendar/mokosuitecalendar.xml b/source/packages/plg_mokosuitecross_mokosuitecalendar/mokosuitecalendar.xml index 4a379ba0..9754769f 100644 --- a/source/packages/plg_mokosuitecross_mokosuitecalendar/mokosuitecalendar.xml +++ b/source/packages/plg_mokosuitecross_mokosuitecalendar/mokosuitecalendar.xml @@ -1,7 +1,7 @@ MokoSuiteCross - MokoSuiteCalendar Events - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_mokosuitegallery/mokosuitegallery.xml b/source/packages/plg_mokosuitecross_mokosuitegallery/mokosuitegallery.xml index 4052a299..f6a8fd18 100644 --- a/source/packages/plg_mokosuitecross_mokosuitegallery/mokosuitegallery.xml +++ b/source/packages/plg_mokosuitecross_mokosuitegallery/mokosuitegallery.xml @@ -1,7 +1,7 @@ MokoSuiteCross - MokoSuiteGallery - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_nostr/nostr.xml b/source/packages/plg_mokosuitecross_nostr/nostr.xml index 45ca9beb..65aae214 100644 --- a/source/packages/plg_mokosuitecross_nostr/nostr.xml +++ b/source/packages/plg_mokosuitecross_nostr/nostr.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Nostr - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_ntfy/ntfy.xml b/source/packages/plg_mokosuitecross_ntfy/ntfy.xml index 994b0575..6bad4014 100644 --- a/source/packages/plg_mokosuitecross_ntfy/ntfy.xml +++ b/source/packages/plg_mokosuitecross_ntfy/ntfy.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Ntfy Push Notifications - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_pinterest/pinterest.xml b/source/packages/plg_mokosuitecross_pinterest/pinterest.xml index 5534d2eb..50dff99f 100644 --- a/source/packages/plg_mokosuitecross_pinterest/pinterest.xml +++ b/source/packages/plg_mokosuitecross_pinterest/pinterest.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Pinterest - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_reddit/reddit.xml b/source/packages/plg_mokosuitecross_reddit/reddit.xml index 75f9fca4..34bcb61b 100644 --- a/source/packages/plg_mokosuitecross_reddit/reddit.xml +++ b/source/packages/plg_mokosuitecross_reddit/reddit.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Reddit - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_rssfeed/rssfeed.xml b/source/packages/plg_mokosuitecross_rssfeed/rssfeed.xml index 5b0e62f0..c18bf39e 100644 --- a/source/packages/plg_mokosuitecross_rssfeed/rssfeed.xml +++ b/source/packages/plg_mokosuitecross_rssfeed/rssfeed.xml @@ -1,7 +1,7 @@ MokoSuiteCross - RSS Feed - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_sendgrid/sendgrid.xml b/source/packages/plg_mokosuitecross_sendgrid/sendgrid.xml index b168cf46..33e61c1d 100644 --- a/source/packages/plg_mokosuitecross_sendgrid/sendgrid.xml +++ b/source/packages/plg_mokosuitecross_sendgrid/sendgrid.xml @@ -1,7 +1,7 @@ MokoSuiteCross - SendGrid - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_slack/slack.xml b/source/packages/plg_mokosuitecross_slack/slack.xml index 19585c95..8d78a29b 100644 --- a/source/packages/plg_mokosuitecross_slack/slack.xml +++ b/source/packages/plg_mokosuitecross_slack/slack.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Slack - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_teams/teams.xml b/source/packages/plg_mokosuitecross_teams/teams.xml index 00e22b36..a0e84c2c 100644 --- a/source/packages/plg_mokosuitecross_teams/teams.xml +++ b/source/packages/plg_mokosuitecross_teams/teams.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Microsoft Teams - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_telegram/telegram.xml b/source/packages/plg_mokosuitecross_telegram/telegram.xml index ddd4a6e8..44e615ed 100644 --- a/source/packages/plg_mokosuitecross_telegram/telegram.xml +++ b/source/packages/plg_mokosuitecross_telegram/telegram.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Telegram - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_threads/threads.xml b/source/packages/plg_mokosuitecross_threads/threads.xml index 224ac436..49bbef62 100644 --- a/source/packages/plg_mokosuitecross_threads/threads.xml +++ b/source/packages/plg_mokosuitecross_threads/threads.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Threads (Meta) - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_tiktok/tiktok.xml b/source/packages/plg_mokosuitecross_tiktok/tiktok.xml index 1a45ccde..1be3ba44 100644 --- a/source/packages/plg_mokosuitecross_tiktok/tiktok.xml +++ b/source/packages/plg_mokosuitecross_tiktok/tiktok.xml @@ -1,7 +1,7 @@ MokoSuiteCross - TikTok - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_tumblr/tumblr.xml b/source/packages/plg_mokosuitecross_tumblr/tumblr.xml index 9631ccc9..8d50878c 100644 --- a/source/packages/plg_mokosuitecross_tumblr/tumblr.xml +++ b/source/packages/plg_mokosuitecross_tumblr/tumblr.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Tumblr - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_twitter/twitter.xml b/source/packages/plg_mokosuitecross_twitter/twitter.xml index f6b25008..6debc191 100644 --- a/source/packages/plg_mokosuitecross_twitter/twitter.xml +++ b/source/packages/plg_mokosuitecross_twitter/twitter.xml @@ -1,7 +1,7 @@ MokoSuiteCross - X / Twitter - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_webhook/webhook.xml b/source/packages/plg_mokosuitecross_webhook/webhook.xml index d8d1ea5d..c8dc4c10 100644 --- a/source/packages/plg_mokosuitecross_webhook/webhook.xml +++ b/source/packages/plg_mokosuitecross_webhook/webhook.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Generic Webhook - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_whatsapp/whatsapp.xml b/source/packages/plg_mokosuitecross_whatsapp/whatsapp.xml index da197f69..2d3d2330 100644 --- a/source/packages/plg_mokosuitecross_whatsapp/whatsapp.xml +++ b/source/packages/plg_mokosuitecross_whatsapp/whatsapp.xml @@ -1,7 +1,7 @@ MokoSuiteCross - WhatsApp Business - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_wordpress/wordpress.xml b/source/packages/plg_mokosuitecross_wordpress/wordpress.xml index 075a18d8..b0663721 100644 --- a/source/packages/plg_mokosuitecross_wordpress/wordpress.xml +++ b/source/packages/plg_mokosuitecross_wordpress/wordpress.xml @@ -1,7 +1,7 @@ MokoSuiteCross - WordPress - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_mokosuitecross_youtube/youtube.xml b/source/packages/plg_mokosuitecross_youtube/youtube.xml index 370c27d3..22a39c7e 100644 --- a/source/packages/plg_mokosuitecross_youtube/youtube.xml +++ b/source/packages/plg_mokosuitecross_youtube/youtube.xml @@ -1,7 +1,7 @@ MokoSuiteCross - Youtube - 01.08.51 + 01.08.52 2026-06-23 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_system_mokosuitecross/mokosuitecross.xml b/source/packages/plg_system_mokosuitecross/mokosuitecross.xml index e5bec16d..509540bb 100644 --- a/source/packages/plg_system_mokosuitecross/mokosuitecross.xml +++ b/source/packages/plg_system_mokosuitecross/mokosuitecross.xml @@ -1,7 +1,7 @@ System - MokoSuiteCross - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_system_mokosuitecross_events/mokosuitecross_events.xml b/source/packages/plg_system_mokosuitecross_events/mokosuitecross_events.xml index 9cd47c8f..13829ca6 100644 --- a/source/packages/plg_system_mokosuitecross_events/mokosuitecross_events.xml +++ b/source/packages/plg_system_mokosuitecross_events/mokosuitecross_events.xml @@ -1,7 +1,7 @@ System - MokoSuiteCross Events - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_system_mokosuitecross_gallery/mokosuitecross_gallery.xml b/source/packages/plg_system_mokosuitecross_gallery/mokosuitecross_gallery.xml index 7a16fc26..19a083c2 100644 --- a/source/packages/plg_system_mokosuitecross_gallery/mokosuitecross_gallery.xml +++ b/source/packages/plg_system_mokosuitecross_gallery/mokosuitecross_gallery.xml @@ -1,7 +1,7 @@ System - MokoSuiteCross Gallery - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_task_mokosuitecross/mokosuitecross.xml b/source/packages/plg_task_mokosuitecross/mokosuitecross.xml index edf8628c..990d1052 100644 --- a/source/packages/plg_task_mokosuitecross/mokosuitecross.xml +++ b/source/packages/plg_task_mokosuitecross/mokosuitecross.xml @@ -1,7 +1,7 @@ Task - MokoSuiteCross Queue Processor - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/packages/plg_webservices_mokosuitecross/mokosuitecross.xml b/source/packages/plg_webservices_mokosuitecross/mokosuitecross.xml index 7d982e5d..83e5d66d 100644 --- a/source/packages/plg_webservices_mokosuitecross/mokosuitecross.xml +++ b/source/packages/plg_webservices_mokosuitecross/mokosuitecross.xml @@ -1,7 +1,7 @@ Web Services - MokoSuiteCross - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech diff --git a/source/pkg_mokosuitecross.xml b/source/pkg_mokosuitecross.xml index 684cb434..da38a4e1 100644 --- a/source/pkg_mokosuitecross.xml +++ b/source/pkg_mokosuitecross.xml @@ -2,7 +2,7 @@ MokoSuiteCross mokosuitecross - 01.08.51 + 01.08.52 2026-05-28 Moko Consulting hello@mokoconsulting.tech -- 2.52.0