diff --git a/administrator/components/com_admin/sql/updates/mysql/5.1.0-2024-02-25.sql b/administrator/components/com_admin/sql/updates/mysql/5.1.0-2024-02-25.sql new file mode 100644 index 0000000000000..d1f08f1cd2e60 --- /dev/null +++ b/administrator/components/com_admin/sql/updates/mysql/5.1.0-2024-02-25.sql @@ -0,0 +1,2 @@ +INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, `client_id`, `enabled`, `access`, `protected`, `locked`, `manifest_cache`, `params`, `custom_data`, `ordering`, `state`) VALUES +(0, 'plg_schemaorg_custom', 'plugin', 'custom', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 0, 0); diff --git a/administrator/components/com_admin/sql/updates/postgresql/5.1.0-2024-02-25.sql b/administrator/components/com_admin/sql/updates/postgresql/5.1.0-2024-02-25.sql new file mode 100644 index 0000000000000..665ac55ee84ff --- /dev/null +++ b/administrator/components/com_admin/sql/updates/postgresql/5.1.0-2024-02-25.sql @@ -0,0 +1,2 @@ +INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", "client_id", "enabled", "access", "protected", "locked", "manifest_cache", "params", "custom_data", "ordering", "state") VALUES +(0, 'plg_schemaorg_custom', 'plugin', 'custom', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 0, 0); diff --git a/administrator/language/en-GB/plg_schemaorg_custom.ini b/administrator/language/en-GB/plg_schemaorg_custom.ini new file mode 100755 index 0000000000000..26431d79293ce --- /dev/null +++ b/administrator/language/en-GB/plg_schemaorg_custom.ini @@ -0,0 +1,10 @@ +; Joomla! Project +; (C) 2024 Open Source Matters, Inc. +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SCHEMAORG_CUSTOM="Schema.org - Custom" +PLG_SCHEMAORG_CUSTOM_XML_DESCRIPTION="Adds a custom field to add any schema type." +PLG_SCHEMAORG_CUSTOM_DESCRIPTION_LABEL="Use any JSON-LD code here to add currently unsupported schema types." +PLG_SCHEMAORG_CUSTOM_JSON_ERROR="The JSON code is not valid or @context or @type is missing." +PLG_SCHEMAORG_CUSTOM_JSON_FIELD_LABEL="JSON Code" diff --git a/administrator/language/en-GB/plg_schemaorg_custom.sys.ini b/administrator/language/en-GB/plg_schemaorg_custom.sys.ini new file mode 100755 index 0000000000000..69568f944c3ef --- /dev/null +++ b/administrator/language/en-GB/plg_schemaorg_custom.sys.ini @@ -0,0 +1,8 @@ +; Joomla! Project +; (C) 2024 Open Source Matters, Inc. + +; License GNU General Public License version 2 or later; see LICENSE.txt +; Note : All ini files need to be saved as UTF-8 + +PLG_SCHEMAORG_CUSTOM="Schema.org - Custom" +PLG_SCHEMAORG_CUSTOM_XML_DESCRIPTION="Adds a custom field to add any schema type." diff --git a/installation/sql/mysql/base.sql b/installation/sql/mysql/base.sql index c34c49dd41e0a..4a54aee554c09 100644 --- a/installation/sql/mysql/base.sql +++ b/installation/sql/mysql/base.sql @@ -341,6 +341,7 @@ INSERT INTO `#__extensions` (`package_id`, `name`, `type`, `element`, `folder`, (0, 'plg_schemaorg_organization', 'plugin', 'organization', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 6, 0), (0, 'plg_schemaorg_person', 'plugin', 'person', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 7, 0), (0, 'plg_schemaorg_recipe', 'plugin', 'recipe', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 8, 0), +(0, 'plg_schemaorg_custom', 'plugin', 'custom', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 9, 0), (0, 'plg_system_accessibility', 'plugin', 'accessibility', 'system', 0, 0, 1, 0, 1, '', '{}', '', 1, 0), (0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 1, 1, 0, 1, '', '{}', '', 2, 0), (0, 'plg_system_cache', 'plugin', 'cache', 'system', 0, 0, 1, 0, 1, '', '{"browsercache":"0","cachetime":"15"}', '', 3, 0), diff --git a/installation/sql/postgresql/base.sql b/installation/sql/postgresql/base.sql index 435afc0ee2112..57493f9568d90 100644 --- a/installation/sql/postgresql/base.sql +++ b/installation/sql/postgresql/base.sql @@ -347,6 +347,7 @@ INSERT INTO "#__extensions" ("package_id", "name", "type", "element", "folder", (0, 'plg_schemaorg_organization', 'plugin', 'organization', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 6, 0), (0, 'plg_schemaorg_person', 'plugin', 'person', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 7, 0), (0, 'plg_schemaorg_recipe', 'plugin', 'recipe', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 8, 0), +(0, 'plg_schemaorg_custom', 'plugin', 'custom', 'schemaorg', 0, 1, 1, 0, 0, '', '{}', '', 9, 0), (0, 'plg_system_accessibility', 'plugin', 'accessibility', 'system', 0, 0, 1, 0, 1, '', '{}', '', 1, 0), (0, 'plg_system_actionlogs', 'plugin', 'actionlogs', 'system', 0, 1, 1, 0, 1, '', '{}', '', 2, 0), (0, 'plg_system_cache', 'plugin', 'cache', 'system', 0, 0, 1, 0, 1, '', '{"browsercache":"0","cachetime":"15"}', '', 3, 0), diff --git a/libraries/src/Extension/ExtensionHelper.php b/libraries/src/Extension/ExtensionHelper.php index f74d6bed987e9..752c51f24bc9b 100644 --- a/libraries/src/Extension/ExtensionHelper.php +++ b/libraries/src/Extension/ExtensionHelper.php @@ -280,6 +280,7 @@ class ExtensionHelper ['plugin', 'article', 'schemaorg', 0], ['plugin', 'blogposting', 'schemaorg', 0], ['plugin', 'book', 'schemaorg', 0], + ['plugin', 'custom', 'schemaorg', 0], ['plugin', 'event', 'schemaorg', 0], ['plugin', 'jobposting', 'schemaorg', 0], ['plugin', 'organization', 'schemaorg', 0], diff --git a/plugins/schemaorg/custom/custom.xml b/plugins/schemaorg/custom/custom.xml new file mode 100755 index 0000000000000..b9794ae30b4cd --- /dev/null +++ b/plugins/schemaorg/custom/custom.xml @@ -0,0 +1,43 @@ + + + plg_schemaorg_custom + Joomla! Project + 2024-01 + (C) 2024 Open Source Matters, Inc. + GNU General Public License version 2 or later; see LICENSE.txt + admin@joomla.org + www.joomla.org + __DEPLOY_VERSION__ + PLG_SCHEMAORG_CUSTOM_XML_DESCRIPTION + Joomla\Plugin\Schemaorg\Custom + + services + src + + + language/en-GB/plg_schemaorg_custom.ini + language/en-GB/plg_schemaorg_custom.sys.ini + + + +
+ + +
+
+
+
diff --git a/plugins/schemaorg/custom/forms/schemaorg.xml b/plugins/schemaorg/custom/forms/schemaorg.xml new file mode 100755 index 0000000000000..ed5dcff482a71 --- /dev/null +++ b/plugins/schemaorg/custom/forms/schemaorg.xml @@ -0,0 +1,39 @@ + +
+ +
+ + + + + + + + + + + +
+
+ diff --git a/plugins/schemaorg/custom/services/provider.php b/plugins/schemaorg/custom/services/provider.php new file mode 100644 index 0000000000000..ffb9e1767bcbd --- /dev/null +++ b/plugins/schemaorg/custom/services/provider.php @@ -0,0 +1,48 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +\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\Schemaorg\Custom\Extension\Custom; + +return new class () implements ServiceProviderInterface { + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function register(Container $container) + { + $container->set( + PluginInterface::class, + function (Container $container) { + $dispatcher = $container->get(DispatcherInterface::class); + $plugin = new Custom( + $dispatcher, + (array) PluginHelper::getPlugin('schemaorg', 'custom') + ); + + $plugin->setApplication(Factory::getApplication()); + + return $plugin; + } + ); + } +}; diff --git a/plugins/schemaorg/custom/src/Extension/Custom.php b/plugins/schemaorg/custom/src/Extension/Custom.php new file mode 100755 index 0000000000000..73335ead2efa3 --- /dev/null +++ b/plugins/schemaorg/custom/src/Extension/Custom.php @@ -0,0 +1,127 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\Plugin\Schemaorg\Custom\Extension; + +use Joomla\CMS\Event\Plugin\System\Schemaorg\BeforeCompileHeadEvent; +use Joomla\CMS\Event\Plugin\System\Schemaorg\PrepareSaveEvent; +use Joomla\CMS\Language\Text; +use Joomla\CMS\Plugin\CMSPlugin; +use Joomla\CMS\Schemaorg\SchemaorgPluginTrait; +use Joomla\Event\Priority; +use Joomla\Event\SubscriberInterface; +use Joomla\Registry\Registry; + +// phpcs:disable PSR1.Files.SideEffects +\defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Schemaorg Plugin + * + * @since __DEPLOY_VERSION__ + */ +final class Custom extends CMSPlugin implements SubscriberInterface +{ + use SchemaorgPluginTrait; + + /** + * Load the language file on instantiation. + * + * @var boolean + * @since __DEPLOY_VERSION__ + */ + protected $autoloadLanguage = true; + + /** + * The name of the schema form + * + * @var string + * @since __DEPLOY_VERSION__ + */ + protected $pluginName = 'Custom'; + + /** + * Returns an array of events this subscriber will listen to. + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public static function getSubscribedEvents(): array + { + return [ + 'onSchemaPrepareForm' => 'onSchemaPrepareForm', + 'onSchemaBeforeCompileHead' => ['onSchemaBeforeCompileHead', Priority::BELOW_NORMAL], + 'onSchemaPrepareSave' => 'onSchemaPrepareSave', + ]; + } + + public function onSchemaPrepareSave(PrepareSaveEvent $event): void + { + $subject = $event->getData(); + + if (empty($subject->schemaType) || $subject->schemaType !== 'Custom' || !isset($subject->schema)) { + return; + } + + try { + $schema = new Registry($subject->schema); + + $json = (new Registry($schema->get('json')))->toArray(); + } catch (\RuntimeException $e) { + $this->getApplication()->enqueueMessage(Text::_('PLG_SCHEMAORG_CUSTOM_JSON_ERROR'), 'error'); + return; + } + + if (!isset($json['@context']) || !preg_match('#^https://schema.org/?$#', $json['@context']) || !isset($json['@type'])) { + $this->getApplication()->enqueueMessage(Text::_('PLG_SCHEMAORG_CUSTOM_JSON_ERROR'), 'error'); + return; + } + + $schema->set('json', json_encode($json, JSON_PRETTY_PRINT)); + + $subject->schema = $schema->toString(); + + $event->setArgument('subject', $subject); + } + + /** + * Cleanup all Custom types + * + * @param BeforeCompileHeadEvent $event The given event + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function onSchemaBeforeCompileHead(BeforeCompileHeadEvent $event): void + { + $schema = $event->getSchema(); + + $graph = $schema->get('@graph'); + + foreach ($graph as $i => $entry) { + if (!isset($entry['@type']) || $entry['@type'] !== 'Custom') { + continue; + } + + $json = (new Registry($entry['json']))->toArray(); + + if (isset($json['@context'])) { + unset($json['@context']); + } + + $graph[$i] = $json; + } + + $schema->set('@graph', $graph); + } +}