Merge pull request 'feat(api): Joomla Web Services API for OG tags (#27)' (#29) from feature/27-webservices-api into dev
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 29s
Joomla: Repo Health / Release configuration (push) Has been cancelled
Joomla: Repo Health / Scripts governance (push) Has been cancelled
Joomla: Repo Health / Repository health (push) Has been cancelled
Joomla: Repo Health / Access control (push) Successful in 1s
Joomla: Update Server / Update updates.xml (push) Successful in 29s
Joomla: Repo Health / Release configuration (push) Has been cancelled
Joomla: Repo Health / Scripts governance (push) Has been cancelled
Joomla: Repo Health / Repository health (push) Has been cancelled
This commit was merged in pull request #29.
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoOpenGraph
|
||||
* @subpackage com_mokoog.api
|
||||
* @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\Api\Controller;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Controller\ApiController;
|
||||
|
||||
class TagsController extends ApiController
|
||||
{
|
||||
/**
|
||||
* The content type for JSON:API output.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $contentType = 'mokoogtags';
|
||||
|
||||
/**
|
||||
* The default view for the API.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $default_view = 'tags';
|
||||
|
||||
/**
|
||||
* Lookup an OG tag by content_type and content_id.
|
||||
*
|
||||
* GET /api/index.php/v1/mokoog/lookup/:content_type/:content_id
|
||||
*
|
||||
* @return static
|
||||
*/
|
||||
public function lookup(): static
|
||||
{
|
||||
$contentType = $this->input->getString('content_type', '');
|
||||
$contentId = $this->input->getInt('content_id', 0);
|
||||
|
||||
if (empty($contentType) || $contentId <= 0) {
|
||||
throw new \RuntimeException('content_type and content_id are required', 400);
|
||||
}
|
||||
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('id'))
|
||||
->from($db->quoteName('#__mokoog_tags'))
|
||||
->where($db->quoteName('content_type') . ' = ' . $db->quote($contentType))
|
||||
->where($db->quoteName('content_id') . ' = ' . $contentId);
|
||||
|
||||
$db->setQuery($query);
|
||||
$id = $db->loadResult();
|
||||
|
||||
if (!$id) {
|
||||
throw new \RuntimeException('OG tag not found for ' . $contentType . ':' . $contentId, 404);
|
||||
}
|
||||
|
||||
$this->input->set('id', $id);
|
||||
|
||||
return $this->displayItem();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoOpenGraph
|
||||
* @subpackage com_mokoog.api
|
||||
* @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\Api\View\Tags;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\MVC\View\JsonApiView as BaseApiView;
|
||||
|
||||
class JsonapiView extends BaseApiView
|
||||
{
|
||||
/**
|
||||
* The fields to render in the API response.
|
||||
*
|
||||
* Whitelist of fields from #__mokoog_tags that are safe to expose.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldsToRenderItem = [
|
||||
'id',
|
||||
'content_type',
|
||||
'content_id',
|
||||
'og_title',
|
||||
'og_description',
|
||||
'og_image',
|
||||
'og_type',
|
||||
'seo_title',
|
||||
'meta_description',
|
||||
'robots',
|
||||
'canonical_url',
|
||||
'language',
|
||||
'published',
|
||||
'created',
|
||||
'modified',
|
||||
];
|
||||
|
||||
/**
|
||||
* The fields to render in list responses.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fieldsToRenderList = [
|
||||
'id',
|
||||
'content_type',
|
||||
'content_id',
|
||||
'og_title',
|
||||
'og_description',
|
||||
'og_image',
|
||||
'og_type',
|
||||
'seo_title',
|
||||
'meta_description',
|
||||
'robots',
|
||||
'canonical_url',
|
||||
'language',
|
||||
'published',
|
||||
'created',
|
||||
'modified',
|
||||
];
|
||||
}
|
||||
@@ -69,4 +69,10 @@
|
||||
<menu link="option=com_mokoog&view=tags">COM_MOKOOG_SUBMENU_TAGS</menu>
|
||||
</submenu>
|
||||
</administration>
|
||||
|
||||
<api>
|
||||
<files folder="api">
|
||||
<folder>src</folder>
|
||||
</files>
|
||||
</api>
|
||||
</extension>
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
namespace Joomla\Component\MokoOG\Administrator\Model;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\MVC\Model\AdminModel;
|
||||
|
||||
class TagModel extends AdminModel
|
||||
{
|
||||
/**
|
||||
* Get the form for the item.
|
||||
*
|
||||
* @param array $data Form data
|
||||
* @param bool $loadData Load data from state
|
||||
*
|
||||
* @return \Joomla\CMS\Form\Form|false
|
||||
*/
|
||||
public function getForm($data = [], $loadData = true)
|
||||
{
|
||||
$form = $this->loadForm(
|
||||
'com_mokoog.tag',
|
||||
'tag',
|
||||
['control' => 'jform', 'load_data' => $loadData]
|
||||
);
|
||||
|
||||
return $form ?: false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the form data.
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
protected function loadFormData(): object
|
||||
{
|
||||
$data = Factory::getApplication()->getUserState('com_mokoog.edit.tag.data', []);
|
||||
|
||||
if (empty($data)) {
|
||||
$data = $this->getItem();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the table class name.
|
||||
*
|
||||
* @param string $name Table name
|
||||
* @param string $prefix Table prefix
|
||||
* @param array $options Table options
|
||||
*
|
||||
* @return \Joomla\CMS\Table\Table
|
||||
*/
|
||||
public function getTable($name = 'Tag', $prefix = 'Administrator', $options = [])
|
||||
{
|
||||
return parent::getTable($name, $prefix, $options);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
; MokoOpenGraph - Web Services Plugin Language File
|
||||
; Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; License: GPL-3.0-or-later
|
||||
|
||||
PLG_WEBSERVICES_MOKOOG="Web Services - MokoOpenGraph"
|
||||
@@ -0,0 +1,6 @@
|
||||
; MokoOpenGraph - Web Services Plugin System Language File
|
||||
; Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; License: GPL-3.0-or-later
|
||||
|
||||
PLG_WEBSERVICES_MOKOOG="Web Services - MokoOpenGraph"
|
||||
PLG_WEBSERVICES_MOKOOG_DESCRIPTION="Exposes MokoOpenGraph OG tag data via Joomla's REST API at /api/index.php/v1/mokoog/tags."
|
||||
@@ -0,0 +1,5 @@
|
||||
; MokoOpenGraph - Web Services Plugin Language File
|
||||
; Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; License: GPL-3.0-or-later
|
||||
|
||||
PLG_WEBSERVICES_MOKOOG="Web Services - MokoOpenGraph"
|
||||
@@ -0,0 +1,6 @@
|
||||
; MokoOpenGraph - Web Services Plugin System Language File
|
||||
; Copyright (C) 2026 Moko Consulting. All rights reserved.
|
||||
; License: GPL-3.0-or-later
|
||||
|
||||
PLG_WEBSERVICES_MOKOOG="Web Services - MokoOpenGraph"
|
||||
PLG_WEBSERVICES_MOKOOG_DESCRIPTION="Exposes MokoOpenGraph OG tag data via Joomla's REST API at /api/index.php/v1/mokoog/tags."
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoOpenGraph
|
||||
* @subpackage plg_webservices_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
|
||||
*
|
||||
* Legacy entry point — not executed under DI container.
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
|
||||
class PlgWebservicesMokoog extends CMSPlugin
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
* @package MokoOpenGraph
|
||||
* @subpackage plg_webservices_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
|
||||
-->
|
||||
<extension type="plugin" group="webservices" method="upgrade">
|
||||
<name>Web Services - MokoOpenGraph</name>
|
||||
<version>01.00.00</version>
|
||||
<creationDate>2026-05-23</creationDate>
|
||||
<author>Moko Consulting</author>
|
||||
<authorEmail>hello@mokoconsulting.tech</authorEmail>
|
||||
<authorUrl>https://mokoconsulting.tech</authorUrl>
|
||||
<copyright>Copyright (C) 2026 Moko Consulting. All rights reserved.</copyright>
|
||||
<license>GPL-3.0-or-later</license>
|
||||
<description>PLG_WEBSERVICES_MOKOOG_DESCRIPTION</description>
|
||||
|
||||
<namespace path="src">Joomla\Plugin\WebServices\MokoOG</namespace>
|
||||
|
||||
<files>
|
||||
<filename plugin="mokoog">mokoog.php</filename>
|
||||
<folder>src</folder>
|
||||
<folder>services</folder>
|
||||
<folder>language</folder>
|
||||
</files>
|
||||
|
||||
<languages>
|
||||
<language tag="en-GB">language/en-GB/plg_webservices_mokoog.ini</language>
|
||||
<language tag="en-GB">language/en-GB/plg_webservices_mokoog.sys.ini</language>
|
||||
</languages>
|
||||
</extension>
|
||||
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoOpenGraph
|
||||
* @subpackage plg_webservices_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
|
||||
*/
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Extension\PluginInterface;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Plugin\PluginHelper;
|
||||
use Joomla\DI\Container;
|
||||
use Joomla\DI\ServiceProviderInterface;
|
||||
use Joomla\Event\DispatcherInterface;
|
||||
use Joomla\Plugin\WebServices\MokoOG\Extension\MokoOGWebServices;
|
||||
|
||||
return new class () implements ServiceProviderInterface {
|
||||
/**
|
||||
* Register the service provider.
|
||||
*
|
||||
* @param Container $container The DI container
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register(Container $container): void
|
||||
{
|
||||
$container->set(
|
||||
PluginInterface::class,
|
||||
function (Container $container) {
|
||||
$plugin = new MokoOGWebServices(
|
||||
$container->get(DispatcherInterface::class),
|
||||
(array) PluginHelper::getPlugin('webservices', 'mokoog')
|
||||
);
|
||||
$plugin->setApplication(Factory::getApplication());
|
||||
|
||||
return $plugin;
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package MokoOpenGraph
|
||||
* @subpackage plg_webservices_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\Plugin\WebServices\MokoOG\Extension;
|
||||
|
||||
defined('_JEXEC') or die;
|
||||
|
||||
use Joomla\CMS\Plugin\CMSPlugin;
|
||||
use Joomla\CMS\Router\ApiRouter;
|
||||
use Joomla\Event\Event;
|
||||
use Joomla\Event\SubscriberInterface;
|
||||
use Joomla\Router\Route;
|
||||
|
||||
final class MokoOGWebServices extends CMSPlugin implements SubscriberInterface
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $autoloadLanguage = true;
|
||||
|
||||
/**
|
||||
* Returns the events this plugin subscribes to.
|
||||
*
|
||||
* @return array<string, string>
|
||||
*/
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
'onBeforeApiRoute' => 'onBeforeApiRoute',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register API routes for MokoOpenGraph.
|
||||
*
|
||||
* Endpoints:
|
||||
* GET /api/index.php/v1/mokoog/tags - List all OG tags
|
||||
* GET /api/index.php/v1/mokoog/tags/:id - Get single OG tag
|
||||
* POST /api/index.php/v1/mokoog/tags - Create OG tag
|
||||
* PATCH /api/index.php/v1/mokoog/tags/:id - Update OG tag
|
||||
* DELETE /api/index.php/v1/mokoog/tags/:id - Delete OG tag
|
||||
*
|
||||
* @param Event $event The event object
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function onBeforeApiRoute(Event $event): void
|
||||
{
|
||||
[$router] = array_values($event->getArguments());
|
||||
|
||||
$defaults = [
|
||||
'component' => 'com_mokoog',
|
||||
'public' => false,
|
||||
];
|
||||
|
||||
// CRUD routes for OG tags
|
||||
$router->createCRUDRoutes(
|
||||
'v1/mokoog/tags',
|
||||
'tags',
|
||||
$defaults
|
||||
);
|
||||
|
||||
// GET by content type + content ID (lookup endpoint)
|
||||
$router->addRoute(
|
||||
new Route(
|
||||
['GET'],
|
||||
'v1/mokoog/lookup/:content_type/:content_id',
|
||||
'tags.lookup',
|
||||
['content_type' => '[a-z_.]+', 'content_id' => '(\d+)'],
|
||||
$defaults
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
<file type="component" id="com_mokoog">com_mokoog.zip</file>
|
||||
<file type="plugin" id="mokoog" group="system">plg_system_mokoog.zip</file>
|
||||
<file type="plugin" id="mokoog" group="content">plg_content_mokoog.zip</file>
|
||||
<file type="plugin" id="mokoog" group="webservices">plg_webservices_mokoog.zip</file>
|
||||
</files>
|
||||
|
||||
<languages>
|
||||
|
||||
@@ -73,6 +73,17 @@ class Pkg_MokoOGInstallerScript
|
||||
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
// Enable the webservices plugin automatically
|
||||
$query = $db->getQuery(true)
|
||||
->update($db->quoteName('#__extensions'))
|
||||
->set($db->quoteName('enabled') . ' = 1')
|
||||
->where($db->quoteName('type') . ' = ' . $db->quote('plugin'))
|
||||
->where($db->quoteName('folder') . ' = ' . $db->quote('webservices'))
|
||||
->where($db->quoteName('element') . ' = ' . $db->quote('mokoog'));
|
||||
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user