Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6916526e67 | |||
| ab65658f12 |
@@ -5,7 +5,7 @@
|
|||||||
# FILE INFORMATION
|
# FILE INFORMATION
|
||||||
# DEFGROUP: Gitea.Workflow
|
# DEFGROUP: Gitea.Workflow
|
||||||
# INGROUP: mokocli.Automation
|
# INGROUP: mokocli.Automation
|
||||||
# VERSION: 01.08.53
|
# VERSION: 01.08.54
|
||||||
# BRIEF: Auto-create feature branch when an issue is opened
|
# BRIEF: Auto-create feature branch when an issue is opened
|
||||||
|
|
||||||
name: "Universal: Issue Branch"
|
name: "Universal: Issue Branch"
|
||||||
|
|||||||
+4
-1
@@ -2,6 +2,9 @@
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- **Best time to post analytics**: engagement tracking with heatmap dashboard widget (#165)
|
||||||
|
- **Analytics heatmap**: 7x24 day/hour grid showing optimal posting windows per platform
|
||||||
|
- **Analytics recommendations**: top posting times based on historical engagement data
|
||||||
- **Social image generator**: Generate Open Graph images with article title overlay using PHP GD library (#157)
|
- **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)
|
- **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 caption generation**: Generate platform-optimized cross-post captions from article content using Claude or OpenAI (#161)
|
||||||
@@ -98,7 +101,7 @@
|
|||||||
## [01.03.00] --- 2026-06-21
|
## [01.03.00] --- 2026-06-21
|
||||||
|
|
||||||
|
|
||||||
<!-- VERSION: 01.08.53 -->
|
<!-- VERSION: 01.08.54 -->
|
||||||
|
|
||||||
All notable changes to MokoSuiteCross will be documented in this file.
|
All notable changes to MokoSuiteCross will be documented in this file.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -14,7 +14,7 @@
|
|||||||
DEFGROUP: Template-Joomla
|
DEFGROUP: Template-Joomla
|
||||||
INGROUP: Template-Joomla.Documentation
|
INGROUP: Template-Joomla.Documentation
|
||||||
REPO: https://github.com/mokoconsulting-tech/Template-Joomla/
|
REPO: https://github.com/mokoconsulting-tech/Template-Joomla/
|
||||||
VERSION: 01.08.53
|
VERSION: 01.08.54
|
||||||
PATH: ./CODE_OF_CONDUCT.md
|
PATH: ./CODE_OF_CONDUCT.md
|
||||||
BRIEF: Community expectations and enforcement guidelines
|
BRIEF: Community expectations and enforcement guidelines
|
||||||
NOTE: Adapted with attribution from the Contributor Covenant v2.1
|
NOTE: Adapted with attribution from the Contributor Covenant v2.1
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# MokoSuiteCross
|
# MokoSuiteCross
|
||||||
|
|
||||||
<!-- VERSION: 01.08.53 -->
|
<!-- VERSION: 01.08.54 -->
|
||||||
|
|
||||||
Cross-posting Joomla content to social media, email marketing, and chat platforms for Joomla 5/6.
|
Cross-posting Joomla content to social media, email marketing, and chat platforms for Joomla 5/6.
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ DEFGROUP: Template-Joomla
|
|||||||
INGROUP: Template-Joomla.Documentation
|
INGROUP: Template-Joomla.Documentation
|
||||||
REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
|
REPO: https://git.mokoconsulting.tech/MokoConsulting/Template-Joomla
|
||||||
PATH: /SECURITY.md
|
PATH: /SECURITY.md
|
||||||
VERSION: 01.08.53
|
VERSION: 01.08.54
|
||||||
BRIEF: Security vulnerability reporting and handling policy
|
BRIEF: Security vulnerability reporting and handling policy
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|||||||
@@ -586,6 +586,14 @@ COM_MOKOSUITECROSS_CONFIG_SOCIAL_IMAGE_SITE_NAME="Site Name Override"
|
|||||||
COM_MOKOSUITECROSS_CONFIG_SOCIAL_IMAGE_SITE_NAME_DESC="Custom site name shown at the bottom of generated images. Leave blank to use the Joomla site name."
|
COM_MOKOSUITECROSS_CONFIG_SOCIAL_IMAGE_SITE_NAME_DESC="Custom site name shown at the bottom of generated images. Leave blank to use the Joomla site name."
|
||||||
COM_MOKOSUITECROSS_AI_NOT_CONFIGURED="AI is not configured. Go to Options to set up a provider and API key."
|
COM_MOKOSUITECROSS_AI_NOT_CONFIGURED="AI is not configured. Go to Options to set up a provider and API key."
|
||||||
|
|
||||||
|
|
||||||
|
; Analytics
|
||||||
|
COM_MOKOSUITECROSS_ANALYTICS="Analytics"
|
||||||
|
COM_MOKOSUITECROSS_ANALYTICS_BEST_TIMES="Best Times to Post"
|
||||||
|
COM_MOKOSUITECROSS_ANALYTICS_HEATMAP="Engagement Heatmap"
|
||||||
|
COM_MOKOSUITECROSS_ANALYTICS_NO_DATA="Not enough data yet. Analytics will appear after posts collect engagement metrics."
|
||||||
|
COM_MOKOSUITECROSS_ANALYTICS_ENGAGEMENT_RATE="Engagement Rate"
|
||||||
|
COM_MOKOSUITECROSS_ANALYTICS_ALL_PLATFORMS="All Platforms"
|
||||||
; Category Rules
|
; Category Rules
|
||||||
COM_MOKOSUITECROSS_CONFIG_CATEGORY_RULES="Category Rules"
|
COM_MOKOSUITECROSS_CONFIG_CATEGORY_RULES="Category Rules"
|
||||||
COM_MOKOSUITECROSS_CONFIG_CATEGORY_RULES_NOTE="Category Routing"
|
COM_MOKOSUITECROSS_CONFIG_CATEGORY_RULES_NOTE="Category Routing"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="component" method="upgrade">
|
<extension type="component" method="upgrade">
|
||||||
<name>com_mokosuitecross</name>
|
<name>com_mokosuitecross</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -96,6 +96,27 @@ INSERT INTO `#__mokosuitecross_templates` (`service_type`, `title`, `template_bo
|
|||||||
('instagram', 'Instagram Default', '{social}\n\n{hashtags}', 1, 21, NOW()),
|
('instagram', 'Instagram Default', '{social}\n\n{hashtags}', 1, 21, NOW()),
|
||||||
('youtube', 'YouTube Default', '{social}\n\n{url}', 1, 22, NOW());
|
('youtube', 'YouTube Default', '{social}\n\n{url}', 1, 22, NOW());
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `#__mokosuitecross_analytics` (
|
||||||
|
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`post_id` int unsigned NOT NULL,
|
||||||
|
`service_id` int unsigned NOT NULL,
|
||||||
|
`service_type` varchar(50) NOT NULL DEFAULT '',
|
||||||
|
`posted_at` datetime DEFAULT NULL,
|
||||||
|
`day_of_week` tinyint unsigned NOT NULL DEFAULT 0,
|
||||||
|
`hour_of_day` tinyint unsigned NOT NULL DEFAULT 0,
|
||||||
|
`impressions` int unsigned NOT NULL DEFAULT 0,
|
||||||
|
`engagements` int unsigned NOT NULL DEFAULT 0,
|
||||||
|
`clicks` int unsigned NOT NULL DEFAULT 0,
|
||||||
|
`shares` int unsigned NOT NULL DEFAULT 0,
|
||||||
|
`engagement_rate` decimal(5,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`created` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_service_type` (`service_type`),
|
||||||
|
KEY `idx_day_hour` (`day_of_week`, `hour_of_day`),
|
||||||
|
KEY `idx_post` (`post_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS `#__mokosuitecross_category_rules` (
|
CREATE TABLE IF NOT EXISTS `#__mokosuitecross_category_rules` (
|
||||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||||
`category_id` int(10) unsigned NOT NULL,
|
`category_id` int(10) unsigned NOT NULL,
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
-- MokoSuiteCross 01.08.54 -- Best time to post analytics
|
||||||
|
-- Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||||
|
-- SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS `#__mokosuitecross_analytics` (
|
||||||
|
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||||
|
`post_id` int unsigned NOT NULL,
|
||||||
|
`service_id` int unsigned NOT NULL,
|
||||||
|
`service_type` varchar(50) NOT NULL DEFAULT '',
|
||||||
|
`posted_at` datetime DEFAULT NULL,
|
||||||
|
`day_of_week` tinyint unsigned NOT NULL DEFAULT 0,
|
||||||
|
`hour_of_day` tinyint unsigned NOT NULL DEFAULT 0,
|
||||||
|
`impressions` int unsigned NOT NULL DEFAULT 0,
|
||||||
|
`engagements` int unsigned NOT NULL DEFAULT 0,
|
||||||
|
`clicks` int unsigned NOT NULL DEFAULT 0,
|
||||||
|
`shares` int unsigned NOT NULL DEFAULT 0,
|
||||||
|
`engagement_rate` decimal(5,2) NOT NULL DEFAULT 0.00,
|
||||||
|
`created` datetime NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
KEY `idx_service_type` (`service_type`),
|
||||||
|
KEY `idx_day_hour` (`day_of_week`, `hour_of_day`),
|
||||||
|
KEY `idx_post` (`post_id`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package MokoSuiteCross
|
||||||
|
* @subpackage com_mokosuitecross
|
||||||
|
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||||
|
* @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\MVC\Controller\BaseController;
|
||||||
|
use Joomla\CMS\Session\Session;
|
||||||
|
use Joomla\Component\MokoSuiteCross\Administrator\Helper\AnalyticsHelper;
|
||||||
|
|
||||||
|
class AnalyticsController extends BaseController
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return heatmap grid data as JSON.
|
||||||
|
*
|
||||||
|
* Query params: service_type (string), days (int, default 90)
|
||||||
|
*/
|
||||||
|
public function heatmap(): 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$serviceType = $this->input->getCmd('service_type', '');
|
||||||
|
$days = $this->input->getInt('days', 90);
|
||||||
|
|
||||||
|
$grid = AnalyticsHelper::getHeatmapData($serviceType, $days);
|
||||||
|
$bestTimes = AnalyticsHelper::getBestTimes($serviceType, 3);
|
||||||
|
|
||||||
|
$this->app->setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'grid' => $grid,
|
||||||
|
'best_times' => $bestTimes,
|
||||||
|
]);
|
||||||
|
$this->app->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the top posting times as JSON.
|
||||||
|
*
|
||||||
|
* Query params: service_type (string), limit (int, default 5)
|
||||||
|
*/
|
||||||
|
public function besttimes(): 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
$serviceType = $this->input->getCmd('service_type', '');
|
||||||
|
$limit = $this->input->getInt('limit', 5);
|
||||||
|
|
||||||
|
$bestTimes = AnalyticsHelper::getBestTimes($serviceType, $limit);
|
||||||
|
$serviceBreakdown = AnalyticsHelper::getServiceBreakdown();
|
||||||
|
|
||||||
|
$this->app->setHeader('Content-Type', 'application/json; charset=utf-8');
|
||||||
|
echo json_encode([
|
||||||
|
'success' => true,
|
||||||
|
'best_times' => $bestTimes,
|
||||||
|
'service_breakdown' => $serviceBreakdown,
|
||||||
|
]);
|
||||||
|
$this->app->close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @package MokoSuiteCross
|
||||||
|
* @subpackage com_mokosuitecross
|
||||||
|
* @author Moko Consulting <hello@mokoconsulting.tech>
|
||||||
|
* @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 AnalyticsHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Record or update engagement metrics for a post.
|
||||||
|
*
|
||||||
|
* @param int $postId The post ID
|
||||||
|
* @param int $serviceId The service ID
|
||||||
|
* @param string $serviceType The service type (e.g. twitter, facebook)
|
||||||
|
* @param array $metrics Engagement metrics: impressions, engagements, clicks, shares, posted_at
|
||||||
|
*
|
||||||
|
* @return bool True on success
|
||||||
|
*/
|
||||||
|
public static function recordEngagement(int $postId, int $serviceId, string $serviceType, array $metrics): bool
|
||||||
|
{
|
||||||
|
$db = Factory::getDbo();
|
||||||
|
|
||||||
|
$postedAt = $metrics['posted_at'] ?? null;
|
||||||
|
|
||||||
|
if ($postedAt) {
|
||||||
|
$timestamp = strtotime($postedAt);
|
||||||
|
$dayOfWeek = (int) date('w', $timestamp);
|
||||||
|
$hourOfDay = (int) date('G', $timestamp);
|
||||||
|
} else {
|
||||||
|
$dayOfWeek = 0;
|
||||||
|
$hourOfDay = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$impressions = (int) ($metrics['impressions'] ?? 0);
|
||||||
|
$engagements = (int) ($metrics['engagements'] ?? 0);
|
||||||
|
$clicks = (int) ($metrics['clicks'] ?? 0);
|
||||||
|
$shares = (int) ($metrics['shares'] ?? 0);
|
||||||
|
|
||||||
|
$engagementRate = $impressions > 0
|
||||||
|
? round(($engagements / $impressions) * 100, 2)
|
||||||
|
: 0.00;
|
||||||
|
|
||||||
|
// Check if a row already exists for this post
|
||||||
|
$query = $db->getQuery(true)
|
||||||
|
->select($db->quoteName('id'))
|
||||||
|
->from($db->quoteName('#__mokosuitecross_analytics'))
|
||||||
|
->where($db->quoteName('post_id') . ' = ' . $postId)
|
||||||
|
->where($db->quoteName('service_id') . ' = ' . $serviceId);
|
||||||
|
$db->setQuery($query);
|
||||||
|
$existingId = $db->loadResult();
|
||||||
|
|
||||||
|
if ($existingId) {
|
||||||
|
$query = $db->getQuery(true)
|
||||||
|
->update($db->quoteName('#__mokosuitecross_analytics'))
|
||||||
|
->set($db->quoteName('impressions') . ' = ' . $impressions)
|
||||||
|
->set($db->quoteName('engagements') . ' = ' . $engagements)
|
||||||
|
->set($db->quoteName('clicks') . ' = ' . $clicks)
|
||||||
|
->set($db->quoteName('shares') . ' = ' . $shares)
|
||||||
|
->set($db->quoteName('engagement_rate') . ' = ' . $engagementRate)
|
||||||
|
->where($db->quoteName('id') . ' = ' . (int) $existingId);
|
||||||
|
$db->setQuery($query);
|
||||||
|
$db->execute();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$record = (object) [
|
||||||
|
'post_id' => $postId,
|
||||||
|
'service_id' => $serviceId,
|
||||||
|
'service_type' => $serviceType,
|
||||||
|
'posted_at' => $postedAt,
|
||||||
|
'day_of_week' => $dayOfWeek,
|
||||||
|
'hour_of_day' => $hourOfDay,
|
||||||
|
'impressions' => $impressions,
|
||||||
|
'engagements' => $engagements,
|
||||||
|
'clicks' => $clicks,
|
||||||
|
'shares' => $shares,
|
||||||
|
'engagement_rate' => $engagementRate,
|
||||||
|
'created' => Factory::getDate()->toSql(),
|
||||||
|
];
|
||||||
|
|
||||||
|
$db->insertObject('#__mokosuitecross_analytics', $record);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get heatmap data as a 7x24 grid of average engagement rates.
|
||||||
|
*
|
||||||
|
* @param string $serviceType Optional service type filter
|
||||||
|
* @param int $days Number of days to look back (0 = all time)
|
||||||
|
*
|
||||||
|
* @return array 7x24 grid: [ day_of_week => [ hour_of_day => avg_engagement_rate ] ]
|
||||||
|
*/
|
||||||
|
public static function getHeatmapData(string $serviceType = '', int $days = 90): array
|
||||||
|
{
|
||||||
|
$db = Factory::getDbo();
|
||||||
|
|
||||||
|
$query = $db->getQuery(true)
|
||||||
|
->select([
|
||||||
|
$db->quoteName('day_of_week'),
|
||||||
|
$db->quoteName('hour_of_day'),
|
||||||
|
'AVG(' . $db->quoteName('engagement_rate') . ') AS avg_rate',
|
||||||
|
'COUNT(*) AS post_count',
|
||||||
|
])
|
||||||
|
->from($db->quoteName('#__mokosuitecross_analytics'))
|
||||||
|
->group($db->quoteName('day_of_week'))
|
||||||
|
->group($db->quoteName('hour_of_day'))
|
||||||
|
->order($db->quoteName('day_of_week') . ' ASC')
|
||||||
|
->order($db->quoteName('hour_of_day') . ' ASC');
|
||||||
|
|
||||||
|
if ($serviceType !== '') {
|
||||||
|
$query->where($db->quoteName('service_type') . ' = ' . $db->quote($serviceType));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($days > 0) {
|
||||||
|
$cutoff = Factory::getDate('-' . $days . ' days')->toSql();
|
||||||
|
$query->where($db->quoteName('posted_at') . ' >= ' . $db->quote($cutoff));
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->setQuery($query);
|
||||||
|
$rows = $db->loadObjectList();
|
||||||
|
|
||||||
|
// Build 7x24 grid initialised to zero
|
||||||
|
$grid = [];
|
||||||
|
|
||||||
|
for ($d = 0; $d < 7; $d++) {
|
||||||
|
for ($h = 0; $h < 24; $h++) {
|
||||||
|
$grid[$d][$h] = ['avg_rate' => 0.00, 'post_count' => 0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$grid[(int) $row->day_of_week][(int) $row->hour_of_day] = [
|
||||||
|
'avg_rate' => round((float) $row->avg_rate, 2),
|
||||||
|
'post_count' => (int) $row->post_count,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the best times to post ranked by average engagement rate.
|
||||||
|
*
|
||||||
|
* @param string $serviceType Optional service type filter
|
||||||
|
* @param int $limit Number of results to return
|
||||||
|
*
|
||||||
|
* @return array List of [day_of_week, hour_of_day, avg_rate, post_count]
|
||||||
|
*/
|
||||||
|
public static function getBestTimes(string $serviceType = '', int $limit = 5): array
|
||||||
|
{
|
||||||
|
$db = Factory::getDbo();
|
||||||
|
|
||||||
|
$query = $db->getQuery(true)
|
||||||
|
->select([
|
||||||
|
$db->quoteName('day_of_week'),
|
||||||
|
$db->quoteName('hour_of_day'),
|
||||||
|
'AVG(' . $db->quoteName('engagement_rate') . ') AS avg_rate',
|
||||||
|
'COUNT(*) AS post_count',
|
||||||
|
])
|
||||||
|
->from($db->quoteName('#__mokosuitecross_analytics'))
|
||||||
|
->group($db->quoteName('day_of_week'))
|
||||||
|
->group($db->quoteName('hour_of_day'))
|
||||||
|
->having('COUNT(*) >= 1')
|
||||||
|
->order('avg_rate DESC');
|
||||||
|
|
||||||
|
if ($serviceType !== '') {
|
||||||
|
$query->where($db->quoteName('service_type') . ' = ' . $db->quote($serviceType));
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->setQuery($query, 0, $limit);
|
||||||
|
$rows = $db->loadAssocList();
|
||||||
|
|
||||||
|
$dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
|
||||||
|
foreach ($rows as $row) {
|
||||||
|
$hour = (int) $row['hour_of_day'];
|
||||||
|
$ampm = $hour < 12 ? 'AM' : 'PM';
|
||||||
|
$hour12 = $hour % 12 ?: 12;
|
||||||
|
|
||||||
|
$results[] = [
|
||||||
|
'day_of_week' => (int) $row['day_of_week'],
|
||||||
|
'day_name' => $dayNames[(int) $row['day_of_week']],
|
||||||
|
'hour_of_day' => $hour,
|
||||||
|
'hour_label' => $hour12 . ':00 ' . $ampm,
|
||||||
|
'avg_rate' => round((float) $row['avg_rate'], 2),
|
||||||
|
'post_count' => (int) $row['post_count'],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get engagement stats grouped by service type.
|
||||||
|
*
|
||||||
|
* @param int $days Number of days to look back (0 = all time)
|
||||||
|
*
|
||||||
|
* @return array List of [service_type, total_posts, avg_engagement_rate, total_impressions, total_engagements]
|
||||||
|
*/
|
||||||
|
public static function getServiceBreakdown(int $days = 30): array
|
||||||
|
{
|
||||||
|
$db = Factory::getDbo();
|
||||||
|
|
||||||
|
$query = $db->getQuery(true)
|
||||||
|
->select([
|
||||||
|
$db->quoteName('service_type'),
|
||||||
|
'COUNT(*) AS total_posts',
|
||||||
|
'AVG(' . $db->quoteName('engagement_rate') . ') AS avg_engagement_rate',
|
||||||
|
'SUM(' . $db->quoteName('impressions') . ') AS total_impressions',
|
||||||
|
'SUM(' . $db->quoteName('engagements') . ') AS total_engagements',
|
||||||
|
'SUM(' . $db->quoteName('clicks') . ') AS total_clicks',
|
||||||
|
'SUM(' . $db->quoteName('shares') . ') AS total_shares',
|
||||||
|
])
|
||||||
|
->from($db->quoteName('#__mokosuitecross_analytics'))
|
||||||
|
->group($db->quoteName('service_type'))
|
||||||
|
->order('avg_engagement_rate DESC');
|
||||||
|
|
||||||
|
if ($days > 0) {
|
||||||
|
$cutoff = Factory::getDate('-' . $days . ' days')->toSql();
|
||||||
|
$query->where($db->quoteName('posted_at') . ' >= ' . $db->quote($cutoff));
|
||||||
|
}
|
||||||
|
|
||||||
|
$db->setQuery($query);
|
||||||
|
$rows = $db->loadAssocList();
|
||||||
|
|
||||||
|
foreach ($rows as &$row) {
|
||||||
|
$row['avg_engagement_rate'] = round((float) $row['avg_engagement_rate'], 2);
|
||||||
|
$row['total_posts'] = (int) $row['total_posts'];
|
||||||
|
$row['total_impressions'] = (int) $row['total_impressions'];
|
||||||
|
$row['total_engagements'] = (int) $row['total_engagements'];
|
||||||
|
$row['total_clicks'] = (int) $row['total_clicks'];
|
||||||
|
$row['total_shares'] = (int) $row['total_shares'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -220,6 +220,175 @@ $queueProcessing = $componentParams->get('queue_processing', 'scheduler');
|
|||||||
</div>
|
</div>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<!-- Analytics: Best Times to Post Heatmap -->
|
||||||
|
<div class="card mt-3">
|
||||||
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
|
<h5 class="card-title mb-0"><?php echo Text::_('COM_MOKOSUITECROSS_ANALYTICS_BEST_TIMES'); ?></h5>
|
||||||
|
<select id="heatmapServiceFilter" class="form-select form-select-sm" style="width: auto;">
|
||||||
|
<option value=""><?php echo Text::_('COM_MOKOSUITECROSS_ANALYTICS_ALL_PLATFORMS'); ?></option>
|
||||||
|
<?php
|
||||||
|
$db = \Joomla\CMS\Factory::getDbo();
|
||||||
|
$stQuery = $db->getQuery(true)
|
||||||
|
->select('DISTINCT ' . $db->quoteName('service_type'))
|
||||||
|
->from($db->quoteName('#__mokosuitecross_services'))
|
||||||
|
->where($db->quoteName('published') . ' = 1')
|
||||||
|
->order($db->quoteName('service_type') . ' ASC');
|
||||||
|
$db->setQuery($stQuery);
|
||||||
|
$serviceTypes = $db->loadColumn();
|
||||||
|
foreach ($serviceTypes as $st) :
|
||||||
|
?>
|
||||||
|
<option value="<?php echo htmlspecialchars($st); ?>"><?php echo htmlspecialchars(ucfirst($st)); ?></option>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div id="heatmapContainer">
|
||||||
|
<p class="text-muted" id="heatmapLoading"><?php echo Text::_('JLIB_HTML_BEHAVIOR_LOADING'); ?></p>
|
||||||
|
<div id="heatmapNoData" style="display:none;">
|
||||||
|
<p class="text-muted mb-0"><?php echo Text::_('COM_MOKOSUITECROSS_ANALYTICS_NO_DATA'); ?></p>
|
||||||
|
</div>
|
||||||
|
<div id="heatmapGrid" style="display:none;">
|
||||||
|
<style>
|
||||||
|
.msc-heatmap { border-collapse: collapse; width: 100%; font-size: 11px; }
|
||||||
|
.msc-heatmap th, .msc-heatmap td { text-align: center; padding: 3px 2px; min-width: 28px; }
|
||||||
|
.msc-heatmap th { font-weight: 600; color: #666; font-size: 10px; }
|
||||||
|
.msc-heatmap td.msc-hm-cell { border-radius: 3px; cursor: default; position: relative; }
|
||||||
|
.msc-heatmap td.msc-hm-cell:hover { outline: 2px solid #333; z-index: 1; }
|
||||||
|
.msc-heatmap .msc-hm-day { text-align: right; padding-right: 8px; font-weight: 600; color: #555; white-space: nowrap; }
|
||||||
|
</style>
|
||||||
|
<table class="msc-heatmap" id="heatmapTable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<?php for ($h = 0; $h < 24; $h++) :
|
||||||
|
$label = $h % 12 ?: 12;
|
||||||
|
$suffix = $h < 12 ? 'a' : 'p';
|
||||||
|
?>
|
||||||
|
<th><?php echo $label . $suffix; ?></th>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php
|
||||||
|
$dayLabels = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
||||||
|
for ($d = 0; $d < 7; $d++) :
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td class="msc-hm-day"><?php echo $dayLabels[$d]; ?></td>
|
||||||
|
<?php for ($h = 0; $h < 24; $h++) : ?>
|
||||||
|
<td class="msc-hm-cell" id="hm-<?php echo $d; ?>-<?php echo $h; ?>" title="<?php echo $dayLabels[$d] . ' ' . ($h % 12 ?: 12) . ':00 ' . ($h < 12 ? 'AM' : 'PM'); ?>"></td>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</tr>
|
||||||
|
<?php endfor; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="d-flex align-items-center justify-content-end mt-2" style="font-size:11px;color:#666;">
|
||||||
|
<span class="me-1"><?php echo Text::_('COM_MOKOSUITECROSS_ANALYTICS_ENGAGEMENT_RATE'); ?>:</span>
|
||||||
|
<span style="display:inline-block;width:14px;height:14px;background:#ebedf0;border-radius:2px;margin:0 1px;" title="0%"></span>
|
||||||
|
<span style="display:inline-block;width:14px;height:14px;background:#9be9a8;border-radius:2px;margin:0 1px;" title="Low"></span>
|
||||||
|
<span style="display:inline-block;width:14px;height:14px;background:#40c463;border-radius:2px;margin:0 1px;" title="Medium"></span>
|
||||||
|
<span style="display:inline-block;width:14px;height:14px;background:#30a14e;border-radius:2px;margin:0 1px;" title="High"></span>
|
||||||
|
<span style="display:inline-block;width:14px;height:14px;background:#216e39;border-radius:2px;margin:0 1px;" title="Very High"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="heatmapBestTimes" style="display:none;" class="mt-3 pt-3 border-top">
|
||||||
|
<strong><?php echo Text::_('COM_MOKOSUITECROSS_ANALYTICS_BEST_TIMES'); ?>:</strong>
|
||||||
|
<ul id="bestTimesList" class="mb-0 mt-1"></ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
var token = '<?php echo \Joomla\CMS\Session\Session::getFormToken(); ?>';
|
||||||
|
|
||||||
|
function loadHeatmap(serviceType) {
|
||||||
|
var url = 'index.php?option=com_mokosuitecross&task=analytics.heatmap&format=json'
|
||||||
|
+ '&service_type=' + encodeURIComponent(serviceType || '')
|
||||||
|
+ '&days=90&' + token + '=1';
|
||||||
|
|
||||||
|
document.getElementById('heatmapLoading').style.display = '';
|
||||||
|
document.getElementById('heatmapGrid').style.display = 'none';
|
||||||
|
document.getElementById('heatmapNoData').style.display = 'none';
|
||||||
|
document.getElementById('heatmapBestTimes').style.display = 'none';
|
||||||
|
|
||||||
|
fetch(url)
|
||||||
|
.then(function(r) { return r.json(); })
|
||||||
|
.then(function(data) {
|
||||||
|
document.getElementById('heatmapLoading').style.display = 'none';
|
||||||
|
|
||||||
|
if (!data.success) {
|
||||||
|
document.getElementById('heatmapNoData').style.display = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var grid = data.grid;
|
||||||
|
var maxRate = 0;
|
||||||
|
var hasData = false;
|
||||||
|
|
||||||
|
for (var d = 0; d < 7; d++) {
|
||||||
|
for (var h = 0; h < 24; h++) {
|
||||||
|
var rate = grid[d] && grid[d][h] ? parseFloat(grid[d][h].avg_rate) : 0;
|
||||||
|
if (rate > maxRate) maxRate = rate;
|
||||||
|
if (rate > 0) hasData = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hasData) {
|
||||||
|
document.getElementById('heatmapNoData').style.display = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('heatmapGrid').style.display = '';
|
||||||
|
|
||||||
|
var colors = ['#ebedf0', '#9be9a8', '#40c463', '#30a14e', '#216e39'];
|
||||||
|
for (var d = 0; d < 7; d++) {
|
||||||
|
for (var h = 0; h < 24; h++) {
|
||||||
|
var cell = document.getElementById('hm-' + d + '-' + h);
|
||||||
|
if (!cell) continue;
|
||||||
|
var val = grid[d] && grid[d][h] ? grid[d][h] : {avg_rate: 0, post_count: 0};
|
||||||
|
var rate = parseFloat(val.avg_rate);
|
||||||
|
var count = parseInt(val.post_count, 10);
|
||||||
|
var level = 0;
|
||||||
|
if (maxRate > 0 && rate > 0) {
|
||||||
|
var pct = rate / maxRate;
|
||||||
|
if (pct <= 0.25) level = 1;
|
||||||
|
else if (pct <= 0.50) level = 2;
|
||||||
|
else if (pct <= 0.75) level = 3;
|
||||||
|
else level = 4;
|
||||||
|
}
|
||||||
|
cell.style.backgroundColor = colors[level];
|
||||||
|
cell.title = cell.title.split(' - ')[0] + ' - ' + rate.toFixed(1) + '% (' + count + ' posts)';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show best times
|
||||||
|
if (data.best_times && data.best_times.length > 0) {
|
||||||
|
document.getElementById('heatmapBestTimes').style.display = '';
|
||||||
|
var list = document.getElementById('bestTimesList');
|
||||||
|
list.innerHTML = '';
|
||||||
|
var top = data.best_times.slice(0, 3);
|
||||||
|
for (var i = 0; i < top.length; i++) {
|
||||||
|
var bt = top[i];
|
||||||
|
var li = document.createElement('li');
|
||||||
|
li.textContent = bt.day_name + ' at ' + bt.hour_label + ' (' + bt.avg_rate.toFixed(1) + '% avg engagement)';
|
||||||
|
list.appendChild(li);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(function() {
|
||||||
|
document.getElementById('heatmapLoading').style.display = 'none';
|
||||||
|
document.getElementById('heatmapNoData').style.display = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('heatmapServiceFilter').addEventListener('change', function() {
|
||||||
|
loadHeatmap(this.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
loadHeatmap('');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
<!-- Recent Activity -->
|
<!-- Recent Activity -->
|
||||||
<div class="card mt-3">
|
<div class="card mt-3">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="content" method="upgrade">
|
<extension type="plugin" group="content" method="upgrade">
|
||||||
<name>Content - MokoSuiteCross</name>
|
<name>Content - MokoSuiteCross</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - ActivityPub (Fediverse)</name>
|
<name>MokoSuiteCross - ActivityPub (Fediverse)</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Google Blogger</name>
|
<name>MokoSuiteCross - Google Blogger</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Bluesky</name>
|
<name>MokoSuiteCross - Bluesky</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Brevo (Sendinblue)</name>
|
<name>MokoSuiteCross - Brevo (Sendinblue)</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Constant Contact</name>
|
<name>MokoSuiteCross - Constant Contact</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - ConvertKit</name>
|
<name>MokoSuiteCross - ConvertKit</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Dev.to</name>
|
<name>MokoSuiteCross - Dev.to</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Discord</name>
|
<name>MokoSuiteCross - Discord</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Facebook / Meta</name>
|
<name>MokoSuiteCross - Facebook / Meta</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Ghost</name>
|
<name>MokoSuiteCross - Ghost</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Google Business Profile</name>
|
<name>MokoSuiteCross - Google Business Profile</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Google Chat</name>
|
<name>MokoSuiteCross - Google Chat</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Hashnode</name>
|
<name>MokoSuiteCross - Hashnode</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Instagram</name>
|
<name>MokoSuiteCross - Instagram</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-06-23</creationDate>
|
<creationDate>2026-06-23</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - LinkedIn</name>
|
<name>MokoSuiteCross - LinkedIn</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Mailchimp</name>
|
<name>MokoSuiteCross - Mailchimp</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Mastodon</name>
|
<name>MokoSuiteCross - Mastodon</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Matrix / Element</name>
|
<name>MokoSuiteCross - Matrix / Element</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Medium</name>
|
<name>MokoSuiteCross - Medium</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - MokoSuiteCalendar Events</name>
|
<name>MokoSuiteCross - MokoSuiteCalendar Events</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - MokoSuiteGallery</name>
|
<name>MokoSuiteCross - MokoSuiteGallery</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Nostr</name>
|
<name>MokoSuiteCross - Nostr</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Ntfy Push Notifications</name>
|
<name>MokoSuiteCross - Ntfy Push Notifications</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Pinterest</name>
|
<name>MokoSuiteCross - Pinterest</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Reddit</name>
|
<name>MokoSuiteCross - Reddit</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - RSS Feed</name>
|
<name>MokoSuiteCross - RSS Feed</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - SendGrid</name>
|
<name>MokoSuiteCross - SendGrid</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Slack</name>
|
<name>MokoSuiteCross - Slack</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Microsoft Teams</name>
|
<name>MokoSuiteCross - Microsoft Teams</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Telegram</name>
|
<name>MokoSuiteCross - Telegram</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Threads (Meta)</name>
|
<name>MokoSuiteCross - Threads (Meta)</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - TikTok</name>
|
<name>MokoSuiteCross - TikTok</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Tumblr</name>
|
<name>MokoSuiteCross - Tumblr</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - X / Twitter</name>
|
<name>MokoSuiteCross - X / Twitter</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Generic Webhook</name>
|
<name>MokoSuiteCross - Generic Webhook</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - WhatsApp Business</name>
|
<name>MokoSuiteCross - WhatsApp Business</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - WordPress</name>
|
<name>MokoSuiteCross - WordPress</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
<extension type="plugin" group="mokosuitecross" method="upgrade">
|
||||||
<name>MokoSuiteCross - Youtube</name>
|
<name>MokoSuiteCross - Youtube</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-06-23</creationDate>
|
<creationDate>2026-06-23</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="system" method="upgrade">
|
<extension type="plugin" group="system" method="upgrade">
|
||||||
<name>System - MokoSuiteCross</name>
|
<name>System - MokoSuiteCross</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="system" method="upgrade">
|
<extension type="plugin" group="system" method="upgrade">
|
||||||
<name>System - MokoSuiteCross Events</name>
|
<name>System - MokoSuiteCross Events</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="system" method="upgrade">
|
<extension type="plugin" group="system" method="upgrade">
|
||||||
<name>System - MokoSuiteCross Gallery</name>
|
<name>System - MokoSuiteCross Gallery</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="task" method="upgrade">
|
<extension type="plugin" group="task" method="upgrade">
|
||||||
<name>Task - MokoSuiteCross Queue Processor</name>
|
<name>Task - MokoSuiteCross Queue Processor</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<extension type="plugin" group="webservices" method="upgrade">
|
<extension type="plugin" group="webservices" method="upgrade">
|
||||||
<name>Web Services - MokoSuiteCross</name>
|
<name>Web Services - MokoSuiteCross</name>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<extension type="package" method="upgrade">
|
<extension type="package" method="upgrade">
|
||||||
<name>MokoSuiteCross</name>
|
<name>MokoSuiteCross</name>
|
||||||
<packagename>mokosuitecross</packagename>
|
<packagename>mokosuitecross</packagename>
|
||||||
<version>01.08.53</version>
|
<version>01.08.54</version>
|
||||||
<creationDate>2026-05-28</creationDate>
|
<creationDate>2026-05-28</creationDate>
|
||||||
<author>Moko Consulting</author>
|
<author>Moko Consulting</author>
|
||||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||||
|
|||||||
Reference in New Issue
Block a user