fix: resolve 3 v1.0 release blockers (#47, #48, #39)

- Add TagsController extending AdminController for admin list
  delete/publish/unpublish operations (#48)
- Add language filter to loadOgDataByType() and loadOgDataByMenu()
  matching the pattern already used in loadOgData() (#47)
- Replace direct $doc->_links access with getHeadData()/setHeadData()
  public API for Joomla forward compatibility (#39)
- Update ISSUES.md with full 2026-06-21 assessment
This commit is contained in:
Jonathan Miller
2026-06-21 10:02:03 -05:00
parent a67cd6da76
commit 433ecfea71
3 changed files with 380 additions and 13 deletions
@@ -0,0 +1,33 @@
<?php
/**
* @package MokoSuiteOpenGraph
* @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
*/
namespace Joomla\Component\MokoOG\Administrator\Controller;
defined('_JEXEC') or die;
use Joomla\CMS\MVC\Controller\AdminController;
use Joomla\CMS\MVC\Model\BaseDatabaseModel;
class TagsController extends AdminController
{
/**
* Proxy for getModel.
*
* @param string $name Model name
* @param string $prefix Model prefix
* @param array $config Configuration array
*
* @return BaseDatabaseModel
*/
public function getModel($name = 'Tag', $prefix = 'Administrator', $config = ['ignore_request' => true])
{
return parent::getModel($name, $prefix, $config);
}
}
@@ -1,7 +1,7 @@
<?php
/**
* @package MokoJoomOpenGraph
* @package MokoSuiteOpenGraph
* @subpackage plg_system_mokoog
* @author Moko Consulting <hello@mokoconsulting.tech>
* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved.
@@ -253,11 +253,17 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface
// Canonical URL
if (!empty($ogData->canonical_url)) {
// Remove any existing canonical link first
foreach ($doc->_links as $link => $attribs) {
if (isset($attribs['relation']) && $attribs['relation'] === 'canonical') {
unset($doc->_links[$link]);
// Remove any existing canonical link via public API
$headData = $doc->getHeadData();
if (!empty($headData['links'])) {
foreach ($headData['links'] as $link => $attribs) {
if (isset($attribs['relation']) && $attribs['relation'] === 'canonical') {
unset($headData['links'][$link]);
}
}
$doc->setHeadData($headData);
}
$doc->addHeadLink($ogData->canonical_url, 'canonical');
@@ -323,15 +329,20 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface
*/
private function loadOgDataByType(string $contentType, int $contentId): ?object
{
$db = Factory::getDbo();
$db = Factory::getDbo();
$lang = Factory::getLanguage()->getTag();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__mokoog_tags'))
->where($db->quoteName('content_type') . ' = ' . $db->quote($contentType))
->where($db->quoteName('content_id') . ' = ' . $contentId)
->where($db->quoteName('published') . ' = 1');
->where($db->quoteName('published') . ' = 1')
->where('(' . $db->quoteName('language') . ' = ' . $db->quote($lang)
. ' OR ' . $db->quoteName('language') . ' = ' . $db->quote('*') . ')')
->order('CASE WHEN ' . $db->quoteName('language') . ' = ' . $db->quote('*') . ' THEN 1 ELSE 0 END ASC');
$db->setQuery($query);
$db->setQuery($query, 0, 1);
return $db->loadObject();
}
@@ -345,15 +356,20 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface
*/
private function loadOgDataByMenu(int $menuId): ?object
{
$db = Factory::getDbo();
$db = Factory::getDbo();
$lang = Factory::getLanguage()->getTag();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__mokoog_tags'))
->where($db->quoteName('content_type') . ' = ' . $db->quote('menu'))
->where($db->quoteName('content_id') . ' = ' . $menuId)
->where($db->quoteName('published') . ' = 1');
->where($db->quoteName('published') . ' = 1')
->where('(' . $db->quoteName('language') . ' = ' . $db->quote($lang)
. ' OR ' . $db->quoteName('language') . ' = ' . $db->quote('*') . ')')
->order('CASE WHEN ' . $db->quoteName('language') . ' = ' . $db->quote('*') . ' THEN 1 ELSE 0 END ASC');
$db->setQuery($query);
$db->setQuery($query, 0, 1);
return $db->loadObject();
}
@@ -534,7 +550,7 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface
$query = $db->getQuery(true)
->select($db->quoteName('extra_query'))
->from($db->quoteName('#__update_sites'))
->where($db->quoteName('name') . ' = ' . $db->quote('MokoJoomOpenGraph Updates'))
->where($db->quoteName('name') . ' = ' . $db->quote('MokoSuiteOpenGraph Updates'))
->setLimit(1);
$db->setQuery($query);
$extraQuery = (string) $db->loadResult();
@@ -555,7 +571,7 @@ final class MokoOG extends CMSPlugin implements SubscriberInterface
. 'No download key is configured. Updates will not be available until a valid license key is entered. '
. 'Go to <a href="index.php?option=com_installer&view=updatesites">System → Update Sites</a> '
. 'and enter your license key (<code>MOKO-XXXX-XXXX-XXXX-XXXX</code>) in the Download Key field '
. 'for the MokoJoomOpenGraph update site.',
. 'for the MokoSuiteOpenGraph update site.',
'warning'
);
} catch (\Throwable $e) {