diff --git a/src/packages/com_mokoog/api/src/Controller/TagsController.php b/src/packages/com_mokoog/api/src/Controller/TagsController.php new file mode 100644 index 0000000..e0d895f --- /dev/null +++ b/src/packages/com_mokoog/api/src/Controller/TagsController.php @@ -0,0 +1,68 @@ + + * @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(); + } +} diff --git a/src/packages/com_mokoog/api/src/View/Tags/JsonapiView.php b/src/packages/com_mokoog/api/src/View/Tags/JsonapiView.php new file mode 100644 index 0000000..c103df2 --- /dev/null +++ b/src/packages/com_mokoog/api/src/View/Tags/JsonapiView.php @@ -0,0 +1,66 @@ + + * @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', + ]; +} diff --git a/src/packages/com_mokoog/mokoog.xml b/src/packages/com_mokoog/mokoog.xml index aa2ad47..f5baeb3 100644 --- a/src/packages/com_mokoog/mokoog.xml +++ b/src/packages/com_mokoog/mokoog.xml @@ -69,4 +69,10 @@ COM_MOKOOG_SUBMENU_TAGS + + + + src + + diff --git a/src/packages/com_mokoog/src/Model/TagModel.php b/src/packages/com_mokoog/src/Model/TagModel.php new file mode 100644 index 0000000..62d14b9 --- /dev/null +++ b/src/packages/com_mokoog/src/Model/TagModel.php @@ -0,0 +1,68 @@ + + * @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); + } +} diff --git a/src/packages/plg_webservices_mokoog/language/en-GB/plg_webservices_mokoog.ini b/src/packages/plg_webservices_mokoog/language/en-GB/plg_webservices_mokoog.ini new file mode 100644 index 0000000..e397923 --- /dev/null +++ b/src/packages/plg_webservices_mokoog/language/en-GB/plg_webservices_mokoog.ini @@ -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" diff --git a/src/packages/plg_webservices_mokoog/language/en-GB/plg_webservices_mokoog.sys.ini b/src/packages/plg_webservices_mokoog/language/en-GB/plg_webservices_mokoog.sys.ini new file mode 100644 index 0000000..903c909 --- /dev/null +++ b/src/packages/plg_webservices_mokoog/language/en-GB/plg_webservices_mokoog.sys.ini @@ -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." diff --git a/src/packages/plg_webservices_mokoog/language/en-US/plg_webservices_mokoog.ini b/src/packages/plg_webservices_mokoog/language/en-US/plg_webservices_mokoog.ini new file mode 100644 index 0000000..e397923 --- /dev/null +++ b/src/packages/plg_webservices_mokoog/language/en-US/plg_webservices_mokoog.ini @@ -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" diff --git a/src/packages/plg_webservices_mokoog/language/en-US/plg_webservices_mokoog.sys.ini b/src/packages/plg_webservices_mokoog/language/en-US/plg_webservices_mokoog.sys.ini new file mode 100644 index 0000000..903c909 --- /dev/null +++ b/src/packages/plg_webservices_mokoog/language/en-US/plg_webservices_mokoog.sys.ini @@ -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." diff --git a/src/packages/plg_webservices_mokoog/mokoog.php b/src/packages/plg_webservices_mokoog/mokoog.php new file mode 100644 index 0000000..899de00 --- /dev/null +++ b/src/packages/plg_webservices_mokoog/mokoog.php @@ -0,0 +1,19 @@ + + * @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 +{ +} diff --git a/src/packages/plg_webservices_mokoog/mokoog.xml b/src/packages/plg_webservices_mokoog/mokoog.xml new file mode 100644 index 0000000..5f862ab --- /dev/null +++ b/src/packages/plg_webservices_mokoog/mokoog.xml @@ -0,0 +1,33 @@ + + + + Web Services - MokoOpenGraph + 01.00.00 + 2026-05-23 + Moko Consulting + hello@mokoconsulting.tech + https://mokoconsulting.tech + Copyright (C) 2026 Moko Consulting. All rights reserved. + GPL-3.0-or-later + PLG_WEBSERVICES_MOKOOG_DESCRIPTION + + Joomla\Plugin\WebServices\MokoOG + + + mokoog.php + src + services + language + + + + language/en-GB/plg_webservices_mokoog.ini + language/en-GB/plg_webservices_mokoog.sys.ini + + diff --git a/src/packages/plg_webservices_mokoog/services/provider.php b/src/packages/plg_webservices_mokoog/services/provider.php new file mode 100644 index 0000000..2aa760d --- /dev/null +++ b/src/packages/plg_webservices_mokoog/services/provider.php @@ -0,0 +1,44 @@ + + * @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; + } + ); + } +}; diff --git a/src/packages/plg_webservices_mokoog/src/Extension/MokoOGWebServices.php b/src/packages/plg_webservices_mokoog/src/Extension/MokoOGWebServices.php new file mode 100644 index 0000000..887e3b8 --- /dev/null +++ b/src/packages/plg_webservices_mokoog/src/Extension/MokoOGWebServices.php @@ -0,0 +1,81 @@ + + * @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 + */ + 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 + ) + ); + } +} diff --git a/src/pkg_mokoog.xml b/src/pkg_mokoog.xml index 355f556..783c779 100644 --- a/src/pkg_mokoog.xml +++ b/src/pkg_mokoog.xml @@ -23,6 +23,7 @@ com_mokoog.zip plg_system_mokoog.zip plg_content_mokoog.zip + plg_webservices_mokoog.zip diff --git a/src/script.php b/src/script.php index c5a505f..0d173ba 100644 --- a/src/script.php +++ b/src/script.php @@ -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(); } } }