fix: resolve 10 issues found in code review
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Universal: Cascade Main → Dev / Cascade main → branches (push) Successful in 3s
Critical:
- Create missing pkg_mokoog.sys.ini package language file
- Create missing forms/tag.xml and forms/filter_tags.xml for component
- Remove non-existent Service/ folder from component manifest
- Remove non-existent scriptfile from system plugin manifest
Important:
- Remove unused DatabaseAwareTrait from system plugin
- Add Event parameter to onBeforeCompileHead (Joomla 5 SubscriberInterface)
- Guard onContentAfterSave with isClient('administrator') check
- Fix duplicate DEFAULT keyword in SQL CREATE TABLE
- Quote column names with quoteName() in content plugin select
- Remove duplicate language file registration in component manifest
Authored-by: Moko Consulting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
; MokoOpenGraph - Package System Language File
|
||||||
|
; Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||||
|
; License: GPL-3.0-or-later
|
||||||
|
|
||||||
|
PKG_MOKOOG="MokoOpenGraph"
|
||||||
|
PKG_MOKOOG_DESCRIPTION="Complete Open Graph, Twitter Card, and social sharing meta tag management for Joomla. Control how every page appears when shared on Facebook, Twitter/X, LinkedIn, WhatsApp, and more."
|
||||||
|
PKG_MOKOOG_PHP_VERSION_ERROR="MokoOpenGraph requires PHP %s or later."
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
; MokoOpenGraph - Package System Language File
|
||||||
|
; Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||||
|
; License: GPL-3.0-or-later
|
||||||
|
|
||||||
|
PKG_MOKOOG="MokoOpenGraph"
|
||||||
|
PKG_MOKOOG_DESCRIPTION="Complete Open Graph, Twitter Card, and social sharing meta tag management for Joomla. Control how every page appears when shared on Facebook, Twitter/X, LinkedIn, WhatsApp, and more."
|
||||||
|
PKG_MOKOOG_PHP_VERSION_ERROR="MokoOpenGraph requires PHP %s or later."
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
* @package MokoOpenGraph
|
||||||
|
* @subpackage com_mokoog
|
||||||
|
* @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
|
||||||
|
-->
|
||||||
|
<form>
|
||||||
|
<fields name="filter">
|
||||||
|
<field
|
||||||
|
name="search"
|
||||||
|
type="text"
|
||||||
|
label="COM_MOKOOG_FILTER_SEARCH"
|
||||||
|
hint="JSEARCH_FILTER"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="published"
|
||||||
|
type="status"
|
||||||
|
label="JOPTION_SELECT_PUBLISHED"
|
||||||
|
onchange="this.form.submit();"
|
||||||
|
>
|
||||||
|
<option value="">JOPTION_SELECT_PUBLISHED</option>
|
||||||
|
<option value="1">JPUBLISHED</option>
|
||||||
|
<option value="0">JUNPUBLISHED</option>
|
||||||
|
</field>
|
||||||
|
<field
|
||||||
|
name="content_type"
|
||||||
|
type="list"
|
||||||
|
label="COM_MOKOOG_FILTER_CONTENT_TYPE"
|
||||||
|
onchange="this.form.submit();"
|
||||||
|
>
|
||||||
|
<option value="">COM_MOKOOG_FILTER_SELECT_TYPE</option>
|
||||||
|
<option value="com_content">Articles</option>
|
||||||
|
<option value="menu">Menu Items</option>
|
||||||
|
</field>
|
||||||
|
</fields>
|
||||||
|
<fields name="list">
|
||||||
|
<field
|
||||||
|
name="fullordering"
|
||||||
|
type="list"
|
||||||
|
label="JGLOBAL_SORT_BY"
|
||||||
|
default="a.modified DESC"
|
||||||
|
onchange="this.form.submit();"
|
||||||
|
>
|
||||||
|
<option value="a.id ASC">JGRID_HEADING_ID_ASC</option>
|
||||||
|
<option value="a.id DESC">JGRID_HEADING_ID_DESC</option>
|
||||||
|
<option value="a.og_title ASC">COM_MOKOOG_HEADING_OG_TITLE_ASC</option>
|
||||||
|
<option value="a.og_title DESC">COM_MOKOOG_HEADING_OG_TITLE_DESC</option>
|
||||||
|
<option value="a.modified ASC">COM_MOKOOG_HEADING_MODIFIED_ASC</option>
|
||||||
|
<option value="a.modified DESC">COM_MOKOOG_HEADING_MODIFIED_DESC</option>
|
||||||
|
</field>
|
||||||
|
<field
|
||||||
|
name="limit"
|
||||||
|
type="limitbox"
|
||||||
|
label="JGLOBAL_LIST_LIMIT"
|
||||||
|
default="25"
|
||||||
|
onchange="this.form.submit();"
|
||||||
|
/>
|
||||||
|
</fields>
|
||||||
|
</form>
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
* @package MokoOpenGraph
|
||||||
|
* @subpackage com_mokoog
|
||||||
|
* @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
|
||||||
|
-->
|
||||||
|
<form>
|
||||||
|
<fieldset name="details">
|
||||||
|
<field
|
||||||
|
name="id"
|
||||||
|
type="hidden"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="content_type"
|
||||||
|
type="text"
|
||||||
|
label="COM_MOKOOG_FIELD_CONTENT_TYPE"
|
||||||
|
readonly="true"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="content_id"
|
||||||
|
type="number"
|
||||||
|
label="COM_MOKOOG_FIELD_CONTENT_ID"
|
||||||
|
readonly="true"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="og_title"
|
||||||
|
type="text"
|
||||||
|
label="COM_MOKOOG_FIELD_OG_TITLE"
|
||||||
|
description="COM_MOKOOG_FIELD_OG_TITLE_DESC"
|
||||||
|
filter="string"
|
||||||
|
maxlength="70"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="og_description"
|
||||||
|
type="textarea"
|
||||||
|
label="COM_MOKOOG_FIELD_OG_DESCRIPTION"
|
||||||
|
description="COM_MOKOOG_FIELD_OG_DESCRIPTION_DESC"
|
||||||
|
filter="string"
|
||||||
|
rows="3"
|
||||||
|
maxlength="200"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="og_image"
|
||||||
|
type="media"
|
||||||
|
label="COM_MOKOOG_FIELD_OG_IMAGE"
|
||||||
|
description="COM_MOKOOG_FIELD_OG_IMAGE_DESC"
|
||||||
|
directory="mokoog"
|
||||||
|
/>
|
||||||
|
<field
|
||||||
|
name="og_type"
|
||||||
|
type="list"
|
||||||
|
label="COM_MOKOOG_FIELD_OG_TYPE"
|
||||||
|
description="COM_MOKOOG_FIELD_OG_TYPE_DESC"
|
||||||
|
default="article"
|
||||||
|
>
|
||||||
|
<option value="article">Article</option>
|
||||||
|
<option value="website">Website</option>
|
||||||
|
<option value="product">Product</option>
|
||||||
|
<option value="profile">Profile</option>
|
||||||
|
</field>
|
||||||
|
<field
|
||||||
|
name="published"
|
||||||
|
type="list"
|
||||||
|
label="JSTATUS"
|
||||||
|
default="1"
|
||||||
|
>
|
||||||
|
<option value="1">JPUBLISHED</option>
|
||||||
|
<option value="0">JUNPUBLISHED</option>
|
||||||
|
</field>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
@@ -4,5 +4,3 @@
|
|||||||
|
|
||||||
COM_MOKOOG="MokoOpenGraph"
|
COM_MOKOOG="MokoOpenGraph"
|
||||||
COM_MOKOOG_DESCRIPTION="Manage Open Graph and social sharing tags for all your content. View, edit, and batch-process OG metadata."
|
COM_MOKOOG_DESCRIPTION="Manage Open Graph and social sharing tags for all your content. View, edit, and batch-process OG metadata."
|
||||||
PKG_MOKOOG_DESCRIPTION="Complete Open Graph, Twitter Card, and social sharing meta tag management for Joomla. Control how every page appears when shared on Facebook, Twitter/X, LinkedIn, WhatsApp, and more."
|
|
||||||
PKG_MOKOOG_PHP_VERSION_ERROR="MokoOpenGraph requires PHP %s or later."
|
|
||||||
|
|||||||
@@ -4,5 +4,3 @@
|
|||||||
|
|
||||||
COM_MOKOOG="MokoOpenGraph"
|
COM_MOKOOG="MokoOpenGraph"
|
||||||
COM_MOKOOG_DESCRIPTION="Manage Open Graph and social sharing tags for all your content. View, edit, and batch-process OG metadata."
|
COM_MOKOOG_DESCRIPTION="Manage Open Graph and social sharing tags for all your content. View, edit, and batch-process OG metadata."
|
||||||
PKG_MOKOOG_DESCRIPTION="Complete Open Graph, Twitter Card, and social sharing meta tag management for Joomla. Control how every page appears when shared on Facebook, Twitter/X, LinkedIn, WhatsApp, and more."
|
|
||||||
PKG_MOKOOG_PHP_VERSION_ERROR="MokoOpenGraph requires PHP %s or later."
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@
|
|||||||
<folder>Controller</folder>
|
<folder>Controller</folder>
|
||||||
<folder>Extension</folder>
|
<folder>Extension</folder>
|
||||||
<folder>Model</folder>
|
<folder>Model</folder>
|
||||||
<folder>Service</folder>
|
|
||||||
<folder>Table</folder>
|
<folder>Table</folder>
|
||||||
<folder>View</folder>
|
<folder>View</folder>
|
||||||
</files>
|
</files>
|
||||||
@@ -69,9 +68,4 @@
|
|||||||
<menu link="option=com_mokoog&view=tags">COM_MOKOOG_SUBMENU_TAGS</menu>
|
<menu link="option=com_mokoog&view=tags">COM_MOKOOG_SUBMENU_TAGS</menu>
|
||||||
</submenu>
|
</submenu>
|
||||||
</administration>
|
</administration>
|
||||||
|
|
||||||
<languages folder="language">
|
|
||||||
<language tag="en-GB">en-GB/com_mokoog.ini</language>
|
|
||||||
<language tag="en-GB">en-GB/com_mokoog.sys.ini</language>
|
|
||||||
</languages>
|
|
||||||
</extension>
|
</extension>
|
||||||
|
|||||||
@@ -18,4 +18,4 @@ CREATE TABLE IF NOT EXISTS `#__mokoog_tags` (
|
|||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
UNIQUE KEY `idx_content` (`content_type`, `content_id`),
|
UNIQUE KEY `idx_content` (`content_type`, `content_id`),
|
||||||
KEY `idx_published` (`published`)
|
KEY `idx_published` (`published`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE=utf8mb4_unicode_ci;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ defined('_JEXEC') or die;
|
|||||||
use Joomla\CMS\Factory;
|
use Joomla\CMS\Factory;
|
||||||
use Joomla\CMS\Form\Form;
|
use Joomla\CMS\Form\Form;
|
||||||
use Joomla\CMS\Plugin\CMSPlugin;
|
use Joomla\CMS\Plugin\CMSPlugin;
|
||||||
|
use Joomla\Event\Event;
|
||||||
use Joomla\Event\SubscriberInterface;
|
use Joomla\Event\SubscriberInterface;
|
||||||
|
|
||||||
final class MokoOGContent extends CMSPlugin implements SubscriberInterface
|
final class MokoOGContent extends CMSPlugin implements SubscriberInterface
|
||||||
@@ -45,7 +46,7 @@ final class MokoOGContent extends CMSPlugin implements SubscriberInterface
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onContentPrepareForm(\Joomla\Event\Event $event): void
|
public function onContentPrepareForm(Event $event): void
|
||||||
{
|
{
|
||||||
[$form, $data] = array_values($event->getArguments());
|
[$form, $data] = array_values($event->getArguments());
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ final class MokoOGContent extends CMSPlugin implements SubscriberInterface
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onContentAfterSave(\Joomla\Event\Event $event): void
|
public function onContentAfterSave(Event $event): void
|
||||||
{
|
{
|
||||||
[$context, $article, $isNew] = array_values($event->getArguments());
|
[$context, $article, $isNew] = array_values($event->getArguments());
|
||||||
|
|
||||||
@@ -109,10 +110,17 @@ final class MokoOGContent extends CMSPlugin implements SubscriberInterface
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only process saves from the admin HTTP interface where form data is available
|
||||||
|
$app = $this->getApplication();
|
||||||
|
|
||||||
|
if (!$app->isClient('administrator')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$contentType = $supportedContexts[$context];
|
$contentType = $supportedContexts[$context];
|
||||||
$contentId = (int) $article->id;
|
$contentId = (int) $article->id;
|
||||||
|
|
||||||
$input = $this->getApplication()->getInput();
|
$input = $app->getInput();
|
||||||
$jform = $input->get('jform', [], 'array');
|
$jform = $input->get('jform', [], 'array');
|
||||||
$ogData = $jform['mokoog'] ?? [];
|
$ogData = $jform['mokoog'] ?? [];
|
||||||
|
|
||||||
@@ -130,7 +138,7 @@ final class MokoOGContent extends CMSPlugin implements SubscriberInterface
|
|||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onContentAfterDelete(\Joomla\Event\Event $event): void
|
public function onContentAfterDelete(Event $event): void
|
||||||
{
|
{
|
||||||
[$context, $article] = array_values($event->getArguments());
|
[$context, $article] = array_values($event->getArguments());
|
||||||
|
|
||||||
@@ -168,7 +176,7 @@ final class MokoOGContent extends CMSPlugin implements SubscriberInterface
|
|||||||
{
|
{
|
||||||
$db = Factory::getDbo();
|
$db = Factory::getDbo();
|
||||||
$query = $db->getQuery(true)
|
$query = $db->getQuery(true)
|
||||||
->select('og_title, og_description, og_image, og_type')
|
->select($db->quoteName(['og_title', 'og_description', 'og_image', 'og_type']))
|
||||||
->from($db->quoteName('#__mokoog_tags'))
|
->from($db->quoteName('#__mokoog_tags'))
|
||||||
->where($db->quoteName('content_type') . ' = ' . $db->quote($contentType))
|
->where($db->quoteName('content_type') . ' = ' . $db->quote($contentType))
|
||||||
->where($db->quoteName('content_id') . ' = ' . $contentId);
|
->where($db->quoteName('content_id') . ' = ' . $contentId);
|
||||||
|
|||||||
@@ -19,8 +19,6 @@
|
|||||||
|
|
||||||
<namespace path="src">Joomla\Plugin\System\MokoOG</namespace>
|
<namespace path="src">Joomla\Plugin\System\MokoOG</namespace>
|
||||||
|
|
||||||
<scriptfile>script.php</scriptfile>
|
|
||||||
|
|
||||||
<files>
|
<files>
|
||||||
<filename plugin="mokoog">mokoog.php</filename>
|
<filename plugin="mokoog">mokoog.php</filename>
|
||||||
<folder>src</folder>
|
<folder>src</folder>
|
||||||
|
|||||||
@@ -14,15 +14,12 @@ defined('_JEXEC') or die;
|
|||||||
|
|
||||||
use Joomla\CMS\Factory;
|
use Joomla\CMS\Factory;
|
||||||
use Joomla\CMS\Plugin\CMSPlugin;
|
use Joomla\CMS\Plugin\CMSPlugin;
|
||||||
use Joomla\CMS\Router\Route;
|
|
||||||
use Joomla\CMS\Uri\Uri;
|
use Joomla\CMS\Uri\Uri;
|
||||||
use Joomla\Database\DatabaseAwareTrait;
|
use Joomla\Event\Event;
|
||||||
use Joomla\Event\SubscriberInterface;
|
use Joomla\Event\SubscriberInterface;
|
||||||
|
|
||||||
final class MokoOG extends CMSPlugin implements SubscriberInterface
|
final class MokoOG extends CMSPlugin implements SubscriberInterface
|
||||||
{
|
{
|
||||||
use DatabaseAwareTrait;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
@@ -43,9 +40,11 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface
|
|||||||
/**
|
/**
|
||||||
* Inject Open Graph and Twitter Card meta tags before the document head is compiled.
|
* Inject Open Graph and Twitter Card meta tags before the document head is compiled.
|
||||||
*
|
*
|
||||||
|
* @param Event $event The event object
|
||||||
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function onBeforeCompileHead(): void
|
public function onBeforeCompileHead(Event $event): void
|
||||||
{
|
{
|
||||||
$app = $this->getApplication();
|
$app = $this->getApplication();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user