From 2088b3f13fe37a2a4ddbdb6f5d0c03ebcd72a0af Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Tue, 23 Jun 2026 12:29:38 -0500 Subject: [PATCH] feat: add OG coverage dashboard to tag manager Shows coverage percentage, article count with/without OG tags, and counts of missing title, description, and image fields. Closes #73 --- .../com_mokoog/language/en-GB/com_mokoog.ini | 7 +++ .../com_mokoog/language/en-US/com_mokoog.ini | 7 +++ .../com_mokoog/tmpl/tags/coverage.php | 58 +++++++++++++++++++ .../packages/com_mokoog/tmpl/tags/default.php | 1 + 4 files changed, 73 insertions(+) create mode 100644 source/packages/com_mokoog/tmpl/tags/coverage.php diff --git a/source/packages/com_mokoog/language/en-GB/com_mokoog.ini b/source/packages/com_mokoog/language/en-GB/com_mokoog.ini index e8db069..4e8f84a 100644 --- a/source/packages/com_mokoog/language/en-GB/com_mokoog.ini +++ b/source/packages/com_mokoog/language/en-GB/com_mokoog.ini @@ -59,3 +59,10 @@ COM_MOKOOG_IMPORT_INVALID_TYPE="Invalid file type. Please upload a .csv file." COM_MOKOOG_IMPORT_FILE_TOO_LARGE="File is too large. Maximum allowed size is %s." COM_MOKOOG_IMPORT_READ_ERROR="Could not read the uploaded CSV file." COM_MOKOOG_IMPORT_RESULT="Import complete: %d created, %d updated, %d skipped." + +COM_MOKOOG_COVERAGE_TITLE="OG Tag Coverage" +COM_MOKOOG_COVERAGE_PERCENT="OG Coverage" +COM_MOKOOG_COVERAGE_ARTICLES="%d of %d articles have OG tags" +COM_MOKOOG_COVERAGE_MISSING_TITLE="%d tags missing custom title" +COM_MOKOOG_COVERAGE_MISSING_DESC="%d tags missing custom description" +COM_MOKOOG_COVERAGE_MISSING_IMAGE="%d tags missing custom image" diff --git a/source/packages/com_mokoog/language/en-US/com_mokoog.ini b/source/packages/com_mokoog/language/en-US/com_mokoog.ini index e8db069..4e8f84a 100644 --- a/source/packages/com_mokoog/language/en-US/com_mokoog.ini +++ b/source/packages/com_mokoog/language/en-US/com_mokoog.ini @@ -59,3 +59,10 @@ COM_MOKOOG_IMPORT_INVALID_TYPE="Invalid file type. Please upload a .csv file." COM_MOKOOG_IMPORT_FILE_TOO_LARGE="File is too large. Maximum allowed size is %s." COM_MOKOOG_IMPORT_READ_ERROR="Could not read the uploaded CSV file." COM_MOKOOG_IMPORT_RESULT="Import complete: %d created, %d updated, %d skipped." + +COM_MOKOOG_COVERAGE_TITLE="OG Tag Coverage" +COM_MOKOOG_COVERAGE_PERCENT="OG Coverage" +COM_MOKOOG_COVERAGE_ARTICLES="%d of %d articles have OG tags" +COM_MOKOOG_COVERAGE_MISSING_TITLE="%d tags missing custom title" +COM_MOKOOG_COVERAGE_MISSING_DESC="%d tags missing custom description" +COM_MOKOOG_COVERAGE_MISSING_IMAGE="%d tags missing custom image" diff --git a/source/packages/com_mokoog/tmpl/tags/coverage.php b/source/packages/com_mokoog/tmpl/tags/coverage.php new file mode 100644 index 0000000..b2f0830 --- /dev/null +++ b/source/packages/com_mokoog/tmpl/tags/coverage.php @@ -0,0 +1,58 @@ + + * @copyright Copyright (C) 2026 Moko Consulting. All rights reserved. + * @license GNU General Public License version 3 or later; see LICENSE + */ + +defined('_JEXEC') or die; + +use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; + +$db = Factory::getDbo(); + +// Total published articles +$db->setQuery($db->getQuery(true)->select('COUNT(*)')->from('#__content')->where('state = 1')); +$totalArticles = (int) $db->loadResult(); + +// Articles with OG tags +$db->setQuery($db->getQuery(true)->select('COUNT(DISTINCT content_id)')->from('#__mokoog_tags')->where("content_type = 'com_content'")->where('published = 1')); +$articlesWithOg = (int) $db->loadResult(); + +// Articles missing OG data fields +$db->setQuery($db->getQuery(true)->select('COUNT(*)')->from('#__mokoog_tags')->where("content_type = 'com_content'")->where("og_title = ''")->where('published = 1')); +$missingTitle = (int) $db->loadResult(); + +$db->setQuery($db->getQuery(true)->select('COUNT(*)')->from('#__mokoog_tags')->where("content_type = 'com_content'")->where("og_description = ''")->where('published = 1')); +$missingDesc = (int) $db->loadResult(); + +$db->setQuery($db->getQuery(true)->select('COUNT(*)')->from('#__mokoog_tags')->where("content_type = 'com_content'")->where("og_image = ''")->where('published = 1')); +$missingImage = (int) $db->loadResult(); + +$coverage = $totalArticles > 0 ? round(($articlesWithOg / $totalArticles) * 100) : 0; +?> +
+
+

+
+
+
+ % +
+ +
+
+
    +
  • +
  • +
  • +
  • +
+
+
+
+
diff --git a/source/packages/com_mokoog/tmpl/tags/default.php b/source/packages/com_mokoog/tmpl/tags/default.php index 6ca4e90..0367944 100644 --- a/source/packages/com_mokoog/tmpl/tags/default.php +++ b/source/packages/com_mokoog/tmpl/tags/default.php @@ -21,6 +21,7 @@ use Joomla\CMS\Session\Session; $token = Session::getFormToken(); ?> +