Release of v4.0.2-beta4

Add native plugin builder for Joomla 4 & 5.
This commit is contained in:
Robot 2024-08-15 01:36:43 +02:00
parent ae1c89a15d
commit 277d6e8355
Signed by: Robot
GPG Key ID: 14DECD44E7E1BB95
80 changed files with 10883 additions and 2136 deletions

View File

@ -1,11 +1,12 @@
# v4.0.2-beta3
# v4.0.2-beta4
- Add more pure JS to the dynamic get area.
- Add native plugin builder for Joomla 4 & 5
# v4.0.2-beta
- Fix abstract schema class function check default index warring
- Fix dynamicGet so that the table values will load again. #1155
- Fix dynamicGet so that the table values will load again. #1155
- Add more pure JS to the dynamic get area
# v4.0.2-alpha

View File

@ -3270,7 +3270,7 @@ class Com_ComponentbuilderInstallerScript implements InstallerScriptInterface
echo '<div style="background-color: #fff;" class="alert alert-info"><a target="_blank" href="https://dev.vdm.io" title="Component Builder">
<img src="components/com_componentbuilder/assets/images/vdm-component.jpg"/>
</a>
<h3>Upgrade to Version 4.0.2-beta3 Was Successful! Let us know if anything is not working as expected.</h3></div>';
<h3>Upgrade to Version 4.0.2-beta4 Was Successful! Let us know if anything is not working as expected.</h3></div>';
// Add/Update component in the action logs extensions table.
$this->setActionLogsExtensions();

View File

@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo
Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have!
You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (4.0.2-beta3) with **ALL** its features and **ALL** concepts totally open-source and free!
You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (4.0.2-beta4) with **ALL** its features and **ALL** concepts totally open-source and free!
> Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45)
@ -144,14 +144,14 @@ TODO
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
+ *First Build*: 30th April, 2015
+ *Last Build*: 1st August, 2024
+ *Version*: 4.0.2-beta3
+ *Last Build*: 14th August, 2024
+ *Version*: 4.0.2-beta4
+ *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved.
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
+ *Line count*: **791544**
+ *Line count*: **823989**
+ *Field count*: **2093**
+ *File count*: **5505**
+ *Folder count*: **544**
+ *File count*: **5734**
+ *Folder count*: **606**
> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](https://www.joomlacomponentbuilder.com).
> Developed by [Llewellyn van der Merwe](mailto:joomla@vdm.io)

View File

@ -9,7 +9,7 @@ The Component Builder for [Joomla](https://extensions.joomla.org/extension/compo
Whether you're a seasoned [Joomla](https://extensions.joomla.org/extension/component-builder/) developer, or have just started, Component Builder will save you lots of time and money. A real must have!
You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (4.0.2-beta3) with **ALL** its features and **ALL** concepts totally open-source and free!
You can install it quite easily and with no limitations. On [gitea](https://git.vdm.dev/joomla/Component-Builder/tags) is the latest release (4.0.2-beta4) with **ALL** its features and **ALL** concepts totally open-source and free!
> Watch Quick Build of a Hello World component in [JCB on Youtube](https://www.youtube.com/watch?v=IQfsLYIeblk&list=PLQRGFI8XZ_wtGvPQZWBfDzzlERLQgpMRE&index=45)
@ -144,14 +144,14 @@ TODO
+ *Author*: [Llewellyn van der Merwe](mailto:joomla@vdm.io)
+ *Name*: [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
+ *First Build*: 30th April, 2015
+ *Last Build*: 1st August, 2024
+ *Version*: 4.0.2-beta3
+ *Last Build*: 14th August, 2024
+ *Version*: 4.0.2-beta4
+ *Copyright*: Copyright (C) 2015 Vast Development Method. All rights reserved.
+ *License*: GNU General Public License version 2 or later; see LICENSE.txt
+ *Line count*: **791544**
+ *Line count*: **823989**
+ *Field count*: **2093**
+ *File count*: **5505**
+ *Folder count*: **544**
+ *File count*: **5734**
+ *Folder count*: **606**
> This **component** was build with a [Joomla](https://extensions.joomla.org/extension/component-builder/) [Automated Component Builder](https://www.joomlacomponentbuilder.com).
> Developed by [Llewellyn van der Merwe](mailto:joomla@vdm.io)

View File

@ -1027,9 +1027,9 @@
<option value="2">
COM_COMPONENTBUILDER_CONFIG_REMOTE_SERVER</option>
</field>
<!-- Cronjob_backup_server Field. Type: Servers. (custom) -->
<!-- Cronjob_backup_server Field. Type: Cron_servers. (custom) -->
<field
type="servers"
type="cron_servers"
name="cronjob_backup_server"
label="COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_SERVER_LABEL"
description="COM_COMPONENTBUILDER_CONFIG_CRONJOB_BACKUP_SERVER_DESCRIPTION"

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,175 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 30th April, 2015
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Component\Componentbuilder\Administrator\Field;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Field\ListField;
use Joomla\CMS\Language\Text;
use Joomla\CMS\HTML\HTMLHelper as Html;
use Joomla\CMS\Component\ComponentHelper;
use VDM\Component\Componentbuilder\Administrator\Helper\ComponentbuilderHelper;
// No direct access to this file
\defined('_JEXEC') or die;
/**
* Cron_servers Form Field class for the Componentbuilder component
*
* @since 1.6
*/
class Cron_serversField extends ListField
{
/**
* The cron_servers field type.
*
* @var string
*/
public $type = 'Cron_servers';
/**
* Override to add new button
*
* @return string The field input markup.
*
* @since 3.2
*/
protected function getInput()
{
// see if we should add buttons
$set_button = $this->getAttribute('button');
// get html
$html = parent::getInput();
// if true set button
if ($set_button === 'true')
{
$button = array();
$script = array();
$button_code_name = $this->getAttribute('name');
// get the input from url
$app = Factory::getApplication();
$jinput = $app->input;
// get the view name & id
$values = $jinput->getArray(array(
'id' => 'int',
'view' => 'word'
));
// check if new item
$ref = '';
$refJ = '';
if (!is_null($values['id']) && strlen($values['view']))
{
// only load referral if not new item.
$ref = '&amp;ref=' . $values['view'] . '&amp;refid=' . $values['id'];
$refJ = '&ref=' . $values['view'] . '&refid=' . $values['id'];
// get the return value.
$_uri = (string) \Joomla\CMS\Uri\Uri::getInstance();
$_return = urlencode(base64_encode($_uri));
// load return value.
$ref .= '&amp;return=' . $_return;
$refJ .= '&return=' . $_return;
}
// get button label
$button_label = trim($button_code_name);
$button_label = preg_replace('/_+/', ' ', $button_label);
$button_label = preg_replace('/\s+/', ' ', $button_label);
$button_label = preg_replace("/[^A-Za-z ]/", '', $button_label);
$button_label = ucfirst(strtolower($button_label));
// get user object
$user = Factory::getApplication()->getIdentity();
// only add if user allowed to create server
if ($user->authorise('server.create', 'com_componentbuilder') && $app->isClient('administrator')) // TODO for now only in admin area.
{
// build Create button
$button[] = '<a id="'.$button_code_name.'Create" class="btn btn-small btn-success hasTooltip" title="'.Text::sprintf('COM_COMPONENTBUILDER_CREATE_NEW_S', $button_label).'" style="border-radius: 0px 4px 4px 0px;"
href="index.php?option=com_componentbuilder&amp;view=server&amp;layout=edit'.$ref.'" >
<span class="icon-new icon-white"></span></a>';
}
// only add if user allowed to edit server
if ($user->authorise('server.edit', 'com_componentbuilder') && $app->isClient('administrator')) // TODO for now only in admin area.
{
// build edit button
$button[] = '<a id="'.$button_code_name.'Edit" class="btn btn-small btn-outline-success button-select hasTooltip" title="'.Text::sprintf('COM_COMPONENTBUILDER_EDIT_S', $button_label).'" style="display: none; border-radius: 0px 4px 4px 0px;" href="#" >
<span class="icon-edit"></span></a>';
// build script
$script[] = "
document.addEventListener('DOMContentLoaded', function() {
document.getElementById('jform_".$button_code_name."').addEventListener('change', function(e) {
e.preventDefault();
let ".$button_code_name."Value = this.value;
".$button_code_name."Button(".$button_code_name."Value);
});
let ".$button_code_name."Value = document.getElementById('jform_".$button_code_name."').value;
".$button_code_name."Button(".$button_code_name."Value);
});
function ".$button_code_name."Button(value) {
var createButton = document.getElementById('".$button_code_name."Create');
var editButton = document.getElementById('".$button_code_name."Edit');
if (value > 0) {
// hide the create button
createButton.style.display = 'none';
// show edit button
editButton.style.display = 'block';
let url = 'index.php?option=com_componentbuilder&view=servers&task=server.edit&id='+value+'".$refJ."';
editButton.setAttribute('href', url);
} else {
// show the create button
createButton.style.display = 'block';
// hide edit button
editButton.style.display = 'none';
}
}";
}
// check if button was created for server field.
if (is_array($button) && count($button) > 0)
{
// Load the needed script.
$document = Factory::getApplication()->getDocument();
$document->addScriptDeclaration(implode(' ',$script));
// return the button attached to input field.
return '<div class="input-group">' .$html . implode('',$button).'</div>';
}
}
return $html;
}
/**
* Method to get a list of options for a list input.
*
* @return array An array of Html options.
* @since 1.6
*/
protected function getOptions()
{
// Get the databse object.
$db = Factory::getDBO();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name','a.protocol'),array('id','cronjob_backup_server_name', 'protocol')));
$query->from($db->quoteName('#__componentbuilder_server', 'a'));
$query->where($db->quoteName('a.published') . ' >= 1');
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = [];
if ($items)
{
if ($this->multiple === false)
{
$options[] = Html::_('select.option', '', Text::_('COM_COMPONENTBUILDER_SELECT_AN_OPTION'));
}
foreach($items as $item)
{
$item->protocol = ($item->protocol == 2) ? Text::_('SFTP') : Text::_('FTP');
$options[] = Html::_('select.option', $item->id, $item->cronjob_backup_server_name .' ['.$item->protocol.']');
}
}
return $options;
}
}

View File

@ -42,25 +42,29 @@ class DynamicgetsField extends ListField
*/
protected function getOptions()
{
// Get the databse object.
$db = Factory::getDBO();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name','a.gettype'),array('id','dynamic_get_name','type')));
$query->from($db->quoteName('#__componentbuilder_dynamic_get', 'a'));
$query->where($db->quoteName('a.published') . ' = 1');
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = array();
if ($items)
{
$model = ComponentbuilderHelper::getModel('dynamic_gets');
foreach($items as $item)
{
$type = $model->selectionTranslation($item->type,'gettype');
$options[] = Html::_('select.option', $item->id, $item->dynamic_get_name . ' (' . Text::_($type) . ')' );
}
}
return $options;
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name','a.gettype'),array('id','dynamic_get_name','type')));
$query->from($db->quoteName('#__componentbuilder_dynamic_get', 'a'));
$query->where($db->quoteName('a.published') . ' >= 1');
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = [];
if ($items)
{
$model = ComponentbuilderHelper::getModel('dynamic_gets');
if ($this->multiple === false)
{
$options[] = Html::_('select.option', '', Text::_('COM_COMPONENTBUILDER_SELECT_AN_OPTION'));
}
foreach($items as $item)
{
$type = $model->selectionTranslation($item->type, 'gettype');
$options[] = Html::_('select.option', $item->id, $item->dynamic_get_name . ' (' . Text::_($type) . ')');
}
}
return $options;
}
}

View File

@ -42,23 +42,27 @@ class LibraryreadonlyField extends ListField
*/
protected function getOptions()
{
// Get the databse object.
$db = Factory::getDBO();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name'),array('id','library_name')));
$query->from($db->quoteName('#__componentbuilder_library', 'a'));
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = array();
if ($items)
{
$options[] = Html::_('select.option', '', 'Select an option');
foreach($items as $item)
{
$options[] = Html::_('select.option', $item->id, $item->library_name);
}
}
return $options;
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name'),array('id','library_name')));
$query->from($db->quoteName('#__componentbuilder_library', 'a'));
$query->where($db->quoteName('a.published') . ' >= 1');
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = [];
if ($items)
{
if ($this->multiple === false)
{
$options[] = Html::_('select.option', '', Text::_('COM_COMPONENTBUILDER_SELECT_AN_OPTION'));
}
foreach($items as $item)
{
$options[] = Html::_('select.option', $item->id, $item->library_name);
}
}
return $options;
}
}

View File

@ -148,25 +148,30 @@ class MaingetsField extends ListField
*/
protected function getOptions()
{
// Get the databse object.
$db = Factory::getDBO();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name','a.gettype'),array('id','main_get_name','type')));
$query->from($db->quoteName('#__componentbuilder_dynamic_get', 'a'));
$query->where($db->quoteName('a.published') . ' = 1');
$query->where('( '.$db->quoteName('a.gettype') . ' = 1 OR ' . $db->quoteName('a.gettype') . ' = 2 )');
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name','a.gettype'),array('id','main_get_name','type')));
$query->from($db->quoteName('#__componentbuilder_dynamic_get', 'a'));
$query->where($db->quoteName('a.published') . ' = 1');
$query->where('( '.$db->quoteName('a.gettype') . ' = 1 OR ' . $db->quoteName('a.gettype') . ' = 2 )');
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = array();
if ($items)
{
$model = ComponentbuilderHelper::getModel('dynamic_gets');
foreach($items as $item)
{
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = [];
if ($items)
{
$model = ComponentbuilderHelper::getModel('dynamic_gets');
if ($this->multiple === false)
{
$options[] = Html::_('select.option', '', Text::_('COM_COMPONENTBUILDER_SELECT_AN_OPTION'));
}
foreach($items as $item)
{
$type = $model->selectionTranslation($item->type,'gettype');
$options[] = Html::_('select.option', $item->id, $item->main_get_name . ' (' . Text::_($type) . ')' );
}
}
return $options;
$options[] = Html::_('select.option', $item->id, $item->main_get_name . ' (' . Text::_($type) . ')');
}
}
return $options;
}
}

View File

@ -148,25 +148,28 @@ class ServersField extends ListField
*/
protected function getOptions()
{
// Get the databse object. (prime)
$db = Factory::getDBO();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name','a.protocol'),array('id','name', 'protocol')));
$query->from($db->quoteName('#__componentbuilder_server', 'a'));
$query->where($db->quoteName('a.published') . ' >= 1');
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = array();
if ($items)
{
$options[] = Html::_('select.option', '', 'Select an option');
foreach($items as $item)
{
$item->protocol = ($item->protocol == 2) ? Text::_('SFTP') : Text::_('FTP');
$options[] = Html::_('select.option', $item->id, $item->name.' ['.$item->protocol.']');
}
}
return $options;
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name','a.protocol'),array('id','update_server_name', 'protocol')));
$query->from($db->quoteName('#__componentbuilder_server', 'a'));
$query->where($db->quoteName('a.published') . ' >= 1');
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = [];
if ($items)
{
if ($this->multiple === false)
{
$options[] = Html::_('select.option', '', Text::_('COM_COMPONENTBUILDER_SELECT_AN_OPTION'));
}
foreach($items as $item)
{
$item->protocol = ($item->protocol == 2) ? Text::_('SFTP') : Text::_('FTP');
$options[] = Html::_('select.option', $item->id, $item->update_server_name .' ['.$item->protocol.']');
}
}
return $options;
}
}

View File

@ -16,6 +16,7 @@ use Joomla\CMS\Language\Text;
use Joomla\CMS\HTML\HTMLHelper as Html;
use Joomla\CMS\Component\ComponentHelper;
use VDM\Component\Componentbuilder\Administrator\Helper\ComponentbuilderHelper;
use VDM\Joomla\Utilities\StringHelper;
// No direct access to this file
\defined('_JEXEC') or die;
@ -148,30 +149,34 @@ class SnippetsField extends ListField
*/
protected function getOptions()
{
// Get the databse object.
$db = Factory::getDBO();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name','b.name','c.name'),array('id','snippet_name','type','library')));
$query->from($db->quoteName('#__componentbuilder_snippet', 'a'));
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name','b.name','c.name'),array('id','snippet_name','type','library')));
$query->from($db->quoteName('#__componentbuilder_snippet', 'a'));
// From the componentbuilder_snippet_type table.
$query->join('LEFT', $db->quoteName('#__componentbuilder_snippet_type', 'b') . ' ON (' . $db->quoteName('a.type') . ' = ' . $db->quoteName('b.id') . ')');
// From the componentbuilder_library table.
$query->join('LEFT', $db->quoteName('#__componentbuilder_library', 'c') . ' ON (' . $db->quoteName('a.library') . ' = ' . $db->quoteName('c.id') . ')');
$query->where($db->quoteName('a.published') . ' >= 1');
$query->order('c.ordering ASC');
$query->where($db->quoteName('a.published') . ' >= 1');
$query->order('c.ordering ASC');
$query->order('b.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = array();
if ($items)
{
foreach($items as $item)
{
$lib = (isset($item->library) && ComponentbuilderHelper::checkString($item->library)) ? ' (' . $item->library . ')' :'';
$type = (isset($item->type) && ComponentbuilderHelper::checkString($item->type)) ? $item->type :Text::_('COM_COMPONENTBUILDER_NO_TYPE');
$options[] = Html::_('select.option', $item->id, $type . ' - ' . $item->snippet_name . $lib );
}
}
return $options;
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = [];
if ($items)
{
if ($this->multiple === false)
{
$options[] = Html::_('select.option', '', Text::_('COM_COMPONENTBUILDER_SELECT_AN_OPTION'));
}
foreach($items as $item)
{
$lib = (isset($item->library) && StringHelper::check($item->library)) ? ' (' . $item->library . ')' :'';
$type = (isset($item->type) && StringHelper::check($item->type)) ? $item->type :Text::_('COM_COMPONENTBUILDER_NO_TYPE');
$options[] = Html::_('select.option', $item->id, $type . ' - ' . $item->snippet_name . $lib);
}
}
return $options;
}
}

View File

@ -42,24 +42,27 @@ class SnippettypeField extends ListField
*/
protected function getOptions()
{
// Get the databse object.
$db = Factory::getDBO();
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name'),array('id','type_name')));
$query->from($db->quoteName('#__componentbuilder_snippet_type', 'a'));
$query->where($db->quoteName('a.published') . ' >= 1');
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = array();
if ($items)
{
$options[] = Html::_('select.option', '', 'Select an option');
foreach($items as $item)
{
$options[] = Html::_('select.option', $item->id, $item->type_name);
}
}
return $options;
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.id','a.name'),array('id','type_name')));
$query->from($db->quoteName('#__componentbuilder_snippet_type', 'a'));
$query->where($db->quoteName('a.published') . ' >= 1');
$query->order('a.name ASC');
$db->setQuery((string)$query);
$items = $db->loadObjectList();
$options = [];
if ($items)
{
if ($this->multiple === false)
{
$options[] = Html::_('select.option', '', Text::_('COM_COMPONENTBUILDER_SELECT_AN_OPTION'));
}
foreach($items as $item)
{
$options[] = Html::_('select.option', $item->id, $item->type_name);
}
}
return $options;
}
}

View File

@ -5674,8 +5674,8 @@ abstract class ComponentbuilderHelper
return MathHelper::sum($array, $scale);
}
/**
* create plugin class name
/**
* create plugin class name
*
* @input string The group name
* @input string The name
@ -5684,7 +5684,7 @@ abstract class ComponentbuilderHelper
*
* @since 3.0.9
*
* @deprecated 4.0 - Use PluginHelper::safe($name, $group);
* @deprecated 4.0 - Use PluginHelper::safeClassName($name, $group);
*/
public static function createPluginClassName($group, $name)
{

View File

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<extension type="component" version="4.0" method="upgrade">
<name>COM_COMPONENTBUILDER</name>
<creationDate>1st August, 2024</creationDate>
<creationDate>14th August, 2024</creationDate>
<author>Llewellyn van der Merwe</author>
<authorEmail>joomla@vdm.io</authorEmail>
<authorUrl>https://dev.vdm.io</authorUrl>
<copyright>Copyright (C) 2015 Vast Development Method. All rights reserved.</copyright>
<license>GNU General Public License version 2 or later; see LICENSE.txt</license>
<version>4.0.2-beta3</version>
<version>4.0.2-beta4</version>
<description><![CDATA[
<h1>Component Builder (v.4.0.2-beta3)</h1>
<h1>Component Builder (v.4.0.2-beta4)</h1>
<div style="clear: both;"></div>
<p>The Component Builder for [Joomla](https://extensions.joomla.org/extension/component-builder/) is highly advanced tool that is truly able to build extremely complex components in a fraction of the time.

View File

@ -80,7 +80,7 @@
<version>4.0.2-beta</version>
<infourl title="Component Builder!">https://dev.vdm.io</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v4.0.2-beta3.zip</downloadurl>
<downloadurl type="full" format="zip">https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v4.0.2-beta4.zip</downloadurl>
</downloads>
<tags>
<tag>beta</tag>
@ -95,10 +95,10 @@
<element>pkg_component_builder</element>
<type>package</type>
<client>site</client>
<version>4.0.2-beta3</version>
<version>4.0.2-beta4</version>
<infourl title="Component Builder!">https://dev.vdm.io</infourl>
<downloads>
<downloadurl type="full" format="zip">https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v4.0.2-beta3.zip</downloadurl>
<downloadurl type="full" format="zip">https://git.vdm.dev/api/v1/repos/joomla/pkg-component-builder/archive/v4.0.2-beta4.zip</downloadurl>
</downloads>
<tags>
<tag>beta</tag>

View File

@ -0,0 +1,215 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Power\Parser;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ExtensionInterface;
/**
* Plugin Extension Class for Joomla 5
*
* @since 5.0.2
*/
final class Extension implements ExtensionInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* The Parser Class.
*
* @var Parser
* @since 5.0.2
*/
protected Parser $parser;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
* @param Parser $parser The Parser Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder, Parser $parser)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
$this->parser = $parser;
}
/**
* Get the updated placeholder content for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The updated placeholder content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$add_subscriber_interface = $this->addNeededMethods($plugin->main_class_code);
$extension = [];
$extension[] = $plugin->comment . PHP_EOL . 'final class ';
$extension[] = $plugin->class_name . ' extends ' . $plugin->extends;
if ($add_subscriber_interface)
{
$extension[] = ' implements Joomla__' . '_c06c5116_6b9d_487c_9b09_5094ec4506a3___Power';
}
$extension[] = PHP_EOL . '{' . PHP_EOL;
$extension[] = $plugin->main_class_code;
$extension[] = PHP_EOL . '}' . PHP_EOL;
return $this->placeholder->update(
implode('', $extension),
$this->builder->allActive()
);
}
/**
* Ensures that the required methods are present in the plugin code.
*
* This method checks the plugin's code for the presence of required methods,
* particularly the method that indicates implementation of the SubscriberInterface.
* If the necessary method is missing, it adds it to the code.
*
* @param string $code The main code of the plugin, passed by reference.
*
* @return bool Returns true if the SubscriberInterface implementation is added or already present, false otherwise.
*
* @since 5.0.2
*/
protected function addNeededMethods(string &$code): bool
{
// Parse the code to extract its structure, particularly its methods.
$code_structure = $this->parser->code($code);
if (empty($code_structure['methods']))
{
return false;
}
// Check if methods are defined and if getSubscribedEvents is not present.
if (!$this->getSubscribedEvents($code_structure['methods']))
{
// Attempt to add the getSubscribedEvents method.
$method = $this->addGetSubscribedEvents($code_structure['methods']);
if ($method !== null)
{
// Append the new method to the code and indicate that the interface must be added.
$code .= $method;
return true;
}
// Return false if the event method could not be added.
return false;
}
// Return true if getSubscribedEvents is already present.
return true;
}
/**
* Add the getSubscribedEvents method
*
* @param array $methods The plugin methods.
*
* @return string|null The getSubscribedEvents code
*
* @since 5.0.2
*/
protected function addGetSubscribedEvents(array $methods): ?string
{
$events = [];
$counter = 0;
foreach ($methods as $method)
{
if ($method['access'] === 'public' && !$method['static'] && !$method['abstract'])
{
$events[$method['name']] = Indent::_(3) . "'{$method['name']}' => '{$method['name']}'";
// autoloaded when method start with 'on'
// so we can ignore adding the getSubscribedEvents
if (substr($method['name'], 0, 2) === 'on')
{
$counter++;
}
}
}
if ($events === [] || $counter == count($events))
{
return null;
}
$method = [];
$method[] = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$method[] = Indent::_(1) . ' * Returns an array of events this subscriber will listen to.';
$method[] = Indent::_(1) . ' *';
$method[] = Indent::_(1) . ' * @return array';
$method[] = Indent::_(1) . ' *';
$method[] = Indent::_(1) . ' * @since 5.0.0';
$method[] = Indent::_(1) . ' */';
$method[] = Indent::_(1) . 'public static function getSubscribedEvents(): array';
$method[] = Indent::_(1) . '{';
$method[] = Indent::_(2) . 'return [';
$method[] = implode(',' . PHP_EOL, $events);
$method[] = Indent::_(2) . '];';
$method[] = Indent::_(1) . '}';
return implode(PHP_EOL, $method);
}
/**
* Check if the getSubscribedEvents is set
*
* @param array $methods The plugin methods.
*
* @return bool
*
* @since 5.0.2
*/
protected function getSubscribedEvents(array $methods): bool
{
foreach ($methods as $method)
{
if ($method['name'] === 'getSubscribedEvents' && $method['static'] && !$method['abstract'])
{
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,569 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin;
use Joomla\CMS\Filesystem\Folder;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Language\Set;
use VDM\Joomla\Componentbuilder\Compiler\Language\Purge;
use VDM\Joomla\Componentbuilder\Compiler\Language\Translation;
use VDM\Joomla\Componentbuilder\Compiler\Language\Multilingual;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetExtension;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Languages;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Multilingual as BuilderMultilingual;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\File;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin\MainXMLInterface;
/**
* Joomla 5 Plugin Main XML Class
*
* @since 5.0.2
*/
final class MainXML implements MainXMLInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Set Class.
*
* @var Set
* @since 5.0.2
*/
protected Set $set;
/**
* The Purge Class.
*
* @var Purge
* @since 5.0.2
*/
protected Purge $purge;
/**
* The Translation Class.
*
* @var Translation
* @since 5.0.2
*/
protected Translation $translation;
/**
* The Multilingual Class.
*
* @var Multilingual
* @since 5.0.2
*/
protected Multilingual $multilingual;
/**
* The EventInterface Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The FieldsetExtension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* The ContentOne Class.
*
* @var ContentOne
* @since 5.0.2
*/
protected ContentOne $contentone;
/**
* The Languages Class.
*
* @var Languages
* @since 5.0.2
*/
protected Languages $languages;
/**
* The Multilingual Class.
*
* @var BuilderMultilingual
* @since 5.0.2
*/
protected BuilderMultilingual $buildermultilingual;
/**
* The Counter Class.
*
* @var Counter
* @since 5.0.2
*/
protected Counter $counter;
/**
* The File Class.
*
* @var File
* @since 5.0.2
*/
protected File $file;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Language $language The Language Class.
* @param Set $set The Set Class.
* @param Purge $purge The Purge Class.
* @param Translation $translation The Translation Class.
* @param Multilingual $multilingual The Multilingual Class.
* @param Event $event The EventInterface Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
* @param ContentOne $contentone The ContentOne Class.
* @param Languages $languages The Languages Class.
* @param BuilderMultilingual $buildermultilingual The Multilingual Class.
* @param Counter $counter The Counter Class.
* @param File $file The File Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Language $language, Set $set, Purge $purge,
Translation $translation, Multilingual $multilingual,
Event $event, FieldsetExtension $fieldsetextension,
ContentOne $contentone, Languages $languages,
BuilderMultilingual $buildermultilingual,
Counter $counter, File $file)
{
$this->config = $config;
$this->language = $language;
$this->set = $set;
$this->purge = $purge;
$this->translation = $translation;
$this->multilingual = $multilingual;
$this->event = $event;
$this->fieldsetextension = $fieldsetextension;
$this->contentone = $contentone;
$this->languages = $languages;
$this->buildermultilingual = $buildermultilingual;
$this->counter = $counter;
$this->file = $file;
}
/**
* Generates the main XML for the plugin.
*
* @param object $plugin The plugin object.
*
* @return string The generated XML.
* @since 5.0.2
*/
public function get(object $plugin): string
{
$config_fields = $this->buildConfigFields($plugin);
$add_component_path = $this->shouldAddComponentPath($plugin);
$language_files = $this->generateLanguageFiles($plugin);
$xml = $this->generateScriptAndSqlXml($plugin);
$xml .= $this->generateLanguageXml($plugin, $language_files);
$xml .= $this->generateFileXml($plugin, $language_files);
$xml .= $this->generateConfigXml($plugin, $config_fields, $add_component_path);
$xml .= $this->generateUpdateServerXml($plugin);
return $xml;
}
/**
* Build configuration fields XML.
*
* @param object $plugin The plugin object.
*
* @return array The configuration fields.
* @since 5.0.2
*/
protected function buildConfigFields(object $plugin): array
{
$configFields = [];
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields))
{
return $configFields;
}
$dbKey = 'yy';
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$xmlFields = $this->fieldsetextension->get($plugin, $fields, $dbKey);
if (isset($xmlFields) && StringHelper::check($xmlFields))
{
$configFields["{$fieldName}{$fieldset}"] = $xmlFields;
}
$dbKey++;
}
}
return $configFields;
}
/**
* Determine if the component path should be added.
*
* @param object $plugin The plugin object.
*
* @return bool True if the component path should be added, false otherwise.
* @since 5.0.2
*/
protected function shouldAddComponentPath(object $plugin): bool
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields) ||
!isset($plugin->fieldsets_paths) || !ArrayHelper::check($plugin->fieldsets_paths))
{
return false;
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
if (isset($plugin->fieldsets_paths["{$fieldName}{$fieldset}"]) &&
$plugin->fieldsets_paths["{$fieldName}{$fieldset}"] == 1)
{
return true;
}
}
}
return false;
}
/**
* Generate XML for script and SQL files.
*
* @param object $plugin The plugin object.
*
* @return string The XML for script and SQL files.
* @since 5.0.2
*/
protected function generateScriptAndSqlXml(object $plugin): string
{
$xml = '';
if ($plugin->add_install_script)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Scripts to run on installation -->';
$xml .= PHP_EOL . Indent::_(1) . '<scriptfile>script.php</scriptfile>';
}
if ($plugin->add_sql)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on install -->';
$xml .= PHP_EOL . Indent::_(1) . '<install>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/install.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</install>';
}
if ($plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on uninstall -->';
$xml .= PHP_EOL . Indent::_(1) . '<uninstall>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/uninstall.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</uninstall>';
}
return $xml;
}
/**
* Generate XML for language files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for language files.
* @since 5.0.2
*/
protected function generateLanguageXml(object $plugin, array $languageFiles): string
{
$xml = '';
if (ArrayHelper::check($languageFiles))
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Language files -->';
$xml .= PHP_EOL . Indent::_(1) . '<languages folder="language">';
foreach ($languageFiles as $addTag)
{
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/plg_'
. strtolower((string) $plugin->group) . '_' .
(string) $plugin->file_name
. '.ini</language>';
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/plg_'
. strtolower((string) $plugin->group) . '_' .
(string) $plugin->file_name
. '.sys.ini</language>';
}
$xml .= PHP_EOL . Indent::_(1) . '</languages>';
}
return $xml;
}
/**
* Generate the XML for the files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for the files.
* @since 5.0.2
*/
protected function generateFileXml(object $plugin, array $languageFiles): string
{
$files = Folder::files($plugin->folder_path);
$folders = Folder::folders($plugin->folder_path);
$ignore = ['sql', 'language', 'script.php', "{$plugin->file_name}.xml"];
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Plugin files -->';
$xml .= PHP_EOL . Indent::_(1) . '<files>';
$xml .= PHP_EOL . Indent::_(2) . "<folder plugin=\"{$plugin->context_name}\">services</folder>";
foreach ($files as $file)
{
if (!in_array($file, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<filename>{$file}</filename>";
}
}
if (!empty($languageFiles))
{
// $xml .= PHP_EOL . Indent::_(2) . '<folder>language</folder>';
}
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>sql</folder>';
}
foreach ($folders as $folder)
{
if (!in_array($folder, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<folder>{$folder}</folder>";
}
}
$xml .= PHP_EOL . Indent::_(1) . '</files>';
return $xml;
}
/**
* Generate XML for configuration fields.
*
* @param object $plugin The plugin object.
* @param array $configFields The configuration fields.
* @param bool $addComponentPath Whether to add the component path.
*
* @return string The XML for configuration fields.
* @since 5.0.2
*/
protected function generateConfigXml(object $plugin, array $configFields, bool $addComponentPath): string
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($configFields))
{
return '';
}
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Config parameters -->';
$xml .= $addComponentPath ? PHP_EOL . Indent::_(1) . '<config' : PHP_EOL . Indent::_(1) . '<config>';
if ($addComponentPath)
{
$xml .= PHP_EOL . Indent::_(3) . 'addruleprefix="' . $this->config->namespace_prefix . '\Component\\' . $this->contentone->get('ComponentNamespace') . '\Administrator\Rule"';
$xml .= PHP_EOL . Indent::_(3) . 'addfieldprefix="' . $this->config->namespace_prefix . '\Component\\' . $this->contentone->get('ComponentNamespace') . '\Administrator\Field">';
$xml .= PHP_EOL . Indent::_(1) . '>';
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
$xml .= PHP_EOL . Indent::_(1) . "<fields name=\"{$fieldName}\">";
foreach ($fieldsets as $fieldset => $fields)
{
$label = $plugin->fieldsets_label["{$fieldName}{$fieldset}"] ?? $fieldset;
$xml .= PHP_EOL . Indent::_(1) . "<fieldset name=\"{$fieldset}\" label=\"{$label}\">";
if (isset($configFields["{$fieldName}{$fieldset}"]))
{
$xml .= $configFields["{$fieldName}{$fieldset}"];
}
$xml .= PHP_EOL . Indent::_(1) . '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . Indent::_(1) . '</config>';
return $xml;
}
/**
* Generate XML for update servers.
*
* @param object $plugin The plugin object.
*
* @return string The XML for update servers.
* @since 5.0.2
*/
protected function generateUpdateServerXml(object $plugin): string
{
$xml = '';
if ($plugin->add_update_server)
{
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Update servers -->';
$xml .= PHP_EOL . Indent::_(1) . '<updateservers>';
$xml .= PHP_EOL . Indent::_(2) . '<server type="extension" priority="1" name="' . $plugin->official_name . '">' . $plugin->update_server_url . '</server>';
$xml .= PHP_EOL . Indent::_(1) . '</updateservers>';
}
return $xml;
}
/**
* Generate language files.
*
* @param object $plugin The plugin object.
*
* @return array The language files.
* @since 5.0.2
*/
protected function generateLanguageFiles(object $plugin): array
{
$languageFiles = [];
if (!$this->language->exist($plugin->key))
{
return $languageFiles;
}
$langContent = $this->language->getTarget($plugin->key);
$this->event->trigger('jcb_ce_onBeforeBuildPluginLang', [&$plugin, &$langContent]);
$values = array_unique($langContent);
$this->buildermultilingual->set('plugins', $this->multilingual->get($values));
$langTag = $this->config->get('lang_tag', 'en-GB');
$this->languages->set("plugins.{$langTag}.all", $langContent);
$this->language->setTarget($plugin->key, null);
$this->set->execute($values, $plugin->id, 'plugins');
$this->purge->execute($values, $plugin->id, 'plugins');
$this->event->trigger('jcb_ce_onBeforeBuildPluginLangFiles', [&$plugin]);
if ($this->languages->IsArray('plugins'))
{
foreach ($this->languages->get('plugins') as $tag => $areas)
{
$tag = trim($tag);
foreach ($areas as $area => $languageStrings)
{
$fileName = "plg_" . strtolower((string)$plugin->group) . '_' . $plugin->file_name . '.ini';
$total = count($values);
if ($this->translation->check($tag, $languageStrings, $total, $fileName))
{
$lang = array_map(
fn($langString, $placeholder) => "{$placeholder}=\"{$langString}\"",
array_values($languageStrings),
array_keys($languageStrings)
);
$path = "{$plugin->folder_path}/language/{$tag}/";
if (!Folder::exists($path))
{
Folder::create($path);
$this->counter->folder++;
}
$this->file->write($path . $fileName, implode(PHP_EOL, $lang));
$this->file->write(
$path . 'plg_' . strtolower((string)$plugin->group) . '_' . $plugin->file_name . '.sys.ini',
implode(PHP_EOL, $lang)
);
$this->counter->line += count($lang);
unset($lang);
$languageFiles[$tag] = $tag;
}
}
}
}
return $languageFiles;
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ProviderInterface;
/**
* Plugin Provider Class for Joomla 5
*
* @since 5.0.2
*/
final class Provider implements ProviderInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated provider for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The provider content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$group = strtolower((string) $plugin->group);
$provider = [];
$provider[] = PHP_EOL . PHP_EOL . "return new class () implements ServiceProviderInterface {";
$provider[] = Indent::_(1) . "/**";
$provider[] = Indent::_(1) . "*" . Line::_(__Line__, __Class__)
. " Registers the service provider with a DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @param Container \$container The DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @return void";
$provider[] = Indent::_(1) . "* @since 4.3.0";
$provider[] = Indent::_(1) . "*/";
$provider[] = Indent::_(1) . "public function register(Container \$container)";
$provider[] = Indent::_(1) . "{";
$provider[] = Indent::_(2) . "\$container->set(";
$provider[] = Indent::_(3) . "PluginInterface::class,";
$provider[] = Indent::_(3) . "function (Container \$container) {";
$provider[] = Indent::_(4) . "\$plugin = new {$plugin->class_name}(";
$provider[] = Indent::_(5) . "\$container->get(DispatcherInterface::class),";
$provider[] = Indent::_(5) . "(array) PluginHelper::getPlugin('{$group}', '{$plugin->context_name}')";
$provider[] = Indent::_(4) . ");";
$provider[] = Indent::_(4) . "\$plugin->setApplication(Factory::getApplication());";
$provider[] = $plugin->service_provider ?? ''; // to add extra plug-in suff
$provider[] = Indent::_(4) . "return \$plugin;";
$provider[] = Indent::_(3) . "}";
$provider[] = Indent::_(2) . ");";
$provider[] = Indent::_(1) . "}";
$provider[] = "};";
return $this->placeholder->update(
implode(PHP_EOL, $provider). PHP_EOL,
$this->builder->allActive()
);
}
}

View File

@ -0,0 +1,215 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Power\Parser;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ExtensionInterface;
/**
* Plugin Extension Class for Joomla 4
*
* @since 5.0.2
*/
final class Extension implements ExtensionInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* The Parser Class.
*
* @var Parser
* @since 5.0.2
*/
protected Parser $parser;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
* @param Parser $parser The Parser Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder, Parser $parser)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
$this->parser = $parser;
}
/**
* Get the updated placeholder content for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The updated placeholder content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$add_subscriber_interface = $this->addNeededMethods($plugin->main_class_code);
$extension = [];
$extension[] = $plugin->comment . PHP_EOL . 'final class ';
$extension[] = $plugin->class_name . ' extends ' . $plugin->extends;
if ($add_subscriber_interface)
{
$extension[] = ' implements Joomla__' . '_c06c5116_6b9d_487c_9b09_5094ec4506a3___Power';
}
$extension[] = PHP_EOL . '{' . PHP_EOL;
$extension[] = $plugin->main_class_code;
$extension[] = PHP_EOL . '}' . PHP_EOL;
return $this->placeholder->update(
implode('', $extension),
$this->builder->allActive()
);
}
/**
* Ensures that the required methods are present in the plugin code.
*
* This method checks the plugin's code for the presence of required methods,
* particularly the method that indicates implementation of the SubscriberInterface.
* If the necessary method is missing, it adds it to the code.
*
* @param string $code The main code of the plugin, passed by reference.
*
* @return bool Returns true if the SubscriberInterface implementation is added or already present, false otherwise.
*
* @since 5.0.2
*/
protected function addNeededMethods(string &$code): bool
{
// Parse the code to extract its structure, particularly its methods.
$code_structure = $this->parser->code($code);
if (empty($code_structure['methods']))
{
return false;
}
// Check if methods are defined and if getSubscribedEvents is not present.
if (!$this->getSubscribedEvents($code_structure['methods']))
{
// Attempt to add the getSubscribedEvents method.
$method = $this->addGetSubscribedEvents($code_structure['methods']);
if ($method !== null)
{
// Append the new method to the code and indicate that the interface must be added.
$code .= $method;
return true;
}
// Return false if the event method could not be added.
return false;
}
// Return true if getSubscribedEvents is already present.
return true;
}
/**
* Add the getSubscribedEvents method
*
* @param array $methods The plugin methods.
*
* @return string|null The getSubscribedEvents code
*
* @since 5.0.2
*/
protected function addGetSubscribedEvents(array $methods): ?string
{
$events = [];
$counter = 0;
foreach ($methods as $method)
{
if ($method['access'] === 'public' && !$method['static'] && !$method['abstract'])
{
$events[$method['name']] = Indent::_(3) . "'{$method['name']}' => '{$method['name']}'";
// autoloaded when method start with 'on'
// so we can ignore adding the getSubscribedEvents
if (substr($method['name'], 0, 2) === 'on')
{
$counter++;
}
}
}
if ($events === [] || $counter == count($events))
{
return null;
}
$method = [];
$method[] = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$method[] = Indent::_(1) . ' * Returns an array of events this subscriber will listen to.';
$method[] = Indent::_(1) . ' *';
$method[] = Indent::_(1) . ' * @return array';
$method[] = Indent::_(1) . ' *';
$method[] = Indent::_(1) . ' * @since 5.0.0';
$method[] = Indent::_(1) . ' */';
$method[] = Indent::_(1) . 'public static function getSubscribedEvents(): array';
$method[] = Indent::_(1) . '{';
$method[] = Indent::_(2) . 'return [';
$method[] = implode(',' . PHP_EOL, $events);
$method[] = Indent::_(2) . '];';
$method[] = Indent::_(1) . '}';
return implode(PHP_EOL, $method);
}
/**
* Check if the getSubscribedEvents is set
*
* @param array $methods The plugin methods.
*
* @return bool
*
* @since 5.0.2
*/
protected function getSubscribedEvents(array $methods): bool
{
foreach ($methods as $method)
{
if ($method['name'] === 'getSubscribedEvents' && $method['static'] && !$method['abstract'])
{
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,569 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Plugin;
use Joomla\CMS\Filesystem\Folder;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Language\Set;
use VDM\Joomla\Componentbuilder\Compiler\Language\Purge;
use VDM\Joomla\Componentbuilder\Compiler\Language\Translation;
use VDM\Joomla\Componentbuilder\Compiler\Language\Multilingual;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetExtension;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Languages;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Multilingual as BuilderMultilingual;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\File;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin\MainXMLInterface;
/**
* Joomla 4 Plugin Main XML Class
*
* @since 5.0.2
*/
final class MainXML implements MainXMLInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Set Class.
*
* @var Set
* @since 5.0.2
*/
protected Set $set;
/**
* The Purge Class.
*
* @var Purge
* @since 5.0.2
*/
protected Purge $purge;
/**
* The Translation Class.
*
* @var Translation
* @since 5.0.2
*/
protected Translation $translation;
/**
* The Multilingual Class.
*
* @var Multilingual
* @since 5.0.2
*/
protected Multilingual $multilingual;
/**
* The EventInterface Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The FieldsetExtension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* The ContentOne Class.
*
* @var ContentOne
* @since 5.0.2
*/
protected ContentOne $contentone;
/**
* The Languages Class.
*
* @var Languages
* @since 5.0.2
*/
protected Languages $languages;
/**
* The Multilingual Class.
*
* @var BuilderMultilingual
* @since 5.0.2
*/
protected BuilderMultilingual $buildermultilingual;
/**
* The Counter Class.
*
* @var Counter
* @since 5.0.2
*/
protected Counter $counter;
/**
* The File Class.
*
* @var File
* @since 5.0.2
*/
protected File $file;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Language $language The Language Class.
* @param Set $set The Set Class.
* @param Purge $purge The Purge Class.
* @param Translation $translation The Translation Class.
* @param Multilingual $multilingual The Multilingual Class.
* @param Event $event The EventInterface Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
* @param ContentOne $contentone The ContentOne Class.
* @param Languages $languages The Languages Class.
* @param BuilderMultilingual $buildermultilingual The Multilingual Class.
* @param Counter $counter The Counter Class.
* @param File $file The File Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Language $language, Set $set, Purge $purge,
Translation $translation, Multilingual $multilingual,
Event $event, FieldsetExtension $fieldsetextension,
ContentOne $contentone, Languages $languages,
BuilderMultilingual $buildermultilingual,
Counter $counter, File $file)
{
$this->config = $config;
$this->language = $language;
$this->set = $set;
$this->purge = $purge;
$this->translation = $translation;
$this->multilingual = $multilingual;
$this->event = $event;
$this->fieldsetextension = $fieldsetextension;
$this->contentone = $contentone;
$this->languages = $languages;
$this->buildermultilingual = $buildermultilingual;
$this->counter = $counter;
$this->file = $file;
}
/**
* Generates the main XML for the plugin.
*
* @param object $plugin The plugin object.
*
* @return string The generated XML.
* @since 5.0.2
*/
public function get(object $plugin): string
{
$config_fields = $this->buildConfigFields($plugin);
$add_component_path = $this->shouldAddComponentPath($plugin);
$language_files = $this->generateLanguageFiles($plugin);
$xml = $this->generateScriptAndSqlXml($plugin);
$xml .= $this->generateLanguageXml($plugin, $language_files);
$xml .= $this->generateFileXml($plugin, $language_files);
$xml .= $this->generateConfigXml($plugin, $config_fields, $add_component_path);
$xml .= $this->generateUpdateServerXml($plugin);
return $xml;
}
/**
* Build configuration fields XML.
*
* @param object $plugin The plugin object.
*
* @return array The configuration fields.
* @since 5.0.2
*/
protected function buildConfigFields(object $plugin): array
{
$configFields = [];
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields))
{
return $configFields;
}
$dbKey = 'yy';
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$xmlFields = $this->fieldsetextension->get($plugin, $fields, $dbKey);
if (isset($xmlFields) && StringHelper::check($xmlFields))
{
$configFields["{$fieldName}{$fieldset}"] = $xmlFields;
}
$dbKey++;
}
}
return $configFields;
}
/**
* Determine if the component path should be added.
*
* @param object $plugin The plugin object.
*
* @return bool True if the component path should be added, false otherwise.
* @since 5.0.2
*/
protected function shouldAddComponentPath(object $plugin): bool
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields) ||
!isset($plugin->fieldsets_paths) || !ArrayHelper::check($plugin->fieldsets_paths))
{
return false;
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
if (isset($plugin->fieldsets_paths["{$fieldName}{$fieldset}"]) &&
$plugin->fieldsets_paths["{$fieldName}{$fieldset}"] == 1)
{
return true;
}
}
}
return false;
}
/**
* Generate XML for script and SQL files.
*
* @param object $plugin The plugin object.
*
* @return string The XML for script and SQL files.
* @since 5.0.2
*/
protected function generateScriptAndSqlXml(object $plugin): string
{
$xml = '';
if ($plugin->add_install_script)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Scripts to run on installation -->';
$xml .= PHP_EOL . Indent::_(1) . '<scriptfile>script.php</scriptfile>';
}
if ($plugin->add_sql)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on install -->';
$xml .= PHP_EOL . Indent::_(1) . '<install>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/install.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</install>';
}
if ($plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on uninstall -->';
$xml .= PHP_EOL . Indent::_(1) . '<uninstall>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/uninstall.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</uninstall>';
}
return $xml;
}
/**
* Generate XML for language files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for language files.
* @since 5.0.2
*/
protected function generateLanguageXml(object $plugin, array $languageFiles): string
{
$xml = '';
if (ArrayHelper::check($languageFiles))
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Language files -->';
$xml .= PHP_EOL . Indent::_(1) . '<languages folder="language">';
foreach ($languageFiles as $addTag)
{
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/plg_'
. strtolower((string) $plugin->group) . '_' .
(string) $plugin->file_name
. '.ini</language>';
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/plg_'
. strtolower((string) $plugin->group) . '_' .
(string) $plugin->file_name
. '.sys.ini</language>';
}
$xml .= PHP_EOL . Indent::_(1) . '</languages>';
}
return $xml;
}
/**
* Generate the XML for the files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for the files.
* @since 5.0.2
*/
protected function generateFileXml(object $plugin, array $languageFiles): string
{
$files = Folder::files($plugin->folder_path);
$folders = Folder::folders($plugin->folder_path);
$ignore = ['sql', 'language', 'script.php', "{$plugin->file_name}.xml"];
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Plugin files -->';
$xml .= PHP_EOL . Indent::_(1) . '<files>';
$xml .= PHP_EOL . Indent::_(2) . "<folder plugin=\"{$plugin->context_name}\">services</folder>";
foreach ($files as $file)
{
if (!in_array($file, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<filename>{$file}</filename>";
}
}
if (!empty($languageFiles))
{
// $xml .= PHP_EOL . Indent::_(2) . '<folder>language</folder>';
}
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>sql</folder>';
}
foreach ($folders as $folder)
{
if (!in_array($folder, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<folder>{$folder}</folder>";
}
}
$xml .= PHP_EOL . Indent::_(1) . '</files>';
return $xml;
}
/**
* Generate XML for configuration fields.
*
* @param object $plugin The plugin object.
* @param array $configFields The configuration fields.
* @param bool $addComponentPath Whether to add the component path.
*
* @return string The XML for configuration fields.
* @since 5.0.2
*/
protected function generateConfigXml(object $plugin, array $configFields, bool $addComponentPath): string
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($configFields))
{
return '';
}
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Config parameters -->';
$xml .= $addComponentPath ? PHP_EOL . Indent::_(1) . '<config' : PHP_EOL . Indent::_(1) . '<config>';
if ($addComponentPath)
{
$xml .= PHP_EOL . Indent::_(3) . 'addruleprefix="' . $this->config->namespace_prefix . '\Component\\' . $this->contentone->get('ComponentNamespace') . '\Administrator\Rule"';
$xml .= PHP_EOL . Indent::_(3) . 'addfieldprefix="' . $this->config->namespace_prefix . '\Component\\' . $this->contentone->get('ComponentNamespace') . '\Administrator\Field">';
$xml .= PHP_EOL . Indent::_(1) . '>';
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
$xml .= PHP_EOL . Indent::_(1) . "<fields name=\"{$fieldName}\">";
foreach ($fieldsets as $fieldset => $fields)
{
$label = $plugin->fieldsets_label["{$fieldName}{$fieldset}"] ?? $fieldset;
$xml .= PHP_EOL . Indent::_(1) . "<fieldset name=\"{$fieldset}\" label=\"{$label}\">";
if (isset($configFields["{$fieldName}{$fieldset}"]))
{
$xml .= $configFields["{$fieldName}{$fieldset}"];
}
$xml .= PHP_EOL . Indent::_(1) . '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . Indent::_(1) . '</config>';
return $xml;
}
/**
* Generate XML for update servers.
*
* @param object $plugin The plugin object.
*
* @return string The XML for update servers.
* @since 5.0.2
*/
protected function generateUpdateServerXml(object $plugin): string
{
$xml = '';
if ($plugin->add_update_server)
{
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Update servers -->';
$xml .= PHP_EOL . Indent::_(1) . '<updateservers>';
$xml .= PHP_EOL . Indent::_(2) . '<server type="extension" priority="1" name="' . $plugin->official_name . '">' . $plugin->update_server_url . '</server>';
$xml .= PHP_EOL . Indent::_(1) . '</updateservers>';
}
return $xml;
}
/**
* Generate language files.
*
* @param object $plugin The plugin object.
*
* @return array The language files.
* @since 5.0.2
*/
protected function generateLanguageFiles(object $plugin): array
{
$languageFiles = [];
if (!$this->language->exist($plugin->key))
{
return $languageFiles;
}
$langContent = $this->language->getTarget($plugin->key);
$this->event->trigger('jcb_ce_onBeforeBuildPluginLang', [&$plugin, &$langContent]);
$values = array_unique($langContent);
$this->buildermultilingual->set('plugins', $this->multilingual->get($values));
$langTag = $this->config->get('lang_tag', 'en-GB');
$this->languages->set("plugins.{$langTag}.all", $langContent);
$this->language->setTarget($plugin->key, null);
$this->set->execute($values, $plugin->id, 'plugins');
$this->purge->execute($values, $plugin->id, 'plugins');
$this->event->trigger('jcb_ce_onBeforeBuildPluginLangFiles', [&$plugin]);
if ($this->languages->IsArray('plugins'))
{
foreach ($this->languages->get('plugins') as $tag => $areas)
{
$tag = trim($tag);
foreach ($areas as $area => $languageStrings)
{
$fileName = "plg_" . strtolower((string)$plugin->group) . '_' . $plugin->file_name . '.ini';
$total = count($values);
if ($this->translation->check($tag, $languageStrings, $total, $fileName))
{
$lang = array_map(
fn($langString, $placeholder) => "{$placeholder}=\"{$langString}\"",
array_values($languageStrings),
array_keys($languageStrings)
);
$path = "{$plugin->folder_path}/language/{$tag}/";
if (!Folder::exists($path))
{
Folder::create($path);
$this->counter->folder++;
}
$this->file->write($path . $fileName, implode(PHP_EOL, $lang));
$this->file->write(
$path . 'plg_' . strtolower((string)$plugin->group) . '_' . $plugin->file_name . '.sys.ini',
implode(PHP_EOL, $lang)
);
$this->counter->line += count($lang);
unset($lang);
$languageFiles[$tag] = $tag;
}
}
}
}
return $languageFiles;
}
}

View File

@ -0,0 +1,106 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ProviderInterface;
/**
* Plugin Provider Class for Joomla 4
*
* @since 5.0.2
*/
final class Provider implements ProviderInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated provider for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The provider content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
$group = strtolower((string) $plugin->group);
$provider = [];
$provider[] = PHP_EOL . PHP_EOL . "return new class () implements ServiceProviderInterface {";
$provider[] = Indent::_(1) . "/**";
$provider[] = Indent::_(1) . "*" . Line::_(__Line__, __Class__)
. " Registers the service provider with a DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @param Container \$container The DI container.";
$provider[] = Indent::_(1) . "*";
$provider[] = Indent::_(1) . "* @return void";
$provider[] = Indent::_(1) . "* @since 4.3.0";
$provider[] = Indent::_(1) . "*/";
$provider[] = Indent::_(1) . "public function register(Container \$container)";
$provider[] = Indent::_(1) . "{";
$provider[] = Indent::_(2) . "\$container->set(";
$provider[] = Indent::_(3) . "PluginInterface::class,";
$provider[] = Indent::_(3) . "function (Container \$container) {";
$provider[] = Indent::_(4) . "\$plugin = new {$plugin->class_name}(";
$provider[] = Indent::_(5) . "\$container->get(DispatcherInterface::class),";
$provider[] = Indent::_(5) . "(array) PluginHelper::getPlugin('{$group}', '{$plugin->context_name}')";
$provider[] = Indent::_(4) . ");";
$provider[] = Indent::_(4) . "\$plugin->setApplication(Factory::getApplication());";
$provider[] = $plugin->service_provider ?? ''; // to add extra plug-in suff
$provider[] = Indent::_(4) . "return \$plugin;";
$provider[] = Indent::_(3) . "}";
$provider[] = Indent::_(2) . ");";
$provider[] = Indent::_(1) . "}";
$provider[] = "};";
return $this->placeholder->update(
implode(PHP_EOL, $provider). PHP_EOL,
$this->builder->allActive()
);
}
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -0,0 +1,78 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ExtensionInterface;
/**
* Plugin Extension Class for Joomla 3
*
* @since 5.0.2
*/
final class Extension implements ExtensionInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated placeholder content for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The updated placeholder content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
return $this->placeholder->update(
$plugin->comment . PHP_EOL . 'class ' .
$plugin->class_name . ' extends ' .
$plugin->extends . PHP_EOL . '{' . PHP_EOL .
$plugin->main_class_code . PHP_EOL .
"}" . PHP_EOL,
$this->builder->allActive()
);
}
}

View File

@ -0,0 +1,570 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin;
use Joomla\CMS\Filesystem\Folder;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Language\Set;
use VDM\Joomla\Componentbuilder\Compiler\Language\Purge;
use VDM\Joomla\Componentbuilder\Compiler\Language\Translation;
use VDM\Joomla\Componentbuilder\Compiler\Language\Multilingual;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetExtension;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Languages;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Multilingual as BuilderMultilingual;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\File;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin\MainXMLInterface;
/**
* Joomla 3 Plugin Main XML Class
*
* @since 5.0.2
*/
final class MainXML implements MainXMLInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Set Class.
*
* @var Set
* @since 5.0.2
*/
protected Set $set;
/**
* The Purge Class.
*
* @var Purge
* @since 5.0.2
*/
protected Purge $purge;
/**
* The Translation Class.
*
* @var Translation
* @since 5.0.2
*/
protected Translation $translation;
/**
* The Multilingual Class.
*
* @var Multilingual
* @since 5.0.2
*/
protected Multilingual $multilingual;
/**
* The EventInterface Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The FieldsetExtension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* The ContentOne Class.
*
* @var ContentOne
* @since 5.0.2
*/
protected ContentOne $contentone;
/**
* The Languages Class.
*
* @var Languages
* @since 5.0.2
*/
protected Languages $languages;
/**
* The Multilingual Class.
*
* @var BuilderMultilingual
* @since 5.0.2
*/
protected BuilderMultilingual $buildermultilingual;
/**
* The Counter Class.
*
* @var Counter
* @since 5.0.2
*/
protected Counter $counter;
/**
* The File Class.
*
* @var File
* @since 5.0.2
*/
protected File $file;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Language $language The Language Class.
* @param Set $set The Set Class.
* @param Purge $purge The Purge Class.
* @param Translation $translation The Translation Class.
* @param Multilingual $multilingual The Multilingual Class.
* @param Event $event The EventInterface Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
* @param ContentOne $contentone The ContentOne Class.
* @param Languages $languages The Languages Class.
* @param BuilderMultilingual $buildermultilingual The Multilingual Class.
* @param Counter $counter The Counter Class.
* @param File $file The File Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Language $language, Set $set, Purge $purge,
Translation $translation, Multilingual $multilingual,
Event $event, FieldsetExtension $fieldsetextension,
ContentOne $contentone, Languages $languages,
BuilderMultilingual $buildermultilingual,
Counter $counter, File $file)
{
$this->config = $config;
$this->language = $language;
$this->set = $set;
$this->purge = $purge;
$this->translation = $translation;
$this->multilingual = $multilingual;
$this->event = $event;
$this->fieldsetextension = $fieldsetextension;
$this->contentone = $contentone;
$this->languages = $languages;
$this->buildermultilingual = $buildermultilingual;
$this->counter = $counter;
$this->file = $file;
}
/**
* Generates the main XML for the plugin.
*
* @param object $plugin The plugin object.
*
* @return string The generated XML.
* @since 5.0.2
*/
public function get(object $plugin): string
{
$config_fields = $this->buildConfigFields($plugin);
$add_component_path = $this->shouldAddComponentPath($plugin);
$language_files = $this->generateLanguageFiles($plugin);
$xml = $this->generateScriptAndSqlXml($plugin);
$xml .= $this->generateLanguageXml($plugin, $language_files);
$xml .= $this->generateFileXml($plugin, $language_files);
$xml .= $this->generateConfigXml($plugin, $config_fields, $add_component_path);
$xml .= $this->generateUpdateServerXml($plugin);
return $xml;
}
/**
* Build configuration fields XML.
*
* @param object $plugin The plugin object.
*
* @return array The configuration fields.
* @since 5.0.2
*/
protected function buildConfigFields(object $plugin): array
{
$configFields = [];
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields))
{
return $configFields;
}
$dbKey = 'yy';
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$xmlFields = $this->fieldsetextension->get($plugin, $fields, $dbKey);
if (isset($xmlFields) && StringHelper::check($xmlFields))
{
$configFields["{$fieldName}{$fieldset}"] = $xmlFields;
}
$dbKey++;
}
}
return $configFields;
}
/**
* Determine if the component path should be added.
*
* @param object $plugin The plugin object.
*
* @return bool True if the component path should be added, false otherwise.
* @since 5.0.2
*/
protected function shouldAddComponentPath(object $plugin): bool
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($plugin->config_fields) ||
!isset($plugin->fieldsets_paths) || !ArrayHelper::check($plugin->fieldsets_paths))
{
return false;
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
if (isset($plugin->fieldsets_paths["{$fieldName}{$fieldset}"]) &&
$plugin->fieldsets_paths["{$fieldName}{$fieldset}"] == 1)
{
return true;
}
}
}
return false;
}
/**
* Generate XML for script and SQL files.
*
* @param object $plugin The plugin object.
*
* @return string The XML for script and SQL files.
* @since 5.0.2
*/
protected function generateScriptAndSqlXml(object $plugin): string
{
$xml = '';
if ($plugin->add_install_script)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Scripts to run on installation -->';
$xml .= PHP_EOL . Indent::_(1) . '<scriptfile>script.php</scriptfile>';
}
if ($plugin->add_sql)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on install -->';
$xml .= PHP_EOL . Indent::_(1) . '<install>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/install.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</install>';
}
if ($plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on uninstall -->';
$xml .= PHP_EOL . Indent::_(1) . '<uninstall>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3) . '<file driver="mysql" charset="utf8">sql/mysql/uninstall.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</uninstall>';
}
return $xml;
}
/**
* Generate XML for language files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for language files.
* @since 5.0.2
*/
protected function generateLanguageXml(object $plugin, array $languageFiles): string
{
$xml = '';
if (ArrayHelper::check($languageFiles))
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Language files -->';
$xml .= PHP_EOL . Indent::_(1) . '<languages folder="language">';
foreach ($languageFiles as $addTag)
{
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/' . $addTag . '.plg_'
. strtolower((string) $plugin->group) . '_' . strtolower(
(string) $plugin->code_name
) . '.ini</language>';
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/' . $addTag . '.plg_'
. strtolower((string) $plugin->group) . '_' . strtolower(
(string) $plugin->code_name
) . '.sys.ini</language>';
}
$xml .= PHP_EOL . Indent::_(1) . '</languages>';
}
return $xml;
}
/**
* Generate the XML for the files.
*
* @param object $plugin The plugin object.
* @param array $languageFiles The language files.
*
* @return string The XML for the files.
* @since 5.0.2
*/
protected function generateFileXml(object $plugin, array $languageFiles): string
{
$files = Folder::files($plugin->folder_path);
$folders = Folder::folders($plugin->folder_path);
$ignore = ['sql', 'language', 'script.php', "{$plugin->file_name}.xml", "{$plugin->file_name}.php"];
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Plugin files -->';
$xml .= PHP_EOL . Indent::_(1) . '<files>';
$xml .= PHP_EOL . Indent::_(2) . "<filename plugin=\"{$plugin->file_name}\">{$plugin->file_name}.php</filename>";
foreach ($files as $file)
{
if (!in_array($file, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<filename>{$file}</filename>";
}
}
if (!empty($languageFiles))
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>language</folder>';
}
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>sql</folder>';
}
foreach ($folders as $folder)
{
if (!in_array($folder, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . "<folder>{$folder}</folder>";
}
}
$xml .= PHP_EOL . Indent::_(1) . '</files>';
return $xml;
}
/**
* Generate XML for configuration fields.
*
* @param object $plugin The plugin object.
* @param array $configFields The configuration fields.
* @param bool $addComponentPath Whether to add the component path.
*
* @return string The XML for configuration fields.
* @since 5.0.2
*/
protected function generateConfigXml(object $plugin, array $configFields, bool $addComponentPath): string
{
if (!isset($plugin->config_fields) || !ArrayHelper::check($configFields))
{
return '';
}
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Config parameters -->';
$xml .= $addComponentPath ? PHP_EOL . Indent::_(1) . '<config' : PHP_EOL . Indent::_(1) . '<config>';
if ($addComponentPath)
{
$xml .= PHP_EOL . Indent::_(2) . 'addrulepath="/administrator/components/com_' . $this->config->component_code_name . '/models/rules"';
$xml .= PHP_EOL . Indent::_(2) . 'addfieldpath="/administrator/components/com_' . $this->config->component_code_name . '/models/fields"';
$xml .= PHP_EOL . Indent::_(1) . '>';
}
foreach ($plugin->config_fields as $fieldName => $fieldsets)
{
$xml .= PHP_EOL . Indent::_(1) . "<fields name=\"{$fieldName}\">";
foreach ($fieldsets as $fieldset => $fields)
{
$label = $plugin->fieldsets_label["{$fieldName}{$fieldset}"] ?? $fieldset;
$xml .= PHP_EOL . Indent::_(1) . "<fieldset name=\"{$fieldset}\" label=\"{$label}\">";
if (isset($configFields["{$fieldName}{$fieldset}"]))
{
$xml .= $configFields["{$fieldName}{$fieldset}"];
}
$xml .= PHP_EOL . Indent::_(1) . '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . Indent::_(1) . '</config>';
return $xml;
}
/**
* Generate XML for update servers.
*
* @param object $plugin The plugin object.
*
* @return string The XML for update servers.
* @since 5.0.2
*/
protected function generateUpdateServerXml(object $plugin): string
{
$xml = '';
if ($plugin->add_update_server)
{
$xml = PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Update servers -->';
$xml .= PHP_EOL . Indent::_(1) . '<updateservers>';
$xml .= PHP_EOL . Indent::_(2) . '<server type="extension" priority="1" name="' . $plugin->official_name . '">' . $plugin->update_server_url . '</server>';
$xml .= PHP_EOL . Indent::_(1) . '</updateservers>';
}
return $xml;
}
/**
* Generate language files.
*
* @param object $plugin The plugin object.
*
* @return array The language files.
* @since 5.0.2
*/
protected function generateLanguageFiles(object $plugin): array
{
$languageFiles = [];
if (!$this->language->exist($plugin->key))
{
return $languageFiles;
}
$langContent = $this->language->getTarget($plugin->key);
$this->event->trigger('jcb_ce_onBeforeBuildPluginLang', [&$plugin, &$langContent]);
$values = array_unique($langContent);
$this->buildermultilingual->set('plugins', $this->multilingual->get($values));
$langTag = $this->config->get('lang_tag', 'en-GB');
$this->languages->set("plugins.{$langTag}.all", $langContent);
$this->language->setTarget($plugin->key, null);
$this->set->execute($values, $plugin->id, 'plugins');
$this->purge->execute($values, $plugin->id, 'plugins');
$this->event->trigger('jcb_ce_onBeforeBuildPluginLangFiles', [&$plugin]);
if ($this->languages->IsArray('plugins'))
{
foreach ($this->languages->get('plugins') as $tag => $areas)
{
$tag = trim($tag);
foreach ($areas as $area => $languageStrings)
{
$fileName = "{$tag}.plg_" . strtolower((string)$plugin->group) . '_' . strtolower((string)$plugin->code_name) . '.ini';
$total = count($values);
if ($this->translation->check($tag, $languageStrings, $total, $fileName))
{
$lang = array_map(
fn($langString, $placeholder) => "{$placeholder}=\"{$langString}\"",
array_values($languageStrings),
array_keys($languageStrings)
);
$path = "{$plugin->folder_path}/language/{$tag}/";
if (!Folder::exists($path))
{
Folder::create($path);
$this->counter->folder++;
}
$this->file->write($path . $fileName, implode(PHP_EOL, $lang));
$this->file->write(
$path . $tag . '.plg_' . strtolower((string)$plugin->group) . '_' . strtolower((string)$plugin->code_name) . '.sys.ini',
implode(PHP_EOL, $lang)
);
$this->counter->line += count($lang);
unset($lang);
$languageFiles[$tag] = $tag;
}
}
}
}
return $languageFiles;
}
}

View File

@ -0,0 +1,71 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Builder;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ProviderInterface;
/**
* Plugin Provider Class for Joomla 3
*
* @since 5.0.2
*/
final class Provider implements ProviderInterface
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The ContentOne Class.
*
* @var Builder
* @since 5.0.2
*/
protected Builder $builder;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param Builder $builder The Content One Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, Builder $builder)
{
$this->placeholder = $placeholder;
$this->builder = $builder;
}
/**
* Get the updated provider for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The provider content.
*
* @since 5.0.2
*/
public function get(object $plugin): string
{
return ''; // no provider in Joomla 3
}
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -0,0 +1,34 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Builder;
use VDM\Joomla\Abstraction\Registry\Traits\IsArray;
use VDM\Joomla\Interfaces\Registryinterface;
use VDM\Joomla\Abstraction\Registry;
/**
* Multilingual Builder Class
*
* @since 5.0.2
*/
final class Multilingual extends Registry implements Registryinterface
{
/**
* Is an Array
*
* @since 5.0.2
*/
use IsArray;
}

View File

@ -0,0 +1,78 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Creator;
use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetDynamic;
/**
* Extension Fieldset Creator Class
*
* @since 5.0.2
*/
final class FieldsetExtension
{
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The FieldsetDynamic Class.
*
* @var FieldsetDynamic
* @since 5.0.2
*/
protected FieldsetDynamic $fieldsetdynamic;
/**
* Constructor.
*
* @param Placeholder $placeholder The Placeholder Class.
* @param FieldsetDynamic $fieldsetdynamic The Fieldset Dynamic Class.
*
* @since 5.0.2
*/
public function __construct(Placeholder $placeholder, FieldsetDynamic $fieldsetdynamic)
{
$this->placeholder = $placeholder;
$this->fieldsetdynamic = $fieldsetdynamic;
}
/**
* build field set for an extention
*
* @param object $extension The extention object
* @param array $fields The fields to build
* @param string $dbkey The database key
*
* @return string The fields set in xml
*
* @since 5.0.2
*/
public function get(object $extension, array $fields, string $dbkey = 'zz'): string
{
// get global placeholders
$placeholder = $this->placeholder->get();
// build the fieldset
return $this->fieldsetdynamic->get(
$fields, $extension->lang_prefix, $extension->key, $extension->key,
$placeholder, $dbkey
);
}
}

View File

@ -115,6 +115,22 @@ final class InstallScript implements GetScriptInterface
*/
protected array $postflightBucket = ['install' => [], 'uninstall' => [], 'discover_install' => [], 'update' => []];
/**
* The paths of the old plugin class files
*
* @var array
* @since 5.0.2
*/
protected array $removeFilePaths = [];
/**
* The paths of the old plugin folders
*
* @var array
* @since 5.0.2
*/
protected array $removeFolderPaths = [];
/**
* get install script
*
@ -128,6 +144,10 @@ final class InstallScript implements GetScriptInterface
// purge the object
$this->rest();
// set the remove path
$this->removeFilePaths = $extension->remove_file_paths ?? [];
$this->removeFolderPaths = $extension->remove_folder_paths ?? [];
// loop over methods and types
foreach ($this->methods as $method)
{
@ -171,6 +191,8 @@ final class InstallScript implements GetScriptInterface
*/
protected function rest(): void
{
$this->removeFilePaths = [];
$this->removeFolderPaths = [];
$this->construct = [];
$this->install = [];
$this->update = [];
@ -210,6 +232,9 @@ final class InstallScript implements GetScriptInterface
// load postflight method if set
$script .= $this->flight('postflight');
// load remove files method
$script .= $this->removeFiles();
// close the class
$script .= PHP_EOL . '}' . PHP_EOL;
@ -229,9 +254,11 @@ final class InstallScript implements GetScriptInterface
// start build
$script = PHP_EOL . 'use Joomla\CMS\Factory;';
$script .= PHP_EOL . 'use Joomla\CMS\Version;';
$script .= PHP_EOL . 'use Joomla\CMS\Installer\InstallerAdapter;';
$script .= PHP_EOL . 'use Joomla\CMS\Language\Text;';
$script .= PHP_EOL . 'use Joomla\CMS\Filesystem\File;';
$script .= PHP_EOL . 'use Joomla\CMS\Filesystem\Folder;' . PHP_EOL;
$script .= PHP_EOL . 'use Joomla\Filesystem\File;';
$script .= PHP_EOL . 'use Joomla\Filesystem\Folder;' . PHP_EOL;
$script .= PHP_EOL . '/**';
$script .= PHP_EOL . ' * ' . $extension->official_name
. ' script file.';
@ -252,26 +279,87 @@ final class InstallScript implements GetScriptInterface
*/
protected function construct(): string
{
// return empty string if not set
if (!ArrayHelper::check($this->construct))
{
return '';
}
// the __construct script
$script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script = PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' *' . Line::_(__Line__, __Class__)
.' The CMS Application.';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @since 4.4.2';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected $app;';
$script .= PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' *' . Line::_(__Line__, __Class__)
.' A list of files to be deleted';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @var array';
$script .= PHP_EOL . Indent::_(1) . ' * @since 3.6';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected array $deleteFiles = [];';
$script .= PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' *' . Line::_(__Line__, __Class__)
.' A list of folders to be deleted';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @var array';
$script .= PHP_EOL . Indent::_(1) . ' * @since 3.6';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected array $deleteFolders = [];';
$script .= PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' * Constructor';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script';
. ' * @param InstallerAdapter $adapter The object responsible for running this script';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1)
. 'public function __construct($adapter)';
$script .= PHP_EOL . Indent::_(1) . '{';
$script .= PHP_EOL . implode(PHP_EOL . PHP_EOL, $this->construct);
$script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__)
. ' get application';
$script .= PHP_EOL . Indent::_(2)
. '$this->app = Factory::getApplication();' . PHP_EOL;
if (ArrayHelper::check($this->construct))
{
$script .= PHP_EOL . implode(PHP_EOL . PHP_EOL, $this->construct);
}
// check if custom remove file is set
if ($this->removeFilePaths !== [] && strpos($script, '$this->deleteFiles') === false)
{
// add the default delete files
foreach ($this->removeFilePaths as $filePath)
{
$script .= PHP_EOL . Indent::_(2) . "if (is_file(JPATH_ROOT . '$filePath'))";
$script .= PHP_EOL . Indent::_(2) . "{";
$script .= PHP_EOL . Indent::_(3) . "\$this->deleteFiles[] = '$filePath';";
$script .= PHP_EOL . Indent::_(2) . "}";
}
}
// check if custom remove file is set
if ($this->removeFolderPaths !== [] && strpos($script, '$this->deleteFolders') === false)
{
// add the default delete folders
foreach ($this->removeFolderPaths as $folderPath)
{
$script .= PHP_EOL . Indent::_(2) . "if (is_dir(JPATH_ROOT . '$folderPath'))";
$script .= PHP_EOL . Indent::_(2) . "{";
$script .= PHP_EOL . Indent::_(3) . "\$this->deleteFolders[] = '$folderPath';";
$script .= PHP_EOL . Indent::_(2) . "}";
}
}
// close the function
$script .= PHP_EOL . Indent::_(1) . '}';
// add remove files
$this->preflightBucket['bottom'][] = Indent::_(2) . '//' . Line::_(__Line__, __Class__)
.' remove old files and folders';
$this->preflightBucket['bottom'][] = Indent::_(2) . '$this->removeFiles();';
return $script;
}
@ -295,7 +383,7 @@ final class InstallScript implements GetScriptInterface
$script .= PHP_EOL . Indent::_(1) . " * Called on $name";
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script';
. ' * @param InstallerAdapter $adapter The object responsible for running this script';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @return boolean True on success';
@ -325,12 +413,6 @@ final class InstallScript implements GetScriptInterface
*/
protected function flight(string $name): string
{
// return empty string if not set
if (empty($this->{$name . 'Active'}))
{
return '';
}
// the pre/post function types
$script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1)
@ -339,7 +421,7 @@ final class InstallScript implements GetScriptInterface
$script .= PHP_EOL . Indent::_(1)
. ' * @param string $route Which action is happening (install|uninstall|discover_install|update)';
$script .= PHP_EOL . Indent::_(1)
. ' * @param Joomla\CMS\Installer\InstallerAdapter $adapter The object responsible for running this script';
. ' * @param InstallerAdapter $adapter The object responsible for running this script';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1)
. ' * @return boolean True on success';
@ -348,9 +430,9 @@ final class InstallScript implements GetScriptInterface
. $name . '($route, $adapter)';
$script .= PHP_EOL . Indent::_(1) . '{';
$script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__)
. ' get application';
. ' set application to local method var, just use $this->app in future [we will drop $app in J6]';
$script .= PHP_EOL . Indent::_(2)
. '$app = Factory::getApplication();' . PHP_EOL;
. '$app = $this->app;' . PHP_EOL;
// add the default version check (TODO) must make this dynamic
if ('preflight' === $name)
@ -358,37 +440,88 @@ final class InstallScript implements GetScriptInterface
$script .= PHP_EOL . Indent::_(2) . '//' . Line::_(__Line__, __Class__)
.' the default for both install and update';
$script .= PHP_EOL . Indent::_(2)
. '$jversion = new JVersion();';
. '$jversion = new Version();';
$script .= PHP_EOL . Indent::_(2)
. "if (!\$jversion->isCompatible('3.8.0'))";
. "if (!\$jversion->isCompatible('5.0.0'))";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3)
. "\$app->enqueueMessage('Please upgrade to at least Joomla! 3.8.0 before continuing!', 'error');";
. "\$app->enqueueMessage('Please upgrade to at least Joomla! 5.0.0 before continuing!', 'error');";
$script .= PHP_EOL . Indent::_(3) . 'return false;';
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
}
// now add the scripts
foreach ($this->{$name . 'Bucket'} as $route => $_script)
if (!empty($this->{$name . 'Active'}))
{
if (ArrayHelper::check($_script))
// now add the scripts
foreach ($this->{$name . 'Bucket'} as $route => $_script)
{
// set the if and script
$script .= PHP_EOL . Indent::_(2) . "if ('" . $route
. "' === \$route)";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . implode(
PHP_EOL . PHP_EOL, $_script
);
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
if (ArrayHelper::check($_script) && $route !== 'bottom')
{
// set the if and script
$script .= PHP_EOL . Indent::_(2) . "if ('" . $route
. "' === \$route)";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . implode(
PHP_EOL . PHP_EOL, $_script
);
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
}
}
}
if (isset($this->{$name . 'Bucket'}['bottom']) && ArrayHelper::check($this->{$name . 'Bucket'}['bottom']))
{
$script .= PHP_EOL . implode(
PHP_EOL , $this->{$name . 'Bucket'}['bottom']
) . PHP_EOL;
}
// return true
$script .= PHP_EOL . Indent::_(2) . 'return true;';
// close the function
$script .= PHP_EOL . Indent::_(1) . '}';
return $script;
}
/**
* build remove files methods
*
* @return string
* @since 5.0.2
*/
protected function removeFiles(): string
{
$script = PHP_EOL . PHP_EOL . Indent::_(1) . '/**';
$script .= PHP_EOL . Indent::_(1) . ' * Remove the files and folders in the given array from';
$script .= PHP_EOL . Indent::_(1) . ' *';
$script .= PHP_EOL . Indent::_(1) . ' * @return void';
$script .= PHP_EOL . Indent::_(1) . ' * @since 5.0.2';
$script .= PHP_EOL . Indent::_(1) . ' */';
$script .= PHP_EOL . Indent::_(1) . 'protected function removeFiles()';
$script .= PHP_EOL . Indent::_(1) . '{';
$script .= PHP_EOL . Indent::_(2) . 'if (!empty($this->deleteFiles))';
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3) . 'foreach ($this->deleteFiles as $file)';
$script .= PHP_EOL . Indent::_(3) . '{';
$script .= PHP_EOL . Indent::_(4) . 'if (is_file(JPATH_ROOT . $file) && !File::delete(JPATH_ROOT . $file))';
$script .= PHP_EOL . Indent::_(4) . '{';
$script .= PHP_EOL . Indent::_(5) . 'echo Text::sprintf(\'JLIB_INSTALLER_ERROR_FILE_FOLDER\', $file) . \'<br>\';';
$script .= PHP_EOL . Indent::_(4) . '}';
$script .= PHP_EOL . Indent::_(3) . '}';
$script .= PHP_EOL . Indent::_(2) . '}';
$script .= PHP_EOL . PHP_EOL . Indent::_(2) . 'if (!empty($this->deleteFolders))';
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3) . 'foreach ($this->deleteFolders as $folder)';
$script .= PHP_EOL . Indent::_(3) . '{';
$script .= PHP_EOL . Indent::_(4) . 'if (is_dir(JPATH_ROOT . $folder) && !Folder::delete(JPATH_ROOT . $folder))';
$script .= PHP_EOL . Indent::_(4) . '{';
$script .= PHP_EOL . Indent::_(5) . 'echo Text::sprintf(\'JLIB_INSTALLER_ERROR_FILE_FOLDER\', $folder) . \'<br>\';';
$script .= PHP_EOL . Indent::_(4) . '}';
$script .= PHP_EOL . Indent::_(3) . '}';
$script .= PHP_EOL . Indent::_(2) . '}';
$script .= PHP_EOL . Indent::_(1) . '}';
return $script;
}
}

View File

@ -360,10 +360,10 @@ final class InstallScript implements GetScriptInterface
$script .= PHP_EOL . Indent::_(2)
. '$jversion = new JVersion();';
$script .= PHP_EOL . Indent::_(2)
. "if (!\$jversion->isCompatible('3.8.0'))";
. "if (!\$jversion->isCompatible('4.0.0'))";
$script .= PHP_EOL . Indent::_(2) . '{';
$script .= PHP_EOL . Indent::_(3)
. "\$app->enqueueMessage('Please upgrade to at least Joomla! 3.8.0 before continuing!', 'error');";
. "\$app->enqueueMessage('Please upgrade to at least Joomla! 4.0.0 before continuing!', 'error');";
$script .= PHP_EOL . Indent::_(3) . 'return false;';
$script .= PHP_EOL . Indent::_(2) . '}' . PHP_EOL;
}

View File

@ -44,6 +44,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Service\BuilderLZ;
use VDM\Joomla\Componentbuilder\Compiler\Service\Creator;
use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitectureController;
use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitectureModel;
use VDM\Joomla\Componentbuilder\Compiler\Service\ArchitecturePlugin;
use VDM\Joomla\Componentbuilder\Service\Gitea;
use VDM\Joomla\Gitea\Service\Utilities as GiteaUtilities;
use VDM\Joomla\Gitea\Service\Settings as GiteaSettings;
@ -143,6 +144,7 @@ abstract class Factory extends ExtendingFactory implements FactoryInterface
->registerServiceProvider(new Creator())
->registerServiceProvider(new ArchitectureController())
->registerServiceProvider(new ArchitectureModel())
->registerServiceProvider(new ArchitecturePlugin())
->registerServiceProvider(new Gitea())
->registerServiceProvider(new GiteaUtilities())
->registerServiceProvider(new GiteaSettings())

View File

@ -1049,8 +1049,6 @@ class Get
$this->langTag = CFactory::_('Config')->get('lang_tag', 'en-GB');
// also set the helper class langTag (for safeStrings)
ComponentbuilderHelper::$langTag = CFactory::_('Config')->get('lang_tag', 'en-GB');
// setup the main language array
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')] = [];
// check if we have Tidy enabled @deprecated
$this->tidy = CFactory::_('Config')->get('tidy', false);
// set the field type builder @deprecated
@ -2049,219 +2047,25 @@ class Get
*
* @param array $values The lang strings to get
*
*
* @return void
*
* @return array|null
* @deprecated 3.4 Use CFactory::_('Language.Multilingual')->get($values);
*/
public function getMultiLangStrings($values)
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->from(
$this->db->quoteName(
'#__componentbuilder_language_translation', 'a'
)
);
if (ArrayHelper::check($values))
{
$query->select(
$this->db->quoteName(
array('a.id', 'a.translation', 'a.source', 'a.components',
'a.modules', 'a.plugins', 'a.published')
)
);
$query->where(
$this->db->quoteName('a.source') . ' IN (' . implode(
',', array_map(
fn($a) => $this->db->quote($a), $values
)
) . ')'
);
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
return $this->db->loadAssocList('source');
}
}
return false;
return CFactory::_('Language.Multilingual')->get($values);
}
/**
* Set the Current language values to DB
*
*
* @return void
*
* @deprecated 3.4 Use CFactory::_('Language.Set')->execute(...);
*/
public function setLangPlaceholders($strings, int $target_id,
$target = 'components'
)
{
$counterInsert = 0;
$counterUpdate = 0;
$today = Factory::getDate()->toSql();
foreach (
$this->languages[$target][CFactory::_('Config')->get('lang_tag', 'en-GB')] as $area => $placeholders
)
{
foreach ($placeholders as $placeholder => $string)
{
// to keep or remove
$remove = false;
// build the translations
if (StringHelper::check($string)
&& isset($this->multiLangString[$string]))
{
// make sure we have converted the string to array
if (isset($this->multiLangString[$string]['translation'])
&& JsonHelper::check(
$this->multiLangString[$string]['translation']
))
{
$this->multiLangString[$string]['translation']
= json_decode(
(string) $this->multiLangString[$string]['translation'], true
);
}
// if we have an array continue
if (isset($this->multiLangString[$string]['translation'])
&& ArrayHelper::check(
$this->multiLangString[$string]['translation']
))
{
// great lets build the multi languages strings
foreach (
$this->multiLangString[$string]['translation'] as
$translations
)
{
if (isset($translations['language'])
&& isset($translations['translation']))
{
// build arrays
if (!isset($this->languages[$target][$translations['language']]))
{
$this->languages[$target][$translations['language']]
= [];
}
if (!isset($this->languages[$target][$translations['language']][$area]))
{
$this->languages[$target][$translations['language']][$area]
= [];
}
$this->languages[$target][$translations['language']][$area][$placeholder]
= CFactory::_('Language')->fix($translations['translation']);
}
}
}
else
{
// remove this string not to be checked again
$remove = true;
}
}
// do the database management
if (StringHelper::check($string)
&& ($key = array_search($string, $strings)) !== false)
{
if (isset($this->multiLangString[$string]))
{
// update the existing placeholder in db
$id = $this->multiLangString[$string]['id'];
if (JsonHelper::check(
$this->multiLangString[$string][$target]
))
{
$targets = (array) json_decode(
(string) $this->multiLangString[$string][$target], true
);
// check if we should add the target ID
if (in_array($target_id, $targets))
{
// only skip the update if the string is published and has the target ID
if ($this->multiLangString[$string]['published']
== 1)
{
continue;
}
}
else
{
$targets[] = $target_id;
}
}
else
{
$targets = array($target_id);
}
// start the bucket for this lang
$this->setUpdateExistingLangStrings(
$id, $target, $targets, 1, $today, $counterUpdate
);
$counterUpdate++;
// load to db
$this->setExistingLangStrings(50);
// remove string if needed
if ($remove)
{
unset($this->multiLangString[$string]);
}
}
else
{
// add the new lang placeholder to the db
if (!isset($this->newLangStrings[$target]))
{
$this->newLangStrings[$target] = [];
}
$this->newLangStrings[$target][$counterInsert]
= [];
$this->newLangStrings[$target][$counterInsert][]
= $this->db->quote(
json_encode(array($target_id))
); // 'target'
$this->newLangStrings[$target][$counterInsert][]
= $this->db->quote(
$string
); // 'source'
$this->newLangStrings[$target][$counterInsert][]
= $this->db->quote(
1
); // 'published'
$this->newLangStrings[$target][$counterInsert][]
= $this->db->quote(
$today
); // 'created'
$this->newLangStrings[$target][$counterInsert][]
= $this->db->quote(
(int) $this->user->id
); // 'created_by'
$this->newLangStrings[$target][$counterInsert][]
= $this->db->quote(
1
); // 'version'
$this->newLangStrings[$target][$counterInsert][]
= $this->db->quote(
1
); // 'access'
$counterInsert++;
// load to db
$this->setNewLangStrings($target, 100);
}
// only set the string once
unset($strings[$key]);
}
}
}
// just to make sure all is done
$this->setExistingLangStrings();
$this->setNewLangStrings($target);
CFactory::_('Language.Set')->execute($strings, $target_id, $target);
}
/**
@ -2271,48 +2075,19 @@ class Get
* @param int $when To set when to update
*
* @return void
*
* @deprecated 3.4
*/
protected function setNewLangStrings($target, $when = 1)
{
if (isset($this->newLangStrings[$target])
&& count(
(array) $this->newLangStrings[$target]
) >= $when)
{
// Create a new query object.
$query = $this->db->getQuery(true);
$continue = false;
// Insert columns.
$columns = array($target, 'source', 'published', 'created',
'created_by', 'version', 'access');
// Prepare the insert query.
$query->insert(
$this->db->quoteName('#__componentbuilder_language_translation')
);
$query->columns($this->db->quoteName($columns));
foreach ($this->newLangStrings[$target] as $values)
{
if (count((array) $values) == 7)
{
$query->values(implode(',', $values));
$continue = true;
}
else
{
// TODO line mismatch... should not happen
}
}
// clear the values array
$this->newLangStrings[$target] = [];
if (!$continue)
{
return false; // insure we dont continue if no values were loaded
}
// Set the query using our newly populated query object and execute it.
$this->db->setQuery($query);
$this->db->execute();
}
// set notice that we could not get a valid string from the target
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_HR_HTHREES_WARNINGHTHREE', __CLASS__), 'Error'
);
$this->app->enqueueMessage(
Text::sprintf(
'Use of a deprecated method (%s)!', __METHOD__
), 'Error'
);
}
/**
@ -2321,29 +2096,19 @@ class Get
* @param int $when To set when to update
*
* @return void
*
* @deprecated 3.4
*/
protected function setExistingLangStrings($when = 1)
{
if (count((array) $this->existingLangStrings) >= $when)
{
foreach ($this->existingLangStrings as $values)
{
// Create a new query object.
$query = $this->db->getQuery(true);
// Prepare the update query.
$query->update(
$this->db->quoteName(
'#__componentbuilder_language_translation'
)
)->set($values['fields'])->where($values['conditions']);
// Set the query using our newly populated query object and execute it.
$this->db->setQuery($query);
$this->db->execute();
}
// clear the values array
$this->existingLangStrings = [];
}
// set notice that we could not get a valid string from the target
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_HR_HTHREES_WARNINGHTHREE', __CLASS__), 'Error'
);
$this->app->enqueueMessage(
Text::sprintf(
'Use of a deprecated method (%s)!', __METHOD__
), 'Error'
);
}
/**
@ -2352,25 +2117,19 @@ class Get
* @param int $id To string ID to remove
*
* @return void
*
* @deprecated 3.4
*/
protected function removeExitingLangString($id)
{
// Create a new query object.
$query = $this->db->getQuery(true);
// delete all custom keys for user 1001.
$conditions = array(
$this->db->quoteName('id') . ' = ' . (int) $id
// set notice that we could not get a valid string from the target
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_HR_HTHREES_WARNINGHTHREE', __CLASS__), 'Error'
);
$query->delete(
$this->db->quoteName('#__componentbuilder_language_translation')
$this->app->enqueueMessage(
Text::sprintf(
'Use of a deprecated method (%s)!', __METHOD__
), 'Error'
);
$query->where($conditions);
$this->db->setQuery($query);
$this->db->execute();
}
/**
@ -2379,180 +2138,32 @@ class Get
* @param string $values the active strings
*
* @return void
*
* @deprecated 3.4 Use CFactory::_('Language.Purge')->execute(...);
*/
public function purgeLanuageStrings($values, $target_id,
$target = 'components'
)
public function purgeLanuageStrings($values, $target_id, $target = 'components')
{
// the target types are
$target_types = array('components' => 'components',
'modules' => 'modules',
'plugins' => 'plugins');
// make sure we only work with preset targets
if (isset($target_types[$target]))
{
// remove the current target
unset($target_types[$target]);
// Create a new query object.
$query = $this->db->getQuery(true);
$query->from(
$this->db->quoteName(
'#__componentbuilder_language_translation', 'a'
)
);
$query->select(
$this->db->quoteName(
array('a.id', 'a.translation', 'a.components', 'a.modules',
'a.plugins')
)
);
// get all string that are not linked to this component
$query->where(
$this->db->quoteName('a.source') . ' NOT IN (' . implode(
',', array_map(
fn($a) => $this->db->quote($a), $values
)
) . ')'
);
$query->where($this->db->quoteName('a.published') . ' = 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
$counterUpdate = 0;
$otherStrings = $this->db->loadAssocList();
$today = Factory::getDate()->toSql();
foreach ($otherStrings as $item)
{
if (JsonHelper::check($item[$target]))
{
$targets = (array) json_decode((string) $item[$target], true);
// if component is not found ignore this string, and do nothing
if (($key = array_search($target_id, $targets))
!== false)
{
// first remove the component from the string
unset($targets[$key]);
// check if there are more components
if (ArrayHelper::check($targets))
{
// just update the string to unlink the current component
$this->setUpdateExistingLangStrings(
$item['id'], $target, $targets, 1, $today,
$counterUpdate
);
$counterUpdate++;
// load to db
$this->setExistingLangStrings(50);
}
// check if this string has been worked on or is linked to other extensions
else
{
// the action (1 = remove, 2 = archive, 0 = do nothing)
$action_with_string = 1;
// now check if it is linked to other extensions
foreach ($target_types as $other_target)
{
// just one linked extension type is enough to stop the search
if ($action_with_string
&& JsonHelper::check(
$item[$other_target]
))
{
$other_targets = (array) json_decode(
(string) $item[$other_target], true
);
// check if linked to other extensions
if (ArrayHelper::check(
$other_targets
))
{
$action_with_string
= 0; // do nothing
}
}
}
// check we should just archive or remove string
if ($action_with_string
&& JsonHelper::check(
$item['translation']
))
{
$translation = json_decode(
(string) $item['translation'], true
);
if (ArrayHelper::check(
$translation
))
{
// only archive the item and update the string to unlink the current component
$this->setUpdateExistingLangStrings(
$item['id'], $target, $targets, 2,
$today, $counterUpdate
);
$counterUpdate++;
// load to db
$this->setExistingLangStrings(50);
$action_with_string
= 2; // we archived it
}
}
// remove the string since no translation found and not linked to any other extensions
if ($action_with_string == 1)
{
$this->removeExitingLangString($item['id']);
}
}
}
}
}
// load to db
$this->setExistingLangStrings();
}
}
CFactory::_('Language.Purge')->execute($values, $target_id, $target);
}
/**
* just to add lang string to the existing Lang Strings array
*
* @return void
*
* @deprecated 3.4
*/
protected function setUpdateExistingLangStrings($id, $target, $targets,
$published, $today, $counterUpdate
)
{
// start the bucket for this lang
$this->existingLangStrings[$counterUpdate] = [];
$this->existingLangStrings[$counterUpdate]['id'] = (int) $id;
$this->existingLangStrings[$counterUpdate]['conditions'] = [];
$this->existingLangStrings[$counterUpdate]['conditions'][]
= $this->db->quoteName(
'id'
) . ' = ' . $this->db->quote($id);
$this->existingLangStrings[$counterUpdate]['fields'] = [];
$this->existingLangStrings[$counterUpdate]['fields'][]
= $this->db->quoteName(
$target
) . ' = ' . $this->db->quote(json_encode($targets));
$this->existingLangStrings[$counterUpdate]['fields'][]
= $this->db->quoteName(
'published'
) . ' = ' . $this->db->quote($published);
$this->existingLangStrings[$counterUpdate]['fields'][]
= $this->db->quoteName(
'modified'
) . ' = ' . $this->db->quote($today);
$this->existingLangStrings[$counterUpdate]['fields'][]
= $this->db->quoteName(
'modified_by'
) . ' = ' . $this->db->quote((int) $this->user->id);
// set notice that we could not get a valid string from the target
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_HR_HTHREES_WARNINGHTHREE', __CLASS__), 'Error'
);
$this->app->enqueueMessage(
Text::sprintf(
'Use of a deprecated method (%s)!', __METHOD__
), 'Error'
);
}
/**
@ -2784,26 +2395,15 @@ class Get
*/
public function getPluginXMLTemplate(&$plugin)
{
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<extension type="plugin" version="'
. CFactory::_('Config')->joomla_versions[CFactory::_('Config')->joomla_version]['xml_version'] . '" group="'
. strtolower((string) $plugin->group) . '" method="upgrade">';
$xml .= PHP_EOL . Indent::_(1) . '<name>' . $plugin->lang_prefix
. '</name>';
$xml .= PHP_EOL . Indent::_(1) . '<creationDate>' . Placefix::_h('BUILDDATE') . '</creationDate>';
$xml .= PHP_EOL . Indent::_(1) . '<author>' . Placefix::_h('AUTHOR') . '</author>';
$xml .= PHP_EOL . Indent::_(1) . '<authorEmail>' . Placefix::_h('AUTHOREMAIL') . '</authorEmail>';
$xml .= PHP_EOL . Indent::_(1) . '<authorUrl>' . Placefix::_h('AUTHORWEBSITE') . '</authorUrl>';
$xml .= PHP_EOL . Indent::_(1) . '<copyright>' . Placefix::_h('COPYRIGHT') . '</copyright>';
$xml .= PHP_EOL . Indent::_(1) . '<license>' . Placefix::_h('LICENSE') . '</license>';
$xml .= PHP_EOL . Indent::_(1) . '<version>' . $plugin->plugin_version
. '</version>';
$xml .= PHP_EOL . Indent::_(1) . '<description>' . $plugin->lang_prefix
. '_XML_DESCRIPTION</description>';
$xml .= Placefix::_h('MAINXML');
$xml .= PHP_EOL . '</extension>';
return $xml;
// set notice that we could not get a valid string from the target
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_HR_HTHREES_WARNINGHTHREE', __CLASS__), 'Error'
);
$this->app->enqueueMessage(
Text::sprintf(
'Use of a deprecated method (%s)!', __METHOD__
), 'Error'
);
}
/**

View File

@ -2227,7 +2227,7 @@ class Infusion extends Interpretation
// FIELDSET_ . $file.$field_name.$fieldset
CFactory::_('Compiler.Builder.Content.Multi')->set($module->key .
'|FIELDSET_' . $file . $field_name . $fieldset,
$this->getExtensionFieldsetXML(
CFactory::_('Compiler.Creator.Fieldset.Extension')->get(
$module, $fields
)
);
@ -2246,68 +2246,10 @@ class Infusion extends Interpretation
}
}
}
// infuse plugin data if set
if (CFactory::_('Joomlaplugin.Data')->exists())
{
foreach (CFactory::_('Joomlaplugin.Data')->get() as $plugin)
{
if (ObjectHelper::check($plugin))
{
// Trigger Event: jcb_ce_onBeforeInfusePluginData
CFactory::_('Event')->trigger(
'jcb_ce_onBeforeInfusePluginData', [&$plugin]
);
CFactory::_('Config')->build_target = $plugin->key;
CFactory::_('Config')->lang_target = $plugin->key;
$this->langPrefix = $plugin->lang_prefix;
CFactory::_('Config')->set('lang_prefix', $plugin->lang_prefix);
// MAINCLASS
CFactory::_('Compiler.Builder.Content.Multi')->set($plugin->key . '|MAINCLASS',
$this->getPluginMainClass($plugin)
);
// only add install script if needed
if ($plugin->add_install_script)
{
// INSTALLCLASS
CFactory::_('Compiler.Builder.Content.Multi')->set($plugin->key . '|INSTALLCLASS',
CFactory::_('Extension.InstallScript')->get($plugin)
);
}
// FIELDSET
if (isset($plugin->form_files)
&& ArrayHelper::check(
$plugin->form_files
))
{
foreach ($plugin->form_files as $file => $files)
{
foreach ($files as $field_name => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
// FIELDSET_ . $file.$field_name.$fieldset
CFactory::_('Compiler.Builder.Content.Multi')->set($plugin->key .
'|FIELDSET_' . $file . $field_name . $fieldset,
$this->getExtensionFieldsetXML(
$plugin, $fields
)
);
}
}
}
}
// MAINXML
CFactory::_('Compiler.Builder.Content.Multi')->set($plugin->key . '|MAINXML',
$this->getPluginMainXML($plugin)
);
// Trigger Event: jcb_ce_onAfterInfusePluginData
CFactory::_('Event')->trigger(
'jcb_ce_onAfterInfusePluginData', [&$plugin]
);
}
}
}
// infuse plugin data if set
CFactory::_('Joomlaplugin.Infusion')->set();
// rest globals
CFactory::_('Config')->build_target = $_backup_target;
CFactory::_('Config')->lang_target = $_backup_lang;
@ -2413,6 +2355,7 @@ class Infusion extends Interpretation
// add final list of needed lang strings
$componentName = CFactory::_('Component')->get('name');
$componentName = OutputFilter::cleanText($componentName);
$langTag = CFactory::_('Config')->get('lang_tag', 'en-GB');
// Trigger Event: jcb_ce_onBeforeLoadingAllLangStrings
CFactory::_('Event')->trigger(
@ -2426,20 +2369,20 @@ class Infusion extends Interpretation
if ($this->setLangAdmin($componentName))
{
$values[] = array_values(
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['admin']
CFactory::_('Compiler.Builder.Languages')->get("components.{$langTag}.admin")
);
$mainLangLoader['admin'] = count(
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['admin']
CFactory::_('Compiler.Builder.Languages')->get("components.{$langTag}.admin")
);
}
// check the admin system lang is set
if ($this->setLangAdminSys())
{
$values[] = array_values(
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['adminsys']
CFactory::_('Compiler.Builder.Languages')->get("components.{$langTag}.adminsys")
);
$mainLangLoader['adminsys'] = count(
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['adminsys']
CFactory::_('Compiler.Builder.Languages')->get("components.{$langTag}.adminsys")
);
}
// check the site lang is set
@ -2447,10 +2390,10 @@ class Infusion extends Interpretation
&& $this->setLangSite($componentName))
{
$values[] = array_values(
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['site']
CFactory::_('Compiler.Builder.Languages')->get("components.{$langTag}.site")
);
$mainLangLoader['site'] = count(
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['site']
CFactory::_('Compiler.Builder.Languages')->get("components.{$langTag}.site")
);
}
// check the site system lang is set
@ -2458,33 +2401,35 @@ class Infusion extends Interpretation
&& $this->setLangSiteSys($componentName))
{
$values[] = array_values(
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['sitesys']
CFactory::_('Compiler.Builder.Languages')->get("components.{$langTag}.sitesys")
);
$mainLangLoader['sitesys'] = count(
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['sitesys']
CFactory::_('Compiler.Builder.Languages')->get("components.{$langTag}.sitesys")
);
}
$values = array_unique(ArrayHelper::merge($values));
// get the other lang strings if there is any
$this->multiLangString = $this->getMultiLangStrings($values);
CFactory::_('Compiler.Builder.Multilingual')->set('components',
CFactory::_('Language.Multilingual')->get($values)
);
// update insert the current lang in to DB
$this->setLangPlaceholders($values, CFactory::_('Config')->component_id);
CFactory::_('Language.Set')->execute($values, CFactory::_('Config')->component_id);
// remove old unused language strings
$this->purgeLanuageStrings($values, CFactory::_('Config')->component_id);
CFactory::_('Language.Purge')->execute($values, CFactory::_('Config')->component_id);
// path to INI file
$getPAth = CFactory::_('Utilities.Paths')->template_path . '/en-GB.com_admin.ini';
// Trigger Event: jcb_ce_onBeforeBuildAllLangFiles
CFactory::_('Event')->trigger(
'jcb_ce_onBeforeBuildAllLangFiles', [&$this->languages['components']]
'jcb_ce_onBeforeBuildAllLangFiles', ['components']
);
// now we insert the values into the files
if (ArrayHelper::check($this->languages['components']))
if (CFactory::_('Compiler.Builder.Languages')->IsArray("components"))
{
// rest xml array
$langXML = [];
foreach ($this->languages['components'] as $tag => $areas)
foreach (CFactory::_('Compiler.Builder.Languages')->get("components") as $tag => $areas)
{
// trim the tag
$tag = trim((string) $tag);
@ -2510,7 +2455,7 @@ class Infusion extends Interpretation
$file_name = $tag . '.com_' . CFactory::_('Config')->component_code_name . $t
. '.ini';
// check if language should be added
if ($this->shouldLanguageBeAdded(
if (CFactory::_('Language.Translation')->check(
$tag, $languageStrings, $mainLangLoader[$area],
$file_name
))

View File

@ -11097,8 +11097,11 @@ class Interpretation extends Fields
// sort the strings
ksort($langContent);
// load to global languages
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['admin']
= $langContent;
$langTag = CFactory::_('Config')->get('lang_tag', 'en-GB');
CFactory::_('Compiler.Builder.Languages')->set(
"components.{$langTag}.admin",
$langContent
);
// remove tmp array
CFactory::_('Language')->setTarget('admin', null);
@ -11187,8 +11190,11 @@ class Interpretation extends Fields
// sort the strings
ksort($langContent);
// load to global languages
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['site']
= $langContent;
$langTag = CFactory::_('Config')->get('lang_tag', 'en-GB');
CFactory::_('Compiler.Builder.Languages')->set(
"components.{$langTag}.site",
$langContent
);
// remove tmp array
CFactory::_('Language')->setTarget('site', null);
@ -11235,8 +11241,11 @@ class Interpretation extends Fields
// sort strings
ksort($langContent);
// load to global languages
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['sitesys']
= $langContent;
$langTag = CFactory::_('Config')->get('lang_tag', 'en-GB');
CFactory::_('Compiler.Builder.Languages')->set(
"components.{$langTag}.sitesys",
$langContent
);
// remove tmp array
CFactory::_('Language')->setTarget('sitesys', null);
@ -11272,8 +11281,11 @@ class Interpretation extends Fields
// sort strings
ksort($langContent);
// load to global languages
$this->languages['components'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['adminsys']
= $langContent;
$langTag = CFactory::_('Config')->get('lang_tag', 'en-GB');
CFactory::_('Compiler.Builder.Languages')->set(
"components.{$langTag}.adminsys",
$langContent
);
// remove tmp array
CFactory::_('Language')->setTarget('adminsys', null);
@ -23020,7 +23032,7 @@ class Interpretation extends Fields
foreach ($fieldsets as $fieldset => $fields)
{
// get the field set
$xmlFields = $this->getExtensionFieldsetXML(
$xmlFields = CFactory::_('Compiler.Creator.Fieldset.Extension')->get(
$module, $fields, $dbkey
);
// check if the custom script field must be set
@ -23066,29 +23078,32 @@ class Interpretation extends Fields
// get other languages
$values = array_unique($langContent);
// get the other lang strings if there is any
$this->multiLangString = $this->getMultiLangStrings($values);
CFactory::_('Compiler.Builder.Multilingual')->set('modules',
CFactory::_('Language.Multilingual')->get($values)
);
// start the modules language bucket (must rest every time)
$this->languages['modules'] = [];
$this->languages['modules'][CFactory::_('Config')->get('lang_tag', 'en-GB')] = [];
$this->languages['modules'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['all']
= $langContent;
$langTag = CFactory::_('Config')->get('lang_tag', 'en-GB');
CFactory::_('Compiler.Builder.Languages')->set(
"modules.{$langTag}.all",
$langContent
);
CFactory::_('Language')->setTarget($module->key, null);
// update insert the current lang in to DB
$this->setLangPlaceholders($values, $module->id, 'modules');
CFactory::_('Language.Set')->execute($values, $module->id, 'modules');
// remove old unused language strings
$this->purgeLanuageStrings($values, $module->id, 'modules');
CFactory::_('Language.Purge')->execute($values, $module->id, 'modules');
$total = count($values);
unset($values);
// Trigger Event: jcb_ce_onBeforeBuildModuleLangFiles
CFactory::_('Event')->trigger(
'jcb_ce_onBeforeBuildModuleLangFiles', [&$module, &$this->languages['modules']]
'jcb_ce_onBeforeBuildModuleLangFiles', [&$module]
);
// now we insert the values into the files
if (ArrayHelper::check($this->languages['modules']))
if (CFactory::_('Compiler.Builder.Languages')->IsArray('modules'))
{
foreach ($this->languages['modules'] as $tag => $areas)
foreach (CFactory::_('Compiler.Builder.Languages')->get('modules') as $tag => $areas)
{
// trim the tag
$tag = trim($tag);
@ -23096,7 +23111,7 @@ class Interpretation extends Fields
{
$file_name = $tag . '.' . $module->file_name . '.ini';
// check if language should be added
if ($this->shouldLanguageBeAdded(
if (CFactory::_('Language.Translation')->check(
$tag, $languageStrings, $total,
$file_name
))
@ -23392,391 +23407,40 @@ class Interpretation extends Fields
return $xml;
}
/**
* get Plugin Main Class
*
* @param object $plugin The plugin object
*
* @return string The fields set in xml
* @deprecated 3.4 CFactory::_('Architecture.Plugin.Extension')->get(...);
*/
public function getPluginMainClass(&$plugin)
{
return CFactory::_('Placeholder')->update(
PHP_EOL . $plugin->head . PHP_EOL .
$plugin->comment . PHP_EOL . 'class ' .
$plugin->class_name . ' extends ' .
$plugin->extends . PHP_EOL . '{' . PHP_EOL .
$plugin->main_class_code . PHP_EOL .
"}" . PHP_EOL,
CFactory::_('Compiler.Builder.Content.One')->allActive()
);
return CFactory::_('Architecture.Plugin.Extension')->get($plugin);
}
/**
* get Plugin Main XML
*
* @param object $plugin The plugin object
*
* @return string The xml
* @deprecated 3.4 CFactory::_('Architecture.Plugin.MainXML')->get(...);
*/
public function getPluginMainXML(&$plugin)
{
// set the custom table key
$dbkey = 'yy';
// build the xml
$xml = '';
// search if we must add the component path
$add_component_path = false;
// build the config fields
$config_fields = [];
if (isset($plugin->config_fields)
&& ArrayHelper::check(
$plugin->config_fields
))
{
foreach ($plugin->config_fields as $field_name => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
// get the field set
$xmlFields = $this->getExtensionFieldsetXML(
$plugin, $fields, $dbkey
);
// make sure the xml is set and a string
if (isset($xmlFields)
&& StringHelper::check($xmlFields))
{
$config_fields[$field_name . $fieldset] = $xmlFields;
}
$dbkey++;
// check if the fieldset path requiers component paths
if (!$add_component_path
&& isset(
$plugin->fieldsets_paths[$field_name . $fieldset]
)
&& $plugin->fieldsets_paths[$field_name . $fieldset]
== 1)
{
$add_component_path = true;
}
}
}
}
// switch to add the language xml
$addLang = [];
// now build the language files
if (CFactory::_('Language')->exist($plugin->key))
{
// get plugin lang content
$langContent = CFactory::_('Language')->getTarget($plugin->key);
// Trigger Event: jcb_ce_onBeforeBuildPluginLang
CFactory::_('Event')->trigger(
'jcb_ce_onBeforeBuildPluginLang', [&$plugin, &$langContent]
);
// get other languages
$values = array_unique($langContent);
// get the other lang strings if there is any
$this->multiLangString = $this->getMultiLangStrings($values);
// start the plugins language bucket (must rest every time)
$this->languages['plugins'] = [];
$this->languages['plugins'][CFactory::_('Config')->get('lang_tag', 'en-GB')] = [];
$this->languages['plugins'][CFactory::_('Config')->get('lang_tag', 'en-GB')]['all']
= $langContent;
CFactory::_('Language')->setTarget($plugin->key, null);
// update insert the current lang in to DB
$this->setLangPlaceholders($values, $plugin->id, 'plugins');
// remove old unused language strings
$this->purgeLanuageStrings($values, $plugin->id, 'plugins');
$total = count($values);
unset($values);
// Trigger Event: jcb_ce_onBeforeBuildPluginLangFiles
CFactory::_('Event')->trigger(
'jcb_ce_onBeforeBuildPluginLangFiles', [&$plugin, &$this->languages['plugins']]
);
// now we insert the values into the files
if (ArrayHelper::check($this->languages['plugins']))
{
foreach ($this->languages['plugins'] as $tag => $areas)
{
// trim the tag
$tag = trim($tag);
foreach ($areas as $area => $languageStrings)
{
$file_name = $tag . '.plg_' . strtolower((string) $plugin->group)
. '_'
. strtolower((string) $plugin->code_name) . '.ini';
// check if language should be added
if ($this->shouldLanguageBeAdded(
$tag, $languageStrings, $total,
$file_name
))
{
$lang = array_map(
fn($langstring, $placeholder) => $placeholder . '="' . $langstring . '"',
array_values($languageStrings),
array_keys($languageStrings)
);
// set path
$path = $plugin->folder_path . '/language/' . $tag
. '/';
// create path if not exist
if (!Folder::exists($path))
{
Folder::create($path);
// count the folder created
CFactory::_('Utilities.Counter')->folder++;
}
// add to language file
CFactory::_('Utilities.File')->write(
$path . $file_name,
implode(PHP_EOL, $lang)
);
CFactory::_('Utilities.File')->write(
$path . $tag . '.plg_' . strtolower(
(string) $plugin->group
)
. '_'
. strtolower((string) $plugin->code_name) . '.sys.ini',
implode(PHP_EOL, $lang)
);
// set the line counter
CFactory::_('Utilities.Counter')->line += count(
(array) $lang
);
unset($lang);
// trigger to add language
$addLang[$tag] = $tag;
}
}
}
}
}
// get all files and folders in plugin folder
$files = Folder::files($plugin->folder_path);
$folders = Folder::folders($plugin->folder_path);
// the files/folders to ignore
$ignore = array('sql', 'language', 'script.php',
$plugin->file_name . '.xml',
$plugin->file_name . '.php');
// should the scriptfile be added
if ($plugin->add_install_script)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Scripts to run on installation -->';
$xml .= PHP_EOL . Indent::_(1)
. '<scriptfile>script.php</scriptfile>';
}
// should the sql install be added
if ($plugin->add_sql)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on install; New in Joomla 1.5 -->';
$xml .= PHP_EOL . Indent::_(1) . '<install>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3)
. '<file driver="mysql" charset="utf8">sql/mysql/install.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</install>';
}
// should the sql uninstall be added
if ($plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Runs on uninstall; New in Joomla 1.5 -->';
$xml .= PHP_EOL . Indent::_(1) . '<uninstall>';
$xml .= PHP_EOL . Indent::_(2) . '<sql>';
$xml .= PHP_EOL . Indent::_(3)
. '<file driver="mysql" charset="utf8">sql/mysql/uninstall.sql</file>';
$xml .= PHP_EOL . Indent::_(2) . '</sql>';
$xml .= PHP_EOL . Indent::_(1) . '</uninstall>';
}
// should the language xml be added
if (ArrayHelper::check($addLang))
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Language files -->';
$xml .= PHP_EOL . Indent::_(1) . '<languages folder="language">';
// load all the language files to xml
foreach ($addLang as $addTag)
{
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/' . $addTag . '.plg_'
. strtolower((string) $plugin->group) . '_' . strtolower(
(string) $plugin->code_name
) . '.ini</language>';
$xml .= PHP_EOL . Indent::_(2) . '<language tag="'
. $addTag . '">' . $addTag . '/' . $addTag . '.plg_'
. strtolower((string) $plugin->group) . '_' . strtolower(
(string) $plugin->code_name
) . '.sys.ini</language>';
}
$xml .= PHP_EOL . Indent::_(1) . '</languages>';
}
// add the plugin files
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Plugin files -->';
$xml .= PHP_EOL . Indent::_(1) . '<files>';
$xml .= PHP_EOL . Indent::_(2) . '<filename plugin="'
. $plugin->file_name . '">' . $plugin->file_name
. '.php</filename>';
// add other files found
if (ArrayHelper::check($files))
{
foreach ($files as $file)
{
// only add what is not ignored
if (!in_array($file, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . '<filename>' . $file
. '</filename>';
}
}
}
// add language folder
if (ArrayHelper::check($addLang))
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>language</folder>';
}
// add sql folder
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>sql</folder>';
}
// add other files found
if (ArrayHelper::check($folders))
{
foreach ($folders as $folder)
{
// only add what is not ignored
if (!in_array($folder, $ignore))
{
$xml .= PHP_EOL . Indent::_(2) . '<folder>' . $folder
. '</folder>';
}
}
}
$xml .= PHP_EOL . Indent::_(1) . '</files>';
// now add the Config Params if needed
if (ArrayHelper::check($config_fields))
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Config parameter -->';
// only add if part of the component field types path is required
if ($add_component_path)
{
// add path to plugin rules and custom fields
$xml .= PHP_EOL . Indent::_(1) . '<config';
if (CFactory::_('Config')->get('joomla_version', 3) == 3)
{
$xml .= PHP_EOL . Indent::_(2)
. 'addrulepath="/administrator/components/com_'
. CFactory::_('Config')->component_code_name . '/models/rules"';
$xml .= PHP_EOL . Indent::_(2)
. 'addfieldpath="/administrator/components/com_'
. CFactory::_('Config')->component_code_name . '/models/fields"';
}
else
{
$xml .= PHP_EOL . Indent::_(3)
. 'addruleprefix="' . CFactory::_('Config')->namespace_prefix
. '\Component\\' . CFactory::_('Compiler.Builder.Content.One')->get('ComponentNamespace')
. '\Administrator\Rule"';
$xml .= PHP_EOL . Indent::_(3)
. 'addfieldprefix="' . CFactory::_('Config')->namespace_prefix
. '\Component\\' . CFactory::_('Compiler.Builder.Content.One')->get('ComponentNamespace')
. '\Administrator\Field">';
}
$xml .= PHP_EOL . Indent::_(1) . '>';
}
else
{
$xml .= PHP_EOL . Indent::_(1) . '<config>';
}
// add the fields
foreach ($plugin->config_fields as $field_name => $fieldsets)
{
$xml .= PHP_EOL . Indent::_(1) . '<fields name="' . $field_name
. '">';
foreach ($fieldsets as $fieldset => $fields)
{
// default to the field set name
$label = $fieldset;
if (isset($plugin->fieldsets_label[$field_name . $fieldset]))
{
$label = $plugin->fieldsets_label[$field_name . $fieldset];
}
// add path to plugin rules and custom fields
if (isset($plugin->fieldsets_paths[$field_name . $fieldset])
&& ($plugin->fieldsets_paths[$field_name . $fieldset] == 2
|| $plugin->fieldsets_paths[$field_name . $fieldset] == 3))
{
if (!isset($plugin->add_rule_path[$field_name . $fieldset]))
{
$plugin->add_rule_path[$field_name . $fieldset] =
'/plugins/' . strtolower((string) $plugin->group
) . '/' . strtolower((string) $plugin->code_name)
. '/rules';
}
if (!isset($plugin->add_field_path[$field_name . $fieldset]))
{
$plugin->add_field_path[$field_name . $fieldset] =
'/plugins/' . strtolower((string) $plugin->group
) . '/' . strtolower((string) $plugin->code_name)
. '/fields';
}
}
// add path to plugin rules and custom fields
if (isset($plugin->add_rule_path[$field_name . $fieldset])
|| isset($plugin->add_field_path[$field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(1) . '<!--'
. Line::_(__Line__, __Class__) . ' default paths of '
. $fieldset . ' fieldset points to the plugin -->';
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '"';
if (isset($plugin->add_rule_path[$field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addrulepath="' . $plugin->add_rule_path[$field_name . $fieldset] . '"';
}
if (isset($plugin->add_field_path[$field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addfieldpath="' . $plugin->add_field_path[$field_name . $fieldset] . '"';
}
$xml .= PHP_EOL . Indent::_(1) . '>';
}
else
{
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '">';
}
// load the fields
if (isset($config_fields[$field_name . $fieldset]))
{
$xml .= $config_fields[$field_name . $fieldset];
unset($config_fields[$field_name . $fieldset]);
}
$xml .= PHP_EOL . Indent::_(1) . '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . Indent::_(1) . '</config>';
}
// set update server if found
if ($plugin->add_update_server)
{
$xml .= PHP_EOL . PHP_EOL . Indent::_(1) . '<!--' . Line::_(
__LINE__,__CLASS__
) . ' Update servers -->';
$xml .= PHP_EOL . Indent::_(1) . '<updateservers>';
$xml .= PHP_EOL . Indent::_(2)
. '<server type="extension" priority="1" name="'
. $plugin->official_name . '">' . $plugin->update_server_url
. '</server>';
$xml .= PHP_EOL . Indent::_(1) . '</updateservers>';
}
return $xml;
return CFactory::_('Architecture.Plugin.MainXML')->get($plugin);
}
/**
* get power code
*
* @param object $power
*
* @return string
* @deprecated 3.4 (line 393 private Compiler.Power.Infusion->code())
*/
public function getPowerCode(&$power)
{
$code = [];
@ -23830,65 +23494,23 @@ class Interpretation extends Fields
* @param string $dbkey The database key
*
* @return string The fields set in xml
*
* @deprecated 3.4 CFactory::_('Compiler.Creator.Access.Sections.Joomla.Fields')->get(...);
*/
public function getExtensionFieldsetXML(&$extension, &$fields, $dbkey = 'zz')
public function getExtensionFieldsetXML(&$extension, &$fields, $dbkey = 'zz'): string
{
// get global placeholders
$placeholder = CFactory::_('Component.Placeholder')->get();
// build the fieldset
return CFactory::_('Compiler.Creator.Fieldset.Dynamic')->get(
$fields, $extension->lang_prefix, $extension->key, $extension->key,
$placeholder, $dbkey
);
return CFactory::_('Compiler.Creator.Fieldset.Extension')->get($extension, $fields, $dbkey);
}
/**
* check if a translation should be added
*
* @return bool
*
* @deprecated 3.4 Use CFactory::_('Language.Translation')->check(...);
*/
public function shouldLanguageBeAdded(&$tag, &$languageStrings, &$total, &$file_name)
{
// only log messages for none CFactory::_('Config')->get('lang_tag', 'en-GB') translations
if (CFactory::_('Config')->get('lang_tag', 'en-GB') !== $tag)
{
$langStringNr = count($languageStrings);
$langStringSum = MathHelper::bc(
'mul', $langStringNr, 100
);
$percentage = MathHelper::bc(
'div', $langStringSum, $total
);
$stringNAme = ($langStringNr == 1) ? '(string '
. $tag . ' translated)'
: '(strings ' . $tag . ' translated)';
// force load if debug lines are added
if (!CFactory::_('Config')->get('debug_line_nr', false))
{
// check if we should install this translation
if ($percentage < CFactory::_('Config')->percentage_language_add)
{
// languages that will be excluded
CFactory::_('Compiler.Builder.Language.Messages')->set("exclude.$file_name",
'<b>' . $total . '</b>(total '
. CFactory::_('Config')->get('lang_tag', 'en-GB') . ' strings) only <b>'
. $langStringNr . '</b>' . $stringNAme . ' = ' . $percentage
);
return false;
}
}
// languages that will be included
CFactory::_('Compiler.Builder.Language.Messages')->set("include.$file_name",
'<b>' . $total . '</b>(total '
. CFactory::_('Config')->get('lang_tag', 'en-GB') . ' strings) and <b>'
. $langStringNr . '</b>' . $stringNAme . ' = ' . $percentage
);
}
return true;
return CFactory::_('Language.Translation')->check($tag, $languageStrings, $total, $file_name);
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin;
/**
* Plugin Extension Interface
*
* @since 5.0.2
*/
interface ExtensionInterface
{
/**
* Get the updated placeholder content for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The updated placeholder content.
*
* @since 5.0.2
*/
public function get(object $plugin): string;
}

View File

@ -0,0 +1,33 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin;
/**
* Plugin Provider Interface
*
* @since 5.0.2
*/
interface ProviderInterface
{
/**
* Get the updated placeholder content for the given plugin.
*
* @param object $plugin The plugin object containing the necessary data.
*
* @return string The updated placeholder content.
*
* @since 5.0.2
*/
public function get(object $plugin): string;
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -0,0 +1,52 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Interfaces;
/**
* Plug-in Data Interface
*
* @since 5.0.2
*/
interface PluginDataInterface
{
/**
* Get the Joomla Plugin/s
*
* @param int|null $id the plugin id
*
* @return object|array|null if ID found it returns object, if no ID given it returns all set
* @since 3.2.0
*/
public function get(int $id = null);
/**
* Check if the Joomla Plugin/s exists
*
* @param int|null $id the plugin id
*
* @return bool if ID found it returns true, if no ID given it returns true if any are set
* @since 3.2.0
*/
public function exists(int $id = null): bool;
/**
* Set the Joomla Plugin
*
* @param int $id the plugin id
*
* @return bool true on success
* @since 3.2.0
*/
public function set(int $id): bool;
}

View File

@ -13,8 +13,9 @@ namespace VDM\Joomla\Componentbuilder\Compiler\JoomlaFive;
use Joomla\CMS\Factory;
use Joomla\Registry\Registry;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Event\DispatcherInterface;
use Joomla\Registry\Registry;
use VDM\Joomla\Utilities\Component\Helper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface;
@ -35,9 +36,9 @@ class Event implements EventInterface
protected $activePlugins = false;
/**
* The application to trigger and event TODO
* The dispatcher to get events
*
* @since 3.2.0
* @since 5.0.2
*/
protected $dispatcher;
@ -69,7 +70,7 @@ class Event implements EventInterface
}
}
$this->dispatcher = Factory::getApplication();
$this->dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
}
/**
@ -89,8 +90,13 @@ class Event implements EventInterface
{
try
{
// Trigger this compiler event.
$results = $this->dispatcher->triggerEvent($event, $data ?? []);
$data ??= [];
$listeners = $this->dispatcher->getListeners($event);
foreach ($listeners as $listener)
{
// Call the listener with the unpacked arguments
$listener(...$data);
}
}
catch (\Exception $e)
{

View File

@ -200,7 +200,7 @@ final class Header implements HeaderInterface
$headers = $this->getHeaders($context);
// add to all except the helper classes
if ('admin.helper' !== $context && 'site.helper' !== $context)
if ('admin.helper' !== $context && 'site.helper' !== $context && 'plugin.extension.header' !== $context && 'plugin.provider.header' !== $context)
{
$target = 'Administrator';
if ($this->config->get('build_target', 'admin') === 'site')
@ -238,7 +238,7 @@ final class Header implements HeaderInterface
if ((2 == $this->config->uikit || 1 == $this->config->uikit)
&& $this->uikitcomp->exists($codeName))
{
$headers[] = 'use Joomla\CMS\Filesystem\File;';
$headers[] = 'use Joomla\Filesystem\File;';
}
break;
@ -262,6 +262,10 @@ final class Header implements HeaderInterface
$headers[] = 'use Joomla\CMS\Helper\TagsHelper;';
break;
case 'plugin.provider.header':
$headers[] = "use {$this->NamespacePrefix}\\Plugin\\[[[PluginGroupNamespace]]]\\[[[PluginNamespace]]]\\Extension\\{$codeName};";
break;
default:
break;
}
@ -308,7 +312,7 @@ final class Header implements HeaderInterface
$headers[] = 'use Joomla\CMS\Access\Access;';
$headers[] = 'use Joomla\CMS\Access\Rules as AccessRules;';
$headers[] = 'use Joomla\CMS\Component\ComponentHelper;';
$headers[] = 'use Joomla\CMS\Filesystem\File;';
$headers[] = 'use Joomla\Filesystem\File;';
$headers[] = 'use Joomla\CMS\Language\Language;';
$headers[] = 'use Joomla\CMS\MVC\Model\BaseDatabaseModel;';
$headers[] = 'use Joomla\CMS\Object\CMSObject;';
@ -498,8 +502,8 @@ final class Header implements HeaderInterface
break;
case 'import.custom.model':
case 'import.model':
$headers[] = 'use Joomla\CMS\Filesystem\File;';
$headers[] = 'use Joomla\CMS\Filesystem\Folder;';
$headers[] = 'use Joomla\Filesystem\File;';
$headers[] = 'use Joomla\Filesystem\Folder;';
$headers[] = 'use Joomla\CMS\Filesystem\Path;';
$headers[] = 'use Joomla\CMS\Filter\OutputFilter;';
$headers[] = 'use Joomla\CMS\Installer\InstallerHelper;';
@ -548,6 +552,19 @@ final class Header implements HeaderInterface
$headers[] = 'use Joomla\CMS\Form\Field\###FORM_EXTENDS###;';
break;
case 'plugin.extension.header':
$headers = [];
break;
case 'plugin.provider.header':
$headers = [];
$headers[] = 'use Joomla\CMS\Factory;';
$headers[] = 'use Joomla\CMS\Plugin\PluginHelper;';
$headers[] = 'use Joomla\CMS\Extension\PluginInterface;';
$headers[] = 'use Joomla\Event\DispatcherInterface;';
$headers[] = 'use Joomla\DI\ServiceProviderInterface;';
$headers[] = 'use Joomla\DI\Container;';
break;
default:
break;
}

View File

@ -13,8 +13,9 @@ namespace VDM\Joomla\Componentbuilder\Compiler\JoomlaFour;
use Joomla\CMS\Factory;
use Joomla\Registry\Registry;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Event\DispatcherInterface;
use Joomla\Registry\Registry;
use VDM\Joomla\Utilities\Component\Helper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface;
@ -35,9 +36,9 @@ final class Event implements EventInterface
protected $activePlugins = false;
/**
* The application to trigger and event TODO
* The dispatcher to get events
*
* @since 3.2.0
* @since 5.0.2
*/
protected $dispatcher;
@ -69,7 +70,7 @@ final class Event implements EventInterface
}
}
$this->dispatcher = Factory::getApplication();
$this->dispatcher = Factory::getContainer()->get(DispatcherInterface::class);
}
/**
@ -89,8 +90,13 @@ final class Event implements EventInterface
{
try
{
// Trigger this compiler event.
$results = $this->dispatcher->triggerEvent($event, $data ?? []);
$data ??= [];
$listeners = $this->dispatcher->getListeners($event);
foreach ($listeners as $listener)
{
// Call the listener with the unpacked arguments
$listener(...$data);
}
}
catch (\Exception $e)
{

View File

@ -262,6 +262,10 @@ final class Header implements HeaderInterface
$headers[] = 'use Joomla\CMS\Helper\TagsHelper;';
break;
case 'plugin.provider.header':
$headers[] = "use {$this->NamespacePrefix}\\Plugin\\[[[PluginGroupNamespace]]]\\[[[PluginNamespace]]]\\Extension\\{$codeName};";
break;
default:
break;
}
@ -548,6 +552,19 @@ final class Header implements HeaderInterface
$headers[] = 'use Joomla\CMS\Form\Field\###FORM_EXTENDS###;';
break;
case 'plugin.extension.header':
$headers = [];
break;
case 'plugin.provider.header':
$headers = [];
$headers[] = 'use Joomla\CMS\Factory;';
$headers[] = 'use Joomla\CMS\Plugin\PluginHelper;';
$headers[] = 'use Joomla\CMS\Extension\PluginInterface;';
$headers[] = 'use Joomla\Event\DispatcherInterface;';
$headers[] = 'use Joomla\DI\ServiceProviderInterface;';
$headers[] = 'use Joomla\DI\Container;';
break;
default:
break;
}

View File

@ -205,6 +205,11 @@ final class Header implements HeaderInterface
$headers[] = 'use Joomla\CMS\Helper\TagsHelper;';
break;
case 'plugin.extension.header':
case 'plugin.provider.header':
$headers = [];
break;
default:
break;
}

View File

@ -0,0 +1,934 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFive;
use Joomla\CMS\Factory;
use Joomla\CMS\Filter\OutputFilter;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Customcode;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Field;
use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName;
use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\String\ClassfunctionHelper;
use VDM\Joomla\Utilities\String\PluginHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\GetHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface;
/**
* Joomla 5 Plug-in Data Class
*
* @since 5.0.2
*/
final class Data implements PluginDataInterface
{
/**
* Compiler Joomla Plug-in's Data
*
* @var array
* @since 3.2.0
*/
protected array $data = [];
/**
* The Configure Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Customcode Class.
*
* @var Customcode
* @since 5.0.2
*/
protected Customcode $customcode;
/**
* The Gui Class.
*
* @var Gui
* @since 5.0.2
*/
protected Gui $gui;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Field Class.
*
* @var Field
* @since 5.0.2
*/
protected Field $field;
/**
* The Name Class.
*
* @var FieldName
* @since 5.0.2
*/
protected FieldName $fieldname;
/**
* The Filesfolders Class.
*
* @var Filesfolders
* @since 5.0.2
*/
protected Filesfolders $filesfolders;
/**
* Database object to query local DB
*
* @since 3.2.0
**/
protected $db;
/**
* Define the mappings of traits and classes to their respective methods and services
*
* @var array
* @since 5.0.2
**/
protected array $service_checks = [
'DatabaseAwareTrait' => [
'trait' => 'Joomla\Database\DatabaseAwareTrait',
'class' => 'Joomla__'.'_ae15e6b6_f7de_43ad_be4b_71499ae88f45___Power',
'method' => 'setDatabase',
'service' => 'Joomla__'.'_7bd29d76_73c9_4c07_a5da_4f7a32aff78f___Power'
],
'UserFactoryAwareTrait' => [
'trait' => 'Joomla\CMS\User\UserFactoryAwareTrait',
'class' => 'Joomla__'.'_a6b2c321_5de3_4425_b05f_e5340965fb80___Power',
'method' => 'setUserFactory',
'service' => 'Joomla__'.'_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power'
]
];
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Customcode $customcode The Customcode Class.
* @param Gui $gui The Gui Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Language $language The Language Class.
* @param Field $field The Field Class.
* @param FieldName $fieldname The Name Class.
* @param Filesfolders $filesfolders The Filesfolders Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Customcode $customcode, Gui $gui,
Placeholder $placeholder, Language $language,
Field $field, FieldName $fieldname,
Filesfolders $filesfolders)
{
$this->config = $config;
$this->customcode = $customcode;
$this->gui = $gui;
$this->placeholder = $placeholder;
$this->language = $language;
$this->field = $field;
$this->fieldname = $fieldname;
$this->filesfolders = $filesfolders;
$this->db = Factory::getDbo();
}
/**
* Get the Joomla Plugin/s
*
* @param int|null $id the plugin id
*
* @return object|array|null if ID found it returns object, if no ID given it returns all set
* @since 3.2.0
*/
public function get(int $id = null)
{
if (is_null($id) && $this->exists())
{
return $this->data;
}
elseif ($this->exists($id))
{
return $this->data[$id];
}
return null;
}
/**
* Check if the Joomla Plugin/s exists
*
* @param int|null $id the plugin id
*
* @return bool if ID found it returns true, if no ID given it returns true if any are set
* @since 3.2.0
*/
public function exists(int $id = null): bool
{
if (is_null($id))
{
return ArrayHelper::check($this->data);
}
elseif (isset($this->data[$id]))
{
return true;
}
return $this->set($id);
}
/**
* Set the Joomla Plugin
*
* @param int $id the plugin id
*
* @return bool true on success
* @since 3.2.0
*/
public function set(int $id): bool
{
if (isset($this->data[$id]))
{
return true;
}
else
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->select('a.*');
$query->select(
$this->db->quoteName(
array(
'g.name',
'e.name',
'e.head',
'e.comment',
'e.id',
'f.addfiles',
'f.addfolders',
'f.addfilesfullpath',
'f.addfoldersfullpath',
'f.addurls',
'u.version_update',
'u.id'
), array(
'group',
'extends',
'class_head',
'comment',
'class_id',
'addfiles',
'addfolders',
'addfilesfullpath',
'addfoldersfullpath',
'addurls',
'version_update',
'version_update_id'
)
)
);
// from these tables
$query->from('#__componentbuilder_joomla_plugin AS a');
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_group', 'g'
) . ' ON (' . $this->db->quoteName('a.joomla_plugin_group')
. ' = ' . $this->db->quoteName('g.id') . ')'
);
$query->join(
'LEFT',
$this->db->quoteName('#__componentbuilder_class_extends', 'e')
. ' ON (' . $this->db->quoteName('a.class_extends') . ' = '
. $this->db->quoteName('e.id') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_updates', 'u'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('u.joomla_plugin') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_files_folders_urls', 'f'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('f.joomla_plugin') . ')'
);
$query->where($this->db->quoteName('a.id') . ' = ' . (int) $id);
$query->where($this->db->quoteName('a.published') . ' >= 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
// get the plugin data
$plugin = $this->db->loadObject();
// tweak system to set stuff to the plugin domain
$_backup_target = $this->config->build_target;
$_backup_lang = $this->config->lang_target;
$_backup_langPrefix = $this->config->lang_prefix;
// set some keys
$plugin->target_type = 'pLuG!n';
$plugin->key = $plugin->id . '_' . $plugin->target_type;
// update to point to plugin
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
// set version if not set
if (empty($plugin->plugin_version))
{
$plugin->plugin_version = '1.0.0';
}
// set GUI mapper
$guiMapper = array('table' => 'joomla_plugin',
'id' => (int) $id, 'type' => 'php');
// update the name if it has dynamic values
$plugin->name = $this->placeholder->update_(
$this->customcode->update($plugin->name)
);
// update the name if it has dynamic values
$plugin->code_name
= ClassfunctionHelper::safe(
$plugin->name
);
// set official name
$plugin->official_name = ucwords(
$plugin->group . ' - ' . $plugin->name
);
// set lang prefix
$plugin->lang_prefix = PluginHelper::safeLangPrefix(
$plugin->code_name,
$plugin->group
);
// set langPrefix
$this->config->lang_prefix = $plugin->lang_prefix;
// set plugin class name
$plugin->class_name = ucfirst(
$plugin->code_name
);
// set plugin context name
$plugin->context_name = strtolower((string)
$plugin->code_name
);
// set plugin namespace
$plugin->namespace = $plugin->code_name;
// set plugin group namespace
$plugin->group_namespace = ucfirst(
$plugin->group
);
// set plugin install class name
$plugin->installer_class_name
= PluginHelper::safeInstallClassName(
$plugin->code_name,
$plugin->group
);
// set plugin folder name
$plugin->folder_name
= PluginHelper::safeFolderName(
$plugin->code_name,
$plugin->group
);
// set the zip name
$plugin->zip_name = $plugin->folder_name . '_v' . str_replace(
'.', '_', (string) $plugin->plugin_version
) . '__J' . $this->config->joomla_version;
// set plugin file name
$plugin->file_name = $plugin->context_name;
$plugin->class_file_name = $plugin->code_name;
// set plugin context
$plugin->context = $plugin->folder_name . '.' . $plugin->id;
// set official_name lang strings
$this->language->set(
$plugin->key, $this->config->lang_prefix, $plugin->official_name
);
// set some placeholder for this plugin
$this->placeholder->set('Plugin_name', $plugin->official_name);
$this->placeholder->set('PLUGIN_NAME', $plugin->official_name);
$this->placeholder->set('Plugin', ucfirst((string) $plugin->code_name));
$this->placeholder->set('plugin', strtolower((string) $plugin->code_name));
$this->placeholder->set('Plugin_group', ucfirst((string) $plugin->group));
$this->placeholder->set('plugin_group', strtolower((string) $plugin->group));
$this->placeholder->set('plugin.version', $plugin->plugin_version);
$this->placeholder->set('VERSION', $plugin->plugin_version);
$this->placeholder->set('plugin_version', str_replace(
'.', '_', (string) $plugin->plugin_version
));
// set description
$this->placeholder->set('DESCRIPTION', '');
if (!isset($plugin->description)
|| !StringHelper::check(
$plugin->description
))
{
$plugin->description = '';
}
else
{
$plugin->description = $this->placeholder->update_(
$this->customcode->update($plugin->description)
);
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_DESCRIPTION',
$plugin->description
);
// set description
$this->placeholder->set('DESCRIPTION', $plugin->description);
$plugin->description = '<p>' . $plugin->description . '</p>';
}
// get author name
$project_author = $this->config->project_author;
// we can only set these if the component was passed
$plugin->xml_description = "<h1>" . $plugin->official_name
. " (v." . $plugin->plugin_version
. ")</h1> <div style='clear: both;'></div>"
. $plugin->description . "<p>Created by <a href='" . trim(
(string) $this->config->project_website
) . "' target='_blank'>" . trim(
(string) OutputFilter::cleanText($project_author)
) . "</a><br /><small>Development started "
. Factory::getDate($plugin->created)->format("jS F, Y")
. "</small></p>";
// set xml discription
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_XML_DESCRIPTION',
$plugin->xml_description
);
// update the readme if set
if ($plugin->addreadme == 1 && !empty($plugin->readme))
{
$plugin->readme = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->readme))
);
}
else
{
$plugin->addreadme = 0;
unset($plugin->readme);
}
// open some base64 strings
if (!empty($plugin->main_class_code))
{
// set GUI mapper field
$guiMapper['field'] = 'main_class_code';
// base64 Decode main_class_code.
$plugin->main_class_code = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->main_class_code)
)
),
$guiMapper
);
}
// set the head :)
if ($plugin->add_head == 1 && !empty($plugin->head))
{
// set GUI mapper field
$guiMapper['field'] = 'head';
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->head)
)
),
$guiMapper
);
}
elseif (!empty($plugin->class_head))
{
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->class_head)
)
),
array(
'table' => 'class_extends',
'field' => 'head',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
unset($plugin->class_head);
// Check the plugin's code and header for each trait
foreach ($this->service_checks as $key => $info)
{
if (strpos($plugin->main_class_code, $key) !== false ||
strpos($plugin->main_class_code, $info['class']) !== false ||
strpos($plugin->header, $info['trait']) !== false)
{
$service_provider[] = Indent::_(4) . "\$plugin->{$info['method']}(\$container->get({$info['service']}::class));";
}
}
// Assign service provider if any services were added
if (!empty($service_provider))
{
$plugin->service_provider = implode(PHP_EOL, $service_provider);
}
// set the comment
if (!empty($plugin->comment))
{
// base64 Decode comment.
$plugin->comment = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->comment)
)
),
array(
'table' => 'class_extends',
'field' => 'comment',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
// start the config array
$plugin->config_fields = [];
// create the form arrays
$plugin->form_files = [];
$plugin->fieldsets_label = [];
$plugin->fieldsets_paths = [];
$plugin->add_rule_path = [];
$plugin->add_field_path = [];
// set global fields rule to default component path
$plugin->fields_rules_paths = 1;
// set the fields data
$plugin->fields = (isset($plugin->fields)
&& JsonHelper::check($plugin->fields))
? json_decode((string) $plugin->fields, true) : null;
if (ArrayHelper::check($plugin->fields))
{
// ket global key
$key = $plugin->key;
$dynamic_fields = array('fieldset' => 'basic',
'fields_name' => 'params',
'file' => 'config');
foreach ($plugin->fields as $n => &$form)
{
if (isset($form['fields'])
&& ArrayHelper::check(
$form['fields']
))
{
// make sure the dynamic_field is set to dynamic_value by default
foreach (
$dynamic_fields as $dynamic_field =>
$dynamic_value
)
{
if (!isset($form[$dynamic_field])
|| !StringHelper::check(
$form[$dynamic_field]
))
{
$form[$dynamic_field] = $dynamic_value;
}
else
{
if ('fields_name' === $dynamic_field
&& strpos((string) $form[$dynamic_field], '.')
!== false)
{
$form[$dynamic_field]
= $form[$dynamic_field];
}
else
{
$form[$dynamic_field]
= StringHelper::safe(
$form[$dynamic_field]
);
}
}
}
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// now build the form key
$unique = $form['file'] . $form['fields_name']
. $form['fieldset'];
}
else
{
// now build the form key
$unique = $form['fields_name']
. $form['fieldset'];
}
// set global fields rule path switchs
if ($plugin->fields_rules_paths == 1
&& isset($form['fields_rules_paths'])
&& $form['fields_rules_paths'] == 2)
{
$plugin->fields_rules_paths = 2;
}
// set where to path is pointing
$plugin->fieldsets_paths[$unique]
= $form['fields_rules_paths'];
// add the label if set to lang
if (isset($form['label'])
&& StringHelper::check(
$form['label']
))
{
$plugin->fieldsets_label[$unique]
= $this->language->key($form['label']);
}
// check for extra rule paths
if (isset($form['addrulepath'])
&& ArrayHelper::check($form['addrulepath']))
{
foreach ($form['addrulepath'] as $add_rule_path)
{
if (StringHelper::check($add_rule_path['path']))
{
$plugin->add_rule_path[$unique] = $add_rule_path['path'];
}
}
}
// check for extra field paths
if (isset($form['addfieldpath'])
&& ArrayHelper::check($form['addfieldpath']))
{
foreach ($form['addfieldpath'] as $add_field_path)
{
if (StringHelper::check($add_field_path['path']))
{
$plugin->add_field_path[$unique] = $add_field_path['path'];
}
}
}
// build the fields
$form['fields'] = array_map(
function ($field) use ($key, $unique) {
// make sure the alias and title is 0
$field['alias'] = 0;
$field['title'] = 0;
// set the field details
$this->field->set(
$field, $key, $key, $unique
);
// update the default if set
if (StringHelper::check(
$field['custom_value']
)
&& isset($field['settings']))
{
if (($old_default
= GetHelper::between(
$field['settings']->xml,
'default="', '"', false
)) !== false)
{
// replace old default
$field['settings']->xml
= str_replace(
'default="' . $old_default
. '"', 'default="'
. $field['custom_value'] . '"',
(string) $field['settings']->xml
);
}
else
{
// add the default (hmmm not ideal but okay it should work)
$field['settings']->xml
= 'default="'
. $field['custom_value'] . '" '
. $field['settings']->xml;
}
}
unset($field['custom_value']);
// return field
return $field;
}, array_values($form['fields'])
);
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// load the form file
if (!isset($plugin->form_files[$form['file']]))
{
$plugin->form_files[$form['file']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']]))
{
$plugin->form_files[$form['file']][$form['fields_name']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]))
{
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the global form file builder
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
else
{
// load the config form
if (!isset($plugin->config_fields[$form['fields_name']]))
{
$plugin->config_fields[$form['fields_name']]
= [];
}
if (!isset($plugin->config_fields[$form['fields_name']][$form['fieldset']]))
{
$plugin->config_fields[$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the config builder
$plugin->config_fields[$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
}
else
{
unset($plugin->fields[$n]);
}
}
}
unset($plugin->fields);
// set files and folders
$this->filesfolders->set($plugin);
// add PHP in plugin install
$plugin->add_install_script = true;
$addScriptMethods = [
'php_preflight',
'php_postflight',
'php_method',
'php_script'
];
$addScriptTypes = [
'install',
'update',
'uninstall',
'construct'
];
foreach ($addScriptMethods as $scriptMethod)
{
foreach ($addScriptTypes as $scriptType)
{
if (isset( $plugin->{'add_' . $scriptMethod . '_' . $scriptType})
&& $plugin->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$plugin->{$scriptMethod . '_' . $scriptType}
))
{
// set GUI mapper field
$guiMapper['field'] = $scriptMethod . '_' . $scriptType;
$plugin->{$scriptMethod . '_' . $scriptType} = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode(
(string) $plugin->{$scriptMethod . '_' . $scriptType}
)
)
),
$guiMapper
);
}
else
{
unset($plugin->{$scriptMethod . '_' . $scriptType});
$plugin->{'add_' . $scriptMethod . '_' . $scriptType} = 0;
}
}
}
// add_sql
if ($plugin->add_sql == 1
&& StringHelper::check($plugin->sql))
{
$plugin->sql = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->sql))
);
}
else
{
unset($plugin->sql);
$plugin->add_sql = 0;
}
// add_sql_uninstall
if ($plugin->add_sql_uninstall == 1
&& StringHelper::check(
$plugin->sql_uninstall
))
{
$plugin->sql_uninstall = $this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->sql_uninstall)
)
);
}
else
{
unset($plugin->sql_uninstall);
$plugin->add_sql_uninstall = 0;
}
// update the URL of the update_server if set
if ($plugin->add_update_server == 1
&& StringHelper::check(
$plugin->update_server_url
))
{
$plugin->update_server_url = $this->placeholder->update_(
$this->customcode->update($plugin->update_server_url)
);
}
// add the update/sales server FTP details if that is the expected protocol
$serverArray = array('update_server', 'sales_server');
foreach ($serverArray as $server)
{
if ($plugin->{'add_' . $server} == 1
&& is_numeric(
$plugin->{$server}
)
&& $plugin->{$server} > 0)
{
// get the server protocol
$plugin->{$server . '_protocol'}
= GetHelper::var(
'server', (int) $plugin->{$server}, 'id', 'protocol'
);
}
else
{
$plugin->{$server} = 0;
// only change this for sales server (update server can be added locally to the zip file)
if ('sales_server' === $server)
{
$plugin->{'add_' . $server} = 0;
}
$plugin->{$server . '_protocol'} = 0;
}
}
// old path (to remove)
$plugin->remove_file_paths = [];
$plugin->remove_file_paths[] = "/plugins/{$plugin->group}/{$plugin->context_name}/{$plugin->file_name}.php";
// set the update server stuff (TODO)
// update_server_xml_path
// update_server_xml_file_name
// rest globals
$this->config->build_target = $_backup_target;
$this->config->lang_target = $_backup_lang;
$this->config->set('lang_prefix', $_backup_langPrefix);
$this->placeholder->remove('Plugin_name');
$this->placeholder->remove('Plugin');
$this->placeholder->remove('plugin');
$this->placeholder->remove('Plugin_group');
$this->placeholder->remove('plugin_group');
$this->placeholder->remove('plugin.version');
$this->placeholder->remove('plugin_version');
$this->placeholder->remove('VERSION');
$this->placeholder->remove('DESCRIPTION');
$this->placeholder->remove('PLUGIN_NAME');
$this->data[$id] = $plugin;
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,392 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFive;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HeaderInterface as Header;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as Data;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\GetScriptInterface as InstallScript;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ExtensionInterface as Extension;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ProviderInterface as Provider;
use VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin\MainXMLInterface as MainXML;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetExtension;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\InfusionInterface;
/**
* Joomla 5 Plugin Infusion Class
*
* @since 5.0.2
*/
final class Infusion implements InfusionInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Header Class.
*
* @var Header
* @since 5.0.2
*/
protected Header $header;
/**
* The Event Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The PluginData Class.
*
* @var Data
* @since 5.0.2
*/
protected Data $data;
/**
* The GetScript Class.
*
* @var InstallScript
* @since 5.0.2
*/
protected InstallScript $installscript;
/**
* The Extension Class.
*
* @var Extension
* @since 5.0.2
*/
protected Extension $extension;
/**
* The Provider Class.
*
* @var Provider
* @since 5.0.2
*/
protected Provider $provider;
/**
* The MainXML Class.
*
* @var MainXML
* @since 5.0.2
*/
protected MainXML $mainxml;
/**
* The Content Multi Class.
*
* @var ContentMulti
* @since 5.0.2
*/
protected ContentMulti $contentmulti;
/**
* The Content One Class.
*
* @var ContentOne
* @since 5.0.2
*/
protected ContentOne $contentone;
/**
* The Fieldset Extension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Header $header The HeaderInterface Class.
* @param Event $event The EventInterface Class.
* @param Data $data The PluginDataInterface Class.
* @param InstallScript $installscript The GetScriptInterface Class.
* @param Extension $extension The ExtensionInterface Class.
* @param Provider $provider The ProviderInterface Class.
* @param MainXML $mainxml The MainXMLInterface Class.
* @param ContentMulti $contentmulti The ContentMulti Class.
* @param ContentOne $contentone The ContentOne Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Placeholder $placeholder, Header $header,
Event $event, Data $data, InstallScript $installscript,
Extension $extension, Provider $provider,
MainXML $mainxml, ContentMulti $contentmulti,
ContentOne $contentone, FieldsetExtension $fieldsetextension)
{
$this->config = $config;
$this->placeholder = $placeholder;
$this->header = $header;
$this->event = $event;
$this->data = $data;
$this->installscript = $installscript;
$this->extension = $extension;
$this->provider = $provider;
$this->mainxml = $mainxml;
$this->contentmulti = $contentmulti;
$this->contentone = $contentone;
$this->fieldsetextension = $fieldsetextension;
}
/**
* Infuse the plugin data into the content.
*
* This method processes each plugin in the data set, triggering events
* before and after infusion, setting placeholders, and adding content
* such as headers, classes, and XML configurations.
*
* @return void
* @since 5.0.2
*/
public function set(): void
{
if (!$this->data->exists())
{
return;
}
foreach ($this->data->get() as $plugin)
{
if (!ObjectHelper::check($plugin))
{
continue;
}
$this->triggerBeforeInfusionEvent($plugin);
$this->setPlaceholders($plugin);
$this->buildPluginContent($plugin);
$this->triggerAfterInfusionEvent($plugin);
}
}
/**
* Trigger the event before infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerBeforeInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onBeforeInfusePluginData', [&$plugin]);
}
/**
* Set placeholders based on plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setPlaceholders($plugin): void
{
$this->placeholder->set('PluginGroupNamespace', $plugin->group_namespace ?? '');
$this->placeholder->set('PluginNamespace', $plugin->namespace ?? '');
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
$this->config->set('lang_prefix', $plugin->lang_prefix);
}
/**
* Build and set the content related to the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function buildPluginContent($plugin): void
{
$this->setExtensionClassHeader($plugin);
$this->setExtensionClass($plugin);
$this->setProviderClassHeader($plugin);
$this->setProviderClass($plugin);
if ($plugin->add_install_script)
{
$this->setInstallClass($plugin);
}
if (isset($plugin->form_files) && ArrayHelper::check($plugin->form_files))
{
$this->setFieldsets($plugin);
}
$this->setMainXml($plugin);
}
/**
* Set the extension class header content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClassHeader($plugin): void
{
$headerContent = trim(
$this->header->get('plugin.extension.header', $plugin->class_name)
. PHP_EOL . ($plugin->header ?? '')
);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS_HEADER",
$this->placeholder->update($headerContent, $this->contentone->allActive())
);
}
/**
* Set the extension class content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClass($plugin): void
{
$extensionContent = $this->extension->get($plugin);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS", $extensionContent);
}
/**
* Set the provider class header content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setProviderClassHeader($plugin): void
{
$providerHeader = $this->header->get('plugin.provider.header', $plugin->class_name);
$this->contentmulti->set("{$plugin->key}|PROVIDER_CLASS_HEADER", $providerHeader);
}
/**
* Set the provider class content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setProviderClass($plugin): void
{
$providerContent = $this->provider->get($plugin);
$this->contentmulti->set("{$plugin->key}|PROVIDER_CLASS", $providerContent);
}
/**
* Set the install script content, if needed.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setInstallClass($plugin): void
{
$installContent = $this->installscript->get($plugin);
$this->contentmulti->set("{$plugin->key}|INSTALL_CLASS", $installContent);
}
/**
* Set fieldset content based on form files.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setFieldsets($plugin): void
{
foreach ($plugin->form_files as $file => $files)
{
foreach ($files as $field_name => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$fieldsetContent = $this->fieldsetextension->get($plugin, $fields);
$this->contentmulti->set(
"{$plugin->key}|FIELDSET_{$file}{$field_name}{$fieldset}",
$fieldsetContent
);
}
}
}
}
/**
* Set the main XML content for the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setMainXml($plugin): void
{
$mainXmlContent = $this->mainxml->get($plugin);
$this->contentmulti->set("{$plugin->key}|MAINXML", $mainXmlContent);
}
/**
* Trigger the event after infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerAfterInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onAfterInfusePluginData', [&$plugin]);
}
}

View File

@ -0,0 +1,830 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFive;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\File;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\FileHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\StructureInterface;
/**
* Joomla 5 Plugin Builder Class
*
* @since 5.0.2
*/
class Structure implements StructureInterface
{
/**
* The Data Class.
*
* @var Plugin
* @since 3.2.0
*/
protected Plugin $plugin;
/**
* The Component Class.
*
* @var Component
* @since 3.2.0
*/
protected Component $component;
/**
* The Config Class.
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* The Registry Class.
*
* @var Registry
* @since 3.2.0
*/
protected Registry $registry;
/**
* The Dispenser Class.
*
* @var Dispenser
* @since 3.2.0
*/
protected Dispenser $dispenser;
/**
* The EventInterface Class.
*
* @var Event
* @since 3.2.0
*/
protected Event $event;
/**
* The Counter Class.
*
* @var Counter
* @since 3.2.0
*/
protected Counter $counter;
/**
* The Folder Class.
*
* @var Folder
* @since 3.2.0
*/
protected Folder $folder;
/**
* The File Class.
*
* @var File
* @since 3.2.0
*/
protected File $file;
/**
* The Files Class.
*
* @var Files
* @since 3.2.0
*/
protected Files $files;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.0
*/
protected Placeholder $placeholder;
/**
* The Namespace Prefix
*
* @var string
* @since 5.0.0
*/
protected string $NamespacePrefix;
/**
* The Component Namespace (in code)
*
* @var string
* @since 3.2.0
*/
protected string $ComponentNamespace;
/**
* Constructor.
*
* @param Plugin $plugin The Data Class.
* @param Component $component The Component Class.
* @param Config $config The Config Class.
* @param Registry $registry The Registry Class.
* @param Dispenser $dispenser The Dispenser Class.
* @param Event $event The EventInterface Class.
* @param Counter $counter The Counter Class.
* @param Folder $folder The Folder Class.
* @param File $file The File Class.
* @param Files $files The Files Class.
* @param Placeholder $placeholder The Placeholder Class.
*
* @since 3.2.0
*/
public function __construct(Plugin $plugin, Component $component, Config $config,
Registry $registry, Dispenser $dispenser, Event $event,
Counter $counter, Folder $folder, File $file,
Files $files, Placeholder $placeholder)
{
$this->plugin = $plugin;
$this->component = $component;
$this->config = $config;
$this->registry = $registry;
$this->dispenser = $dispenser;
$this->event = $event;
$this->counter = $counter;
$this->folder = $folder;
$this->file = $file;
$this->files = $files;
$this->placeholder = $placeholder;
// set some global values
$this->NamespacePrefix = $this->placeholder->get('NamespacePrefix');
$this->ComponentNamespace = $this->placeholder->get('ComponentNamespace');
}
/**
* Build the Plugins files, folders, url's and config
*
* @return void
* @since 3.2.0
*/
public function build()
{
if ($this->plugin->exists())
{
// for plugin event TODO change event api signatures
$component_context = $this->config->component_context;
$plugins = $this->plugin->get();
// Trigger Event: jcb_ce_onBeforeSetPlugins
$this->event->trigger(
'jcb_ce_onBeforeBuildPlugins',
array(&$component_context, &$plugins)
);
foreach ($plugins as $plugin)
{
if (ObjectHelper::check($plugin)
&& isset($plugin->folder_name)
&& StringHelper::check($plugin->folder_name))
{
// plugin path
$this->pluginPath($plugin);
// create src folder
$this->folder->create($plugin->folder_path . '/src');
// set the plugin paths
$this->registry->set('dynamic_paths.' . $plugin->key, $plugin->folder_path);
// make sure there is no old build
$this->folder->remove($plugin->folder_path);
// creat the main component folder
$this->folder->create($plugin->folder_path);
// set main class file
$this->setMainClassFile($plugin);
// set service provider class file
$this->setServiceProviderClassFile($plugin);
// set main xml file
$this->setMainXmlFile($plugin);
// set install script if needed
$this->setInstallScript($plugin);
// set readme if found
$this->setReadme($plugin);
// set fields & rules folders if needed
if (isset($plugin->fields_rules_paths)
&& $plugin->fields_rules_paths == 2)
{
// create fields folder
$this->folder->create($plugin->folder_path . '/src/Field');
// create rules folder
$this->folder->create($plugin->folder_path . '/src/Rule');
}
// set forms folder if needed
$this->setForms($plugin);
// set SQL stuff if needed
$this->setSQL($plugin);
// create the language folder path
$this->folder->create($plugin->folder_path . '/language');
// also create the lang tag folder path
$this->folder->create(
$plugin->folder_path . '/language/' . $this->config->get('lang_tag', 'en-GB')
);
// check if this plugin has files
$this->setFiles($plugin);
// check if this plugin has folders
$this->setFolders($plugin);
// check if this plugin has urls
$this->setUrls($plugin);
}
}
}
}
/**
* get the plugin xml template
*
* @param object $plugin The plugin object
*
* @return string
* @since 3.2.0
*/
protected function getXML(object $plugin): string
{
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<extension type="plugin" version="'
. $this->config->joomla_versions[$this->config->joomla_version]['xml_version'] . '" group="'
. $plugin->group . '" method="upgrade">';
$xml .= PHP_EOL . Indent::_(1) . '<name>' . $plugin->lang_prefix
. '</name>';
$xml .= PHP_EOL . Indent::_(1) . '<creationDate>' . Placefix::_h('BUILDDATE') . '</creationDate>';
$xml .= PHP_EOL . Indent::_(1) . '<author>' . Placefix::_h('AUTHOR') . '</author>';
$xml .= PHP_EOL . Indent::_(1) . '<authorEmail>' . Placefix::_h('AUTHOREMAIL') . '</authorEmail>';
$xml .= PHP_EOL . Indent::_(1) . '<authorUrl>' . Placefix::_h('AUTHORWEBSITE') . '</authorUrl>';
$xml .= PHP_EOL . Indent::_(1) . '<copyright>' . Placefix::_h('COPYRIGHT') . '</copyright>';
$xml .= PHP_EOL . Indent::_(1) . '<license>' . Placefix::_h('LICENSE') . '</license>';
$xml .= PHP_EOL . Indent::_(1) . '<version>' . $plugin->plugin_version
. '</version>';
$xml .= PHP_EOL . Indent::_(1) . '<namespace path="src">' . "{$this->NamespacePrefix}\\Plugin\\{$plugin->group_namespace}\\{$plugin->namespace}"
. '</namespace>';
$xml .= PHP_EOL . Indent::_(1) . '<description>' . $plugin->lang_prefix
. '_XML_DESCRIPTION</description>';
$xml .= Placefix::_h('MAINXML');
$xml .= PHP_EOL . '</extension>';
return $xml;
}
/**
* set the plugin path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function pluginPath(object &$plugin): void
{
$plugin->folder_path = $this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/'
. $plugin->folder_name;
}
/**
* set the main class path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setMainClassFile(object $plugin): void
{
// create extension folder
$this->folder->create($plugin->folder_path . '/src/Extension');
$file_details = [
'path' => $plugin->folder_path . '/src/Extension/' . $plugin->class_file_name . '.php',
'name' => $plugin->class_file_name . '.php',
'zip' => 'src/Extension/' . $plugin->class_file_name . '.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Plugin main class template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
"namespace {$this->NamespacePrefix}\\Plugin\\{$plugin->group_namespace}\\{$plugin->namespace}\\Extension;" .
PHP_EOL . PHP_EOL . Placefix::_h('EXTENSION_CLASS_HEADER') .
PHP_EOL . PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" .
PHP_EOL . PHP_EOL .
Placefix::_h('EXTENSION_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the service provider path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setServiceProviderClassFile(object $plugin): void
{
// create services folder
$this->folder->create($plugin->folder_path . '/services');
$file_details = [
'path' => $plugin->folder_path . '/services/provider.php',
'name' => 'provider.php',
'zip' => 'services/provider.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Plugin services provider class template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" .
PHP_EOL . PHP_EOL .
Placefix::_h('PROVIDER_CLASS_HEADER') .
Placefix::_h('PROVIDER_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the main xml file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setMainXmlFile(object $plugin): void
{
$file_details = [
'path' => $plugin->folder_path . '/' . $plugin->file_name . '.xml',
'name' => $plugin->file_name . '.xml',
'zip' => $plugin->file_name . '.xml'
];
$this->file->write(
$file_details['path'],
$this->getXML($plugin)
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the install script file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setInstallScript(object $plugin): void
{
if ($plugin->add_install_script)
{
$file_details = [
'path' => $plugin->folder_path . '/script.php',
'name' => 'script.php',
'zip' => 'script.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Script template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" . PHP_EOL .
Placefix::_h('INSTALL_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
/**
* set the readme file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setReadme(object $plugin): void
{
if ($plugin->addreadme)
{
$file_details = [
'path' => $plugin->folder_path . '/README.md',
'name' => 'README.md',
'zip' => 'README.md'
];
$this->file->write($file_details['path'], $plugin->readme);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
/**
* set the form files and folders
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setForms(object $plugin): void
{
if (isset($plugin->form_files)
&& ArrayHelper::check($plugin->form_files))
{
$Group = ucfirst((string) $plugin->group);
$FileName = $plugin->file_name;
// create forms folder
$this->folder->create($plugin->folder_path . '/forms');
// set the template files
foreach ($plugin->form_files as $file => $fields)
{
// set file details
$file_details = [
'path' => $plugin->folder_path . '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file . '.xml'
];
// build basic XML
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<!--' . Line::_(__Line__, __Class__)
. ' default paths of ' . $file
. ' form points to ' . $this->config->component_code_name
. ' -->';
// search if we must add the component path
$add_component_path = false;
foreach ($fields as $field_name => $fieldsets)
{
if (!$add_component_path)
{
foreach ($fieldsets as $fieldset => $field)
{
if (!$add_component_path
&& isset($plugin->fieldsets_paths[$file . $field_name . $fieldset])
&& $plugin->fieldsets_paths[$file. $field_name . $fieldset] == 1)
{
$add_component_path = true;
}
}
}
}
// only add if part of the component field types path is required
if ($add_component_path)
{
$xml .= PHP_EOL . '<form';
$xml .= PHP_EOL . Indent::_(1)
. 'addruleprefix="' . $this->NamespacePrefix
. '\Component\\' . $this->ComponentNamespace
. '\Administrator\Rule"';
$xml .= PHP_EOL . Indent::_(1)
.'addfieldprefix="' . $this->NamespacePrefix
. '\Component\\' . $this->ComponentNamespace
. '\Administrator\Field"';
$xml .= PHP_EOL . '>';
}
else
{
$xml .= PHP_EOL . '<form>';
}
// add the fields
foreach ($fields as $field_name => $fieldsets)
{
// check if we have an double fields naming set
$field_name_inner = '';
$field_name_outer = $field_name;
if (strpos((string)$field_name, '.') !== false)
{
$field_names = explode('.', (string)$field_name);
if (count((array)$field_names) == 2)
{
$field_name_outer = $field_names[0];
$field_name_inner = $field_names[1];
}
}
$xml .= PHP_EOL . Indent::_(1)
. '<fields name="' . $field_name_outer
. '">';
foreach ($fieldsets as $fieldset => $field)
{
// default to the field set name
$label = $fieldset;
if (isset($plugin->fieldsets_label[$file . $field_name . $fieldset]))
{
$label = $plugin->fieldsets_label[$file . $field_name . $fieldset];
}
// add path to plugin rules and custom fields
if (isset($plugin->fieldsets_paths[$file . $field_name . $fieldset])
&& ($plugin->fieldsets_paths[$file . $field_name . $fieldset] == 2
|| $plugin->fieldsets_paths[$file . $field_name . $fieldset] == 3))
{
if (!isset($plugin->add_rule_path[$file . $field_name . $fieldset]))
{
$plugin->add_rule_path[$file . $field_name . $fieldset] =
"{$this->NamespacePrefix}\\Plugin\\{$Group}\\{$FileName}\\Rule";
}
if (!isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$plugin->add_field_path[$file . $field_name . $fieldset] =
"{$this->NamespacePrefix}\\Plugin\\{$Group}\\{$FileName}\\Field";
}
}
// add path to plugin rules and custom fields
if (isset($plugin->add_rule_path[$file . $field_name . $fieldset])
|| isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(1) . '<!--'
. Line::_(__Line__, __Class__) . ' default paths of '
. $fieldset . ' fieldset points to the plugin -->';
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '"';
if (isset($plugin->add_rule_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addrulepath="' . $plugin->add_rule_path[$file . $field_name . $fieldset] . '"';
}
if (isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addfieldpath="' . $plugin->add_field_path[$file . $field_name . $fieldset] . '"';
}
$xml .= PHP_EOL . Indent::_(1) . '>';
}
else
{
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '">';
}
// check if we have an inner field set
if (StringHelper::check($field_name_inner))
{
$xml .= PHP_EOL . Indent::_(1)
. '<fields name="'
. $field_name_inner . '">';
}
// add the placeholder of the fields
$xml .= Placefix::_h('FIELDSET_' . $file
. $field_name . $fieldset);
// check if we have an inner field set
if (StringHelper::check($field_name_inner))
{
$xml .= PHP_EOL . Indent::_(1)
. '</fields>';
}
$xml .= PHP_EOL . Indent::_(1)
. '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . '</form>';
// add xml to file
$this->file->write($file_details['path'], $xml);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
}
/**
* set the sql stuff
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setSQL(object $plugin): void
{
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
// create SQL folder
$this->folder->create($plugin->folder_path . '/sql');
// create mysql folder
$this->folder->create(
$plugin->folder_path . '/sql/mysql'
);
// now set the install file
if ($plugin->add_sql)
{
$this->file->write(
$plugin->folder_path . '/sql/mysql/install.sql',
$plugin->sql
);
// count the file created
$this->counter->file++;
}
// now set the uninstall file
if ($plugin->add_sql_uninstall)
{
$this->file->write(
$plugin->folder_path
. '/sql/mysql/uninstall.sql',
$plugin->sql_uninstall
);
// count the file created
$this->counter->file++;
}
}
}
/**
* set the files
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setFiles(object $plugin): void
{
if (isset($plugin->files) && ArrayHelper::check($plugin->files))
{
// add to component files
foreach ($plugin->files as $file)
{
// set the path finder
$file['target_type'] = $plugin->target_type;
$file['target_id'] = $plugin->id;
$this->component->appendArray('files', $file);
}
}
}
/**
* set the folders
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setFolders(object $plugin): void
{
if (isset($plugin->folders) && ArrayHelper::check($plugin->folders))
{
// add to component folders
foreach ($plugin->folders as $folder)
{
// set the path finder
$folder['target_type'] = $plugin->target_type;
$folder['target_id'] = $plugin->id;
$this->component->appendArray('folders', $folder);
}
}
}
/**
* set the urls
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setUrls(object &$plugin): void
{
if (isset($plugin->urls) && ArrayHelper::check($plugin->urls))
{
// add to component urls
foreach ($plugin->urls as &$url)
{
// should we add the local folder
if (isset($url['type']) && $url['type'] > 1
&& isset($url['url'])
&& StringHelper::check($url['url']))
{
// set file name
$fileName = basename((string)$url['url']);
// get the file contents
$data = FileHelper::getContent(
$url['url']
);
// build sub path
if (strpos($fileName, '.js') !== false)
{
$path = '/js';
}
elseif (strpos($fileName, '.css') !== false)
{
$path = '/css';
}
else
{
$path = '';
}
// create sub media folder path if not set
$this->folder->create(
$plugin->folder_path . $path
);
// set the path to plugin file
$url['path'] = $plugin->folder_path . $path
. '/' . $fileName; // we need this for later
// write data to path
$this->file->write($url['path'], $data);
// count the file created
$this->counter->file++;
}
}
}
}
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -0,0 +1,934 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour;
use Joomla\CMS\Factory;
use Joomla\CMS\Filter\OutputFilter;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Customcode;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Field;
use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName;
use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\String\ClassfunctionHelper;
use VDM\Joomla\Utilities\String\PluginHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\GetHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface;
/**
* Joomla 4 Plug-in Data Class
*
* @since 5.0.2
*/
final class Data implements PluginDataInterface
{
/**
* Compiler Joomla Plug-in's Data
*
* @var array
* @since 3.2.0
*/
protected array $data = [];
/**
* The Configure Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Customcode Class.
*
* @var Customcode
* @since 5.0.2
*/
protected Customcode $customcode;
/**
* The Gui Class.
*
* @var Gui
* @since 5.0.2
*/
protected Gui $gui;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Field Class.
*
* @var Field
* @since 5.0.2
*/
protected Field $field;
/**
* The Name Class.
*
* @var FieldName
* @since 5.0.2
*/
protected FieldName $fieldname;
/**
* The Filesfolders Class.
*
* @var Filesfolders
* @since 5.0.2
*/
protected Filesfolders $filesfolders;
/**
* Database object to query local DB
*
* @since 3.2.0
**/
protected $db;
/**
* Define the mappings of traits and classes to their respective methods and services
*
* @var array
* @since 5.0.2
**/
protected array $service_checks = [
'DatabaseAwareTrait' => [
'trait' => 'Joomla\Database\DatabaseAwareTrait',
'class' => 'Joomla__'.'_ae15e6b6_f7de_43ad_be4b_71499ae88f45___Power',
'method' => 'setDatabase',
'service' => 'Joomla__'.'_7bd29d76_73c9_4c07_a5da_4f7a32aff78f___Power'
],
'UserFactoryAwareTrait' => [
'trait' => 'Joomla\CMS\User\UserFactoryAwareTrait',
'class' => 'Joomla__'.'_a6b2c321_5de3_4425_b05f_e5340965fb80___Power',
'method' => 'setUserFactory',
'service' => 'Joomla__'.'_c2980d12_c3ef_4e23_b4a2_e6af1f5900a9___Power'
]
];
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Customcode $customcode The Customcode Class.
* @param Gui $gui The Gui Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Language $language The Language Class.
* @param Field $field The Field Class.
* @param FieldName $fieldname The Name Class.
* @param Filesfolders $filesfolders The Filesfolders Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Customcode $customcode, Gui $gui,
Placeholder $placeholder, Language $language,
Field $field, FieldName $fieldname,
Filesfolders $filesfolders)
{
$this->config = $config;
$this->customcode = $customcode;
$this->gui = $gui;
$this->placeholder = $placeholder;
$this->language = $language;
$this->field = $field;
$this->fieldname = $fieldname;
$this->filesfolders = $filesfolders;
$this->db = Factory::getDbo();
}
/**
* Get the Joomla Plugin/s
*
* @param int|null $id the plugin id
*
* @return object|array|null if ID found it returns object, if no ID given it returns all set
* @since 3.2.0
*/
public function get(int $id = null)
{
if (is_null($id) && $this->exists())
{
return $this->data;
}
elseif ($this->exists($id))
{
return $this->data[$id];
}
return null;
}
/**
* Check if the Joomla Plugin/s exists
*
* @param int|null $id the plugin id
*
* @return bool if ID found it returns true, if no ID given it returns true if any are set
* @since 3.2.0
*/
public function exists(int $id = null): bool
{
if (is_null($id))
{
return ArrayHelper::check($this->data);
}
elseif (isset($this->data[$id]))
{
return true;
}
return $this->set($id);
}
/**
* Set the Joomla Plugin
*
* @param int $id the plugin id
*
* @return bool true on success
* @since 3.2.0
*/
public function set(int $id): bool
{
if (isset($this->data[$id]))
{
return true;
}
else
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->select('a.*');
$query->select(
$this->db->quoteName(
array(
'g.name',
'e.name',
'e.head',
'e.comment',
'e.id',
'f.addfiles',
'f.addfolders',
'f.addfilesfullpath',
'f.addfoldersfullpath',
'f.addurls',
'u.version_update',
'u.id'
), array(
'group',
'extends',
'class_head',
'comment',
'class_id',
'addfiles',
'addfolders',
'addfilesfullpath',
'addfoldersfullpath',
'addurls',
'version_update',
'version_update_id'
)
)
);
// from these tables
$query->from('#__componentbuilder_joomla_plugin AS a');
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_group', 'g'
) . ' ON (' . $this->db->quoteName('a.joomla_plugin_group')
. ' = ' . $this->db->quoteName('g.id') . ')'
);
$query->join(
'LEFT',
$this->db->quoteName('#__componentbuilder_class_extends', 'e')
. ' ON (' . $this->db->quoteName('a.class_extends') . ' = '
. $this->db->quoteName('e.id') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_updates', 'u'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('u.joomla_plugin') . ')'
);
$query->join(
'LEFT', $this->db->quoteName(
'#__componentbuilder_joomla_plugin_files_folders_urls', 'f'
) . ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName('f.joomla_plugin') . ')'
);
$query->where($this->db->quoteName('a.id') . ' = ' . (int) $id);
$query->where($this->db->quoteName('a.published') . ' >= 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
// get the plugin data
$plugin = $this->db->loadObject();
// tweak system to set stuff to the plugin domain
$_backup_target = $this->config->build_target;
$_backup_lang = $this->config->lang_target;
$_backup_langPrefix = $this->config->lang_prefix;
// set some keys
$plugin->target_type = 'pLuG!n';
$plugin->key = $plugin->id . '_' . $plugin->target_type;
// update to point to plugin
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
// set version if not set
if (empty($plugin->plugin_version))
{
$plugin->plugin_version = '1.0.0';
}
// set GUI mapper
$guiMapper = array('table' => 'joomla_plugin',
'id' => (int) $id, 'type' => 'php');
// update the name if it has dynamic values
$plugin->name = $this->placeholder->update_(
$this->customcode->update($plugin->name)
);
// update the name if it has dynamic values
$plugin->code_name
= ClassfunctionHelper::safe(
$plugin->name
);
// set official name
$plugin->official_name = ucwords(
$plugin->group . ' - ' . $plugin->name
);
// set lang prefix
$plugin->lang_prefix = PluginHelper::safeLangPrefix(
$plugin->code_name,
$plugin->group
);
// set langPrefix
$this->config->lang_prefix = $plugin->lang_prefix;
// set plugin class name
$plugin->class_name = ucfirst(
$plugin->code_name
);
// set plugin context name
$plugin->context_name = strtolower((string)
$plugin->code_name
);
// set plugin namespace
$plugin->namespace = $plugin->code_name;
// set plugin group namespace
$plugin->group_namespace = ucfirst(
$plugin->group
);
// set plugin install class name
$plugin->installer_class_name
= PluginHelper::safeInstallClassName(
$plugin->code_name,
$plugin->group
);
// set plugin folder name
$plugin->folder_name
= PluginHelper::safeFolderName(
$plugin->code_name,
$plugin->group
);
// set the zip name
$plugin->zip_name = $plugin->folder_name . '_v' . str_replace(
'.', '_', (string) $plugin->plugin_version
) . '__J' . $this->config->joomla_version;
// set plugin file name
$plugin->file_name = $plugin->context_name;
$plugin->class_file_name = $plugin->code_name;
// set plugin context
$plugin->context = $plugin->folder_name . '.' . $plugin->id;
// set official_name lang strings
$this->language->set(
$plugin->key, $this->config->lang_prefix, $plugin->official_name
);
// set some placeholder for this plugin
$this->placeholder->set('Plugin_name', $plugin->official_name);
$this->placeholder->set('PLUGIN_NAME', $plugin->official_name);
$this->placeholder->set('Plugin', ucfirst((string) $plugin->code_name));
$this->placeholder->set('plugin', strtolower((string) $plugin->code_name));
$this->placeholder->set('Plugin_group', ucfirst((string) $plugin->group));
$this->placeholder->set('plugin_group', strtolower((string) $plugin->group));
$this->placeholder->set('plugin.version', $plugin->plugin_version);
$this->placeholder->set('VERSION', $plugin->plugin_version);
$this->placeholder->set('plugin_version', str_replace(
'.', '_', (string) $plugin->plugin_version
));
// set description
$this->placeholder->set('DESCRIPTION', '');
if (!isset($plugin->description)
|| !StringHelper::check(
$plugin->description
))
{
$plugin->description = '';
}
else
{
$plugin->description = $this->placeholder->update_(
$this->customcode->update($plugin->description)
);
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_DESCRIPTION',
$plugin->description
);
// set description
$this->placeholder->set('DESCRIPTION', $plugin->description);
$plugin->description = '<p>' . $plugin->description . '</p>';
}
// get author name
$project_author = $this->config->project_author;
// we can only set these if the component was passed
$plugin->xml_description = "<h1>" . $plugin->official_name
. " (v." . $plugin->plugin_version
. ")</h1> <div style='clear: both;'></div>"
. $plugin->description . "<p>Created by <a href='" . trim(
(string) $this->config->project_website
) . "' target='_blank'>" . trim(
(string) OutputFilter::cleanText($project_author)
) . "</a><br /><small>Development started "
. Factory::getDate($plugin->created)->format("jS F, Y")
. "</small></p>";
// set xml discription
$this->language->set(
$plugin->key, $plugin->lang_prefix . '_XML_DESCRIPTION',
$plugin->xml_description
);
// update the readme if set
if ($plugin->addreadme == 1 && !empty($plugin->readme))
{
$plugin->readme = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->readme))
);
}
else
{
$plugin->addreadme = 0;
unset($plugin->readme);
}
// open some base64 strings
if (!empty($plugin->main_class_code))
{
// set GUI mapper field
$guiMapper['field'] = 'main_class_code';
// base64 Decode main_class_code.
$plugin->main_class_code = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->main_class_code)
)
),
$guiMapper
);
}
// set the head :)
if ($plugin->add_head == 1 && !empty($plugin->head))
{
// set GUI mapper field
$guiMapper['field'] = 'head';
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->head)
)
),
$guiMapper
);
}
elseif (!empty($plugin->class_head))
{
// base64 Decode head.
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->class_head)
)
),
array(
'table' => 'class_extends',
'field' => 'head',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
unset($plugin->class_head);
// Check the plugin's code and header for each trait
foreach ($this->service_checks as $key => $info)
{
if (strpos($plugin->main_class_code, $key) !== false ||
strpos($plugin->main_class_code, $info['class']) !== false ||
strpos($plugin->header, $info['trait']) !== false)
{
$service_provider[] = Indent::_(4) . "\$plugin->{$info['method']}(\$container->get({$info['service']}::class));";
}
}
// Assign service provider if any services were added
if (!empty($service_provider))
{
$plugin->service_provider = implode(PHP_EOL, $service_provider);
}
// set the comment
if (!empty($plugin->comment))
{
// base64 Decode comment.
$plugin->comment = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->comment)
)
),
array(
'table' => 'class_extends',
'field' => 'comment',
'id' => (int) $plugin->class_id,
'type' => 'php')
);
}
// start the config array
$plugin->config_fields = [];
// create the form arrays
$plugin->form_files = [];
$plugin->fieldsets_label = [];
$plugin->fieldsets_paths = [];
$plugin->add_rule_path = [];
$plugin->add_field_path = [];
// set global fields rule to default component path
$plugin->fields_rules_paths = 1;
// set the fields data
$plugin->fields = (isset($plugin->fields)
&& JsonHelper::check($plugin->fields))
? json_decode((string) $plugin->fields, true) : null;
if (ArrayHelper::check($plugin->fields))
{
// ket global key
$key = $plugin->key;
$dynamic_fields = array('fieldset' => 'basic',
'fields_name' => 'params',
'file' => 'config');
foreach ($plugin->fields as $n => &$form)
{
if (isset($form['fields'])
&& ArrayHelper::check(
$form['fields']
))
{
// make sure the dynamic_field is set to dynamic_value by default
foreach (
$dynamic_fields as $dynamic_field =>
$dynamic_value
)
{
if (!isset($form[$dynamic_field])
|| !StringHelper::check(
$form[$dynamic_field]
))
{
$form[$dynamic_field] = $dynamic_value;
}
else
{
if ('fields_name' === $dynamic_field
&& strpos((string) $form[$dynamic_field], '.')
!== false)
{
$form[$dynamic_field]
= $form[$dynamic_field];
}
else
{
$form[$dynamic_field]
= StringHelper::safe(
$form[$dynamic_field]
);
}
}
}
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// now build the form key
$unique = $form['file'] . $form['fields_name']
. $form['fieldset'];
}
else
{
// now build the form key
$unique = $form['fields_name']
. $form['fieldset'];
}
// set global fields rule path switchs
if ($plugin->fields_rules_paths == 1
&& isset($form['fields_rules_paths'])
&& $form['fields_rules_paths'] == 2)
{
$plugin->fields_rules_paths = 2;
}
// set where to path is pointing
$plugin->fieldsets_paths[$unique]
= $form['fields_rules_paths'];
// add the label if set to lang
if (isset($form['label'])
&& StringHelper::check(
$form['label']
))
{
$plugin->fieldsets_label[$unique]
= $this->language->key($form['label']);
}
// check for extra rule paths
if (isset($form['addrulepath'])
&& ArrayHelper::check($form['addrulepath']))
{
foreach ($form['addrulepath'] as $add_rule_path)
{
if (StringHelper::check($add_rule_path['path']))
{
$plugin->add_rule_path[$unique] = $add_rule_path['path'];
}
}
}
// check for extra field paths
if (isset($form['addfieldpath'])
&& ArrayHelper::check($form['addfieldpath']))
{
foreach ($form['addfieldpath'] as $add_field_path)
{
if (StringHelper::check($add_field_path['path']))
{
$plugin->add_field_path[$unique] = $add_field_path['path'];
}
}
}
// build the fields
$form['fields'] = array_map(
function ($field) use ($key, $unique) {
// make sure the alias and title is 0
$field['alias'] = 0;
$field['title'] = 0;
// set the field details
$this->field->set(
$field, $key, $key, $unique
);
// update the default if set
if (StringHelper::check(
$field['custom_value']
)
&& isset($field['settings']))
{
if (($old_default
= GetHelper::between(
$field['settings']->xml,
'default="', '"', false
)) !== false)
{
// replace old default
$field['settings']->xml
= str_replace(
'default="' . $old_default
. '"', 'default="'
. $field['custom_value'] . '"',
(string) $field['settings']->xml
);
}
else
{
// add the default (hmmm not ideal but okay it should work)
$field['settings']->xml
= 'default="'
. $field['custom_value'] . '" '
. $field['settings']->xml;
}
}
unset($field['custom_value']);
// return field
return $field;
}, array_values($form['fields'])
);
// check if field is external form file
if (!isset($form['plugin']) || $form['plugin'] != 1)
{
// load the form file
if (!isset($plugin->form_files[$form['file']]))
{
$plugin->form_files[$form['file']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']]))
{
$plugin->form_files[$form['file']][$form['fields_name']]
= [];
}
if (!isset($plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]))
{
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the global form file builder
$plugin->form_files[$form['file']][$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
else
{
// load the config form
if (!isset($plugin->config_fields[$form['fields_name']]))
{
$plugin->config_fields[$form['fields_name']]
= [];
}
if (!isset($plugin->config_fields[$form['fields_name']][$form['fieldset']]))
{
$plugin->config_fields[$form['fields_name']][$form['fieldset']]
= [];
}
// do some house cleaning (for fields)
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the config builder
$plugin->config_fields[$form['fields_name']][$form['fieldset']][]
= $field;
}
// remove form
unset($plugin->fields[$n]);
}
}
else
{
unset($plugin->fields[$n]);
}
}
}
unset($plugin->fields);
// set files and folders
$this->filesfolders->set($plugin);
// add PHP in plugin install
$plugin->add_install_script = true;
$addScriptMethods = [
'php_preflight',
'php_postflight',
'php_method',
'php_script'
];
$addScriptTypes = [
'install',
'update',
'uninstall',
'construct'
];
foreach ($addScriptMethods as $scriptMethod)
{
foreach ($addScriptTypes as $scriptType)
{
if (isset( $plugin->{'add_' . $scriptMethod . '_' . $scriptType})
&& $plugin->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$plugin->{$scriptMethod . '_' . $scriptType}
))
{
// set GUI mapper field
$guiMapper['field'] = $scriptMethod . '_' . $scriptType;
$plugin->{$scriptMethod . '_' . $scriptType} = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode(
(string) $plugin->{$scriptMethod . '_' . $scriptType}
)
)
),
$guiMapper
);
}
else
{
unset($plugin->{$scriptMethod . '_' . $scriptType});
$plugin->{'add_' . $scriptMethod . '_' . $scriptType} = 0;
}
}
}
// add_sql
if ($plugin->add_sql == 1
&& StringHelper::check($plugin->sql))
{
$plugin->sql = $this->placeholder->update_(
$this->customcode->update(base64_decode((string) $plugin->sql))
);
}
else
{
unset($plugin->sql);
$plugin->add_sql = 0;
}
// add_sql_uninstall
if ($plugin->add_sql_uninstall == 1
&& StringHelper::check(
$plugin->sql_uninstall
))
{
$plugin->sql_uninstall = $this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->sql_uninstall)
)
);
}
else
{
unset($plugin->sql_uninstall);
$plugin->add_sql_uninstall = 0;
}
// update the URL of the update_server if set
if ($plugin->add_update_server == 1
&& StringHelper::check(
$plugin->update_server_url
))
{
$plugin->update_server_url = $this->placeholder->update_(
$this->customcode->update($plugin->update_server_url)
);
}
// add the update/sales server FTP details if that is the expected protocol
$serverArray = array('update_server', 'sales_server');
foreach ($serverArray as $server)
{
if ($plugin->{'add_' . $server} == 1
&& is_numeric(
$plugin->{$server}
)
&& $plugin->{$server} > 0)
{
// get the server protocol
$plugin->{$server . '_protocol'}
= GetHelper::var(
'server', (int) $plugin->{$server}, 'id', 'protocol'
);
}
else
{
$plugin->{$server} = 0;
// only change this for sales server (update server can be added locally to the zip file)
if ('sales_server' === $server)
{
$plugin->{'add_' . $server} = 0;
}
$plugin->{$server . '_protocol'} = 0;
}
}
// old path (to remove)
$plugin->remove_file_paths = [];
$plugin->remove_file_paths[] = "/plugins/{$plugin->group}/{$plugin->context_name}/{$plugin->file_name}.php";
// set the update server stuff (TODO)
// update_server_xml_path
// update_server_xml_file_name
// rest globals
$this->config->build_target = $_backup_target;
$this->config->lang_target = $_backup_lang;
$this->config->set('lang_prefix', $_backup_langPrefix);
$this->placeholder->remove('Plugin_name');
$this->placeholder->remove('Plugin');
$this->placeholder->remove('plugin');
$this->placeholder->remove('Plugin_group');
$this->placeholder->remove('plugin_group');
$this->placeholder->remove('plugin.version');
$this->placeholder->remove('plugin_version');
$this->placeholder->remove('VERSION');
$this->placeholder->remove('DESCRIPTION');
$this->placeholder->remove('PLUGIN_NAME');
$this->data[$id] = $plugin;
return true;
}
}
return false;
}
}

View File

@ -0,0 +1,392 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HeaderInterface as Header;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as Data;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\GetScriptInterface as InstallScript;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ExtensionInterface as Extension;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ProviderInterface as Provider;
use VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin\MainXMLInterface as MainXML;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetExtension;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\InfusionInterface;
/**
* Joomla 4 Plugin Infusion Class
*
* @since 5.0.2
*/
final class Infusion implements InfusionInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Header Class.
*
* @var Header
* @since 5.0.2
*/
protected Header $header;
/**
* The Event Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The PluginData Class.
*
* @var Data
* @since 5.0.2
*/
protected Data $data;
/**
* The GetScript Class.
*
* @var InstallScript
* @since 5.0.2
*/
protected InstallScript $installscript;
/**
* The Extension Class.
*
* @var Extension
* @since 5.0.2
*/
protected Extension $extension;
/**
* The Provider Class.
*
* @var Provider
* @since 5.0.2
*/
protected Provider $provider;
/**
* The MainXML Class.
*
* @var MainXML
* @since 5.0.2
*/
protected MainXML $mainxml;
/**
* The Content Multi Class.
*
* @var ContentMulti
* @since 5.0.2
*/
protected ContentMulti $contentmulti;
/**
* The Content One Class.
*
* @var ContentOne
* @since 5.0.2
*/
protected ContentOne $contentone;
/**
* The Fieldset Extension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Header $header The HeaderInterface Class.
* @param Event $event The EventInterface Class.
* @param Data $data The PluginDataInterface Class.
* @param InstallScript $installscript The GetScriptInterface Class.
* @param Extension $extension The ExtensionInterface Class.
* @param Provider $provider The ProviderInterface Class.
* @param MainXML $mainxml The MainXMLInterface Class.
* @param ContentMulti $contentmulti The ContentMulti Class.
* @param ContentOne $contentone The ContentOne Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Placeholder $placeholder, Header $header,
Event $event, Data $data, InstallScript $installscript,
Extension $extension, Provider $provider,
MainXML $mainxml, ContentMulti $contentmulti,
ContentOne $contentone, FieldsetExtension $fieldsetextension)
{
$this->config = $config;
$this->placeholder = $placeholder;
$this->header = $header;
$this->event = $event;
$this->data = $data;
$this->installscript = $installscript;
$this->extension = $extension;
$this->provider = $provider;
$this->mainxml = $mainxml;
$this->contentmulti = $contentmulti;
$this->contentone = $contentone;
$this->fieldsetextension = $fieldsetextension;
}
/**
* Infuse the plugin data into the content.
*
* This method processes each plugin in the data set, triggering events
* before and after infusion, setting placeholders, and adding content
* such as headers, classes, and XML configurations.
*
* @return void
* @since 5.0.2
*/
public function set(): void
{
if (!$this->data->exists())
{
return;
}
foreach ($this->data->get() as $plugin)
{
if (!ObjectHelper::check($plugin))
{
continue;
}
$this->triggerBeforeInfusionEvent($plugin);
$this->setPlaceholders($plugin);
$this->buildPluginContent($plugin);
$this->triggerAfterInfusionEvent($plugin);
}
}
/**
* Trigger the event before infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerBeforeInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onBeforeInfusePluginData', [&$plugin]);
}
/**
* Set placeholders based on plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setPlaceholders($plugin): void
{
$this->placeholder->set('PluginGroupNamespace', $plugin->group_namespace ?? '');
$this->placeholder->set('PluginNamespace', $plugin->namespace ?? '');
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
$this->config->set('lang_prefix', $plugin->lang_prefix);
}
/**
* Build and set the content related to the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function buildPluginContent($plugin): void
{
$this->setExtensionClassHeader($plugin);
$this->setExtensionClass($plugin);
$this->setProviderClassHeader($plugin);
$this->setProviderClass($plugin);
if ($plugin->add_install_script)
{
$this->setInstallClass($plugin);
}
if (isset($plugin->form_files) && ArrayHelper::check($plugin->form_files))
{
$this->setFieldsets($plugin);
}
$this->setMainXml($plugin);
}
/**
* Set the extension class header content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClassHeader($plugin): void
{
$headerContent = trim(
$this->header->get('plugin.extension.header', $plugin->class_name)
. PHP_EOL . ($plugin->header ?? '')
);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS_HEADER",
$this->placeholder->update($headerContent, $this->contentone->allActive())
);
}
/**
* Set the extension class content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClass($plugin): void
{
$extensionContent = $this->extension->get($plugin);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS", $extensionContent);
}
/**
* Set the provider class header content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setProviderClassHeader($plugin): void
{
$providerHeader = $this->header->get('plugin.provider.header', $plugin->class_name);
$this->contentmulti->set("{$plugin->key}|PROVIDER_CLASS_HEADER", $providerHeader);
}
/**
* Set the provider class content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setProviderClass($plugin): void
{
$providerContent = $this->provider->get($plugin);
$this->contentmulti->set("{$plugin->key}|PROVIDER_CLASS", $providerContent);
}
/**
* Set the install script content, if needed.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setInstallClass($plugin): void
{
$installContent = $this->installscript->get($plugin);
$this->contentmulti->set("{$plugin->key}|INSTALL_CLASS", $installContent);
}
/**
* Set fieldset content based on form files.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setFieldsets($plugin): void
{
foreach ($plugin->form_files as $file => $files)
{
foreach ($files as $field_name => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$fieldsetContent = $this->fieldsetextension->get($plugin, $fields);
$this->contentmulti->set(
"{$plugin->key}|FIELDSET_{$file}{$field_name}{$fieldset}",
$fieldsetContent
);
}
}
}
}
/**
* Set the main XML content for the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setMainXml($plugin): void
{
$mainXmlContent = $this->mainxml->get($plugin);
$this->contentmulti->set("{$plugin->key}|MAINXML", $mainXmlContent);
}
/**
* Trigger the event after infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerAfterInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onAfterInfusePluginData', [&$plugin]);
}
}

View File

@ -0,0 +1,830 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\File;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\FileHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\StructureInterface;
/**
* Joomla 4 Plugin Builder Class
*
* @since 5.0.2
*/
class Structure implements StructureInterface
{
/**
* The Data Class.
*
* @var Plugin
* @since 3.2.0
*/
protected Plugin $plugin;
/**
* The Component Class.
*
* @var Component
* @since 3.2.0
*/
protected Component $component;
/**
* The Config Class.
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* The Registry Class.
*
* @var Registry
* @since 3.2.0
*/
protected Registry $registry;
/**
* The Dispenser Class.
*
* @var Dispenser
* @since 3.2.0
*/
protected Dispenser $dispenser;
/**
* The EventInterface Class.
*
* @var Event
* @since 3.2.0
*/
protected Event $event;
/**
* The Counter Class.
*
* @var Counter
* @since 3.2.0
*/
protected Counter $counter;
/**
* The Folder Class.
*
* @var Folder
* @since 3.2.0
*/
protected Folder $folder;
/**
* The File Class.
*
* @var File
* @since 3.2.0
*/
protected File $file;
/**
* The Files Class.
*
* @var Files
* @since 3.2.0
*/
protected Files $files;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.0
*/
protected Placeholder $placeholder;
/**
* The Namespace Prefix
*
* @var string
* @since 5.0.0
*/
protected string $NamespacePrefix;
/**
* The Component Namespace (in code)
*
* @var string
* @since 3.2.0
*/
protected string $ComponentNamespace;
/**
* Constructor.
*
* @param Plugin $plugin The Data Class.
* @param Component $component The Component Class.
* @param Config $config The Config Class.
* @param Registry $registry The Registry Class.
* @param Dispenser $dispenser The Dispenser Class.
* @param Event $event The EventInterface Class.
* @param Counter $counter The Counter Class.
* @param Folder $folder The Folder Class.
* @param File $file The File Class.
* @param Files $files The Files Class.
* @param Placeholder $placeholder The Placeholder Class.
*
* @since 3.2.0
*/
public function __construct(Plugin $plugin, Component $component, Config $config,
Registry $registry, Dispenser $dispenser, Event $event,
Counter $counter, Folder $folder, File $file,
Files $files, Placeholder $placeholder)
{
$this->plugin = $plugin;
$this->component = $component;
$this->config = $config;
$this->registry = $registry;
$this->dispenser = $dispenser;
$this->event = $event;
$this->counter = $counter;
$this->folder = $folder;
$this->file = $file;
$this->files = $files;
$this->placeholder = $placeholder;
// set some global values
$this->NamespacePrefix = $this->placeholder->get('NamespacePrefix');
$this->ComponentNamespace = $this->placeholder->get('ComponentNamespace');
}
/**
* Build the Plugins files, folders, url's and config
*
* @return void
* @since 3.2.0
*/
public function build()
{
if ($this->plugin->exists())
{
// for plugin event TODO change event api signatures
$component_context = $this->config->component_context;
$plugins = $this->plugin->get();
// Trigger Event: jcb_ce_onBeforeSetPlugins
$this->event->trigger(
'jcb_ce_onBeforeBuildPlugins',
array(&$component_context, &$plugins)
);
foreach ($plugins as $plugin)
{
if (ObjectHelper::check($plugin)
&& isset($plugin->folder_name)
&& StringHelper::check($plugin->folder_name))
{
// plugin path
$this->pluginPath($plugin);
// create src folder
$this->folder->create($plugin->folder_path . '/src');
// set the plugin paths
$this->registry->set('dynamic_paths.' . $plugin->key, $plugin->folder_path);
// make sure there is no old build
$this->folder->remove($plugin->folder_path);
// creat the main component folder
$this->folder->create($plugin->folder_path);
// set main class file
$this->setMainClassFile($plugin);
// set service provider class file
$this->setServiceProviderClassFile($plugin);
// set main xml file
$this->setMainXmlFile($plugin);
// set install script if needed
$this->setInstallScript($plugin);
// set readme if found
$this->setReadme($plugin);
// set fields & rules folders if needed
if (isset($plugin->fields_rules_paths)
&& $plugin->fields_rules_paths == 2)
{
// create fields folder
$this->folder->create($plugin->folder_path . '/src/Field');
// create rules folder
$this->folder->create($plugin->folder_path . '/src/Rule');
}
// set forms folder if needed
$this->setForms($plugin);
// set SQL stuff if needed
$this->setSQL($plugin);
// create the language folder path
$this->folder->create($plugin->folder_path . '/language');
// also create the lang tag folder path
$this->folder->create(
$plugin->folder_path . '/language/' . $this->config->get('lang_tag', 'en-GB')
);
// check if this plugin has files
$this->setFiles($plugin);
// check if this plugin has folders
$this->setFolders($plugin);
// check if this plugin has urls
$this->setUrls($plugin);
}
}
}
}
/**
* get the plugin xml template
*
* @param object $plugin The plugin object
*
* @return string
* @since 3.2.0
*/
protected function getXML(object $plugin): string
{
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<extension type="plugin" version="'
. $this->config->joomla_versions[$this->config->joomla_version]['xml_version'] . '" group="'
. $plugin->group . '" method="upgrade">';
$xml .= PHP_EOL . Indent::_(1) . '<name>' . $plugin->lang_prefix
. '</name>';
$xml .= PHP_EOL . Indent::_(1) . '<creationDate>' . Placefix::_h('BUILDDATE') . '</creationDate>';
$xml .= PHP_EOL . Indent::_(1) . '<author>' . Placefix::_h('AUTHOR') . '</author>';
$xml .= PHP_EOL . Indent::_(1) . '<authorEmail>' . Placefix::_h('AUTHOREMAIL') . '</authorEmail>';
$xml .= PHP_EOL . Indent::_(1) . '<authorUrl>' . Placefix::_h('AUTHORWEBSITE') . '</authorUrl>';
$xml .= PHP_EOL . Indent::_(1) . '<copyright>' . Placefix::_h('COPYRIGHT') . '</copyright>';
$xml .= PHP_EOL . Indent::_(1) . '<license>' . Placefix::_h('LICENSE') . '</license>';
$xml .= PHP_EOL . Indent::_(1) . '<version>' . $plugin->plugin_version
. '</version>';
$xml .= PHP_EOL . Indent::_(1) . '<namespace path="src">' . "{$this->NamespacePrefix}\\Plugin\\{$plugin->group_namespace}\\{$plugin->namespace}"
. '</namespace>';
$xml .= PHP_EOL . Indent::_(1) . '<description>' . $plugin->lang_prefix
. '_XML_DESCRIPTION</description>';
$xml .= Placefix::_h('MAINXML');
$xml .= PHP_EOL . '</extension>';
return $xml;
}
/**
* set the plugin path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function pluginPath(object &$plugin): void
{
$plugin->folder_path = $this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/'
. $plugin->folder_name;
}
/**
* set the main class path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setMainClassFile(object $plugin): void
{
// create extension folder
$this->folder->create($plugin->folder_path . '/src/Extension');
$file_details = [
'path' => $plugin->folder_path . '/src/Extension/' . $plugin->class_file_name . '.php',
'name' => $plugin->class_file_name . '.php',
'zip' => 'src/Extension/' . $plugin->class_file_name . '.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Plugin main class template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
"namespace {$this->NamespacePrefix}\\Plugin\\{$plugin->group_namespace}\\{$plugin->namespace}\\Extension;" .
PHP_EOL . PHP_EOL . Placefix::_h('EXTENSION_CLASS_HEADER') .
PHP_EOL . PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" .
PHP_EOL . PHP_EOL .
Placefix::_h('EXTENSION_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the service provider path
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setServiceProviderClassFile(object $plugin): void
{
// create services folder
$this->folder->create($plugin->folder_path . '/services');
$file_details = [
'path' => $plugin->folder_path . '/services/provider.php',
'name' => 'provider.php',
'zip' => 'services/provider.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Plugin services provider class template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" .
PHP_EOL . PHP_EOL .
Placefix::_h('PROVIDER_CLASS_HEADER') .
Placefix::_h('PROVIDER_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the main xml file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setMainXmlFile(object $plugin): void
{
$file_details = [
'path' => $plugin->folder_path . '/' . $plugin->file_name . '.xml',
'name' => $plugin->file_name . '.xml',
'zip' => $plugin->file_name . '.xml'
];
$this->file->write(
$file_details['path'],
$this->getXML($plugin)
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
/**
* set the install script file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setInstallScript(object $plugin): void
{
if ($plugin->add_install_script)
{
$file_details = [
'path' => $plugin->folder_path . '/script.php',
'name' => 'script.php',
'zip' => 'script.php'
];
$this->file->write(
$file_details['path'],
'<?php' . PHP_EOL . '// Script template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" . PHP_EOL .
Placefix::_h('INSTALL_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
/**
* set the readme file
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setReadme(object $plugin): void
{
if ($plugin->addreadme)
{
$file_details = [
'path' => $plugin->folder_path . '/README.md',
'name' => 'README.md',
'zip' => 'README.md'
];
$this->file->write($file_details['path'], $plugin->readme);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
/**
* set the form files and folders
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setForms(object $plugin): void
{
if (isset($plugin->form_files)
&& ArrayHelper::check($plugin->form_files))
{
$Group = ucfirst((string) $plugin->group);
$FileName = $plugin->file_name;
// create forms folder
$this->folder->create($plugin->folder_path . '/forms');
// set the template files
foreach ($plugin->form_files as $file => $fields)
{
// set file details
$file_details = [
'path' => $plugin->folder_path . '/forms/' . $file . '.xml',
'name' => $file . '.xml',
'zip' => 'forms/' . $file . '.xml'
];
// build basic XML
$xml = '<?xml version="1.0" encoding="utf-8"?>';
$xml .= PHP_EOL . '<!--' . Line::_(__Line__, __Class__)
. ' default paths of ' . $file
. ' form points to ' . $this->config->component_code_name
. ' -->';
// search if we must add the component path
$add_component_path = false;
foreach ($fields as $field_name => $fieldsets)
{
if (!$add_component_path)
{
foreach ($fieldsets as $fieldset => $field)
{
if (!$add_component_path
&& isset($plugin->fieldsets_paths[$file . $field_name . $fieldset])
&& $plugin->fieldsets_paths[$file. $field_name . $fieldset] == 1)
{
$add_component_path = true;
}
}
}
}
// only add if part of the component field types path is required
if ($add_component_path)
{
$xml .= PHP_EOL . '<form';
$xml .= PHP_EOL . Indent::_(1)
. 'addruleprefix="' . $this->NamespacePrefix
. '\Component\\' . $this->ComponentNamespace
. '\Administrator\Rule"';
$xml .= PHP_EOL . Indent::_(1)
.'addfieldprefix="' . $this->NamespacePrefix
. '\Component\\' . $this->ComponentNamespace
. '\Administrator\Field"';
$xml .= PHP_EOL . '>';
}
else
{
$xml .= PHP_EOL . '<form>';
}
// add the fields
foreach ($fields as $field_name => $fieldsets)
{
// check if we have an double fields naming set
$field_name_inner = '';
$field_name_outer = $field_name;
if (strpos((string)$field_name, '.') !== false)
{
$field_names = explode('.', (string)$field_name);
if (count((array)$field_names) == 2)
{
$field_name_outer = $field_names[0];
$field_name_inner = $field_names[1];
}
}
$xml .= PHP_EOL . Indent::_(1)
. '<fields name="' . $field_name_outer
. '">';
foreach ($fieldsets as $fieldset => $field)
{
// default to the field set name
$label = $fieldset;
if (isset($plugin->fieldsets_label[$file . $field_name . $fieldset]))
{
$label = $plugin->fieldsets_label[$file . $field_name . $fieldset];
}
// add path to plugin rules and custom fields
if (isset($plugin->fieldsets_paths[$file . $field_name . $fieldset])
&& ($plugin->fieldsets_paths[$file . $field_name . $fieldset] == 2
|| $plugin->fieldsets_paths[$file . $field_name . $fieldset] == 3))
{
if (!isset($plugin->add_rule_path[$file . $field_name . $fieldset]))
{
$plugin->add_rule_path[$file . $field_name . $fieldset] =
"{$this->NamespacePrefix}\\Plugin\\{$Group}\\{$FileName}\\Rule";
}
if (!isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$plugin->add_field_path[$file . $field_name . $fieldset] =
"{$this->NamespacePrefix}\\Plugin\\{$Group}\\{$FileName}\\Field";
}
}
// add path to plugin rules and custom fields
if (isset($plugin->add_rule_path[$file . $field_name . $fieldset])
|| isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(1) . '<!--'
. Line::_(__Line__, __Class__) . ' default paths of '
. $fieldset . ' fieldset points to the plugin -->';
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '"';
if (isset($plugin->add_rule_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addrulepath="' . $plugin->add_rule_path[$file . $field_name . $fieldset] . '"';
}
if (isset($plugin->add_field_path[$file . $field_name . $fieldset]))
{
$xml .= PHP_EOL . Indent::_(2)
. 'addfieldpath="' . $plugin->add_field_path[$file . $field_name . $fieldset] . '"';
}
$xml .= PHP_EOL . Indent::_(1) . '>';
}
else
{
$xml .= PHP_EOL . Indent::_(1) . '<fieldset name="'
. $fieldset . '" label="' . $label . '">';
}
// check if we have an inner field set
if (StringHelper::check($field_name_inner))
{
$xml .= PHP_EOL . Indent::_(1)
. '<fields name="'
. $field_name_inner . '">';
}
// add the placeholder of the fields
$xml .= Placefix::_h('FIELDSET_' . $file
. $field_name . $fieldset);
// check if we have an inner field set
if (StringHelper::check($field_name_inner))
{
$xml .= PHP_EOL . Indent::_(1)
. '</fields>';
}
$xml .= PHP_EOL . Indent::_(1)
. '</fieldset>';
}
$xml .= PHP_EOL . Indent::_(1) . '</fields>';
}
$xml .= PHP_EOL . '</form>';
// add xml to file
$this->file->write($file_details['path'], $xml);
$this->files->appendArray($plugin->key, $file_details);
// count the file created
$this->counter->file++;
}
}
}
/**
* set the sql stuff
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setSQL(object $plugin): void
{
if ($plugin->add_sql || $plugin->add_sql_uninstall)
{
// create SQL folder
$this->folder->create($plugin->folder_path . '/sql');
// create mysql folder
$this->folder->create(
$plugin->folder_path . '/sql/mysql'
);
// now set the install file
if ($plugin->add_sql)
{
$this->file->write(
$plugin->folder_path . '/sql/mysql/install.sql',
$plugin->sql
);
// count the file created
$this->counter->file++;
}
// now set the uninstall file
if ($plugin->add_sql_uninstall)
{
$this->file->write(
$plugin->folder_path
. '/sql/mysql/uninstall.sql',
$plugin->sql_uninstall
);
// count the file created
$this->counter->file++;
}
}
}
/**
* set the files
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setFiles(object $plugin): void
{
if (isset($plugin->files) && ArrayHelper::check($plugin->files))
{
// add to component files
foreach ($plugin->files as $file)
{
// set the path finder
$file['target_type'] = $plugin->target_type;
$file['target_id'] = $plugin->id;
$this->component->appendArray('files', $file);
}
}
}
/**
* set the folders
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setFolders(object $plugin): void
{
if (isset($plugin->folders) && ArrayHelper::check($plugin->folders))
{
// add to component folders
foreach ($plugin->folders as $folder)
{
// set the path finder
$folder['target_type'] = $plugin->target_type;
$folder['target_id'] = $plugin->id;
$this->component->appendArray('folders', $folder);
}
}
}
/**
* set the urls
*
* @param object $plugin The plugin object
*
* @return void
* @since 3.2.0
*/
protected function setUrls(object &$plugin): void
{
if (isset($plugin->urls) && ArrayHelper::check($plugin->urls))
{
// add to component urls
foreach ($plugin->urls as &$url)
{
// should we add the local folder
if (isset($url['type']) && $url['type'] > 1
&& isset($url['url'])
&& StringHelper::check($url['url']))
{
// set file name
$fileName = basename((string)$url['url']);
// get the file contents
$data = FileHelper::getContent(
$url['url']
);
// build sub path
if (strpos($fileName, '.js') !== false)
{
$path = '/js';
}
elseif (strpos($fileName, '.css') !== false)
{
$path = '/css';
}
else
{
$path = '';
}
// create sub media folder path if not set
$this->folder->create(
$plugin->folder_path . $path
);
// set the path to plugin file
$url['path'] = $plugin->folder_path . $path
. '/' . $fileName; // we need this for later
// write data to path
$this->file->write($url['path'], $data);
// count the file created
$this->counter->file++;
}
}
}
}
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -9,12 +9,11 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin;
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaThree;
use Joomla\CMS\Factory;
use Joomla\CMS\Filter\OutputFilter;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Customcode;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui;
@ -29,17 +28,18 @@ use VDM\Joomla\Utilities\String\PluginHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\GetHelper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface;
/**
* Joomla Plugin Data Class
* Joomla 3 Plug-in Data Class
*
* @since 3.2.0
*/
class Data
final class Data implements PluginDataInterface
{
/**
* Compiler Joomla Plugins Data
* Compiler Joomla Plug-in's Data
*
* @var array
* @since 3.2.0
@ -47,68 +47,68 @@ class Data
protected array $data = [];
/**
* Compiler Config
* The Configure Class.
*
* @var Config
* @since 3.2.0
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* Compiler Customcode
* The Customcode Class.
*
* @var Customcode
* @since 3.2.0
* @var Customcode
* @since 5.0.2
*/
protected Customcode $customcode;
/**
* Compiler Customcode in Gui
* The Gui Class.
*
* @var Gui
* @since 3.2.0
**/
* @var Gui
* @since 5.0.2
*/
protected Gui $gui;
/**
* Compiler Placeholder
* The Placeholder Class.
*
* @var Placeholder
* @since 3.2.0
**/
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* Compiler Language
* The Language Class.
*
* @var Language
* @since 3.2.0
**/
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* Compiler Field
* The Field Class.
*
* @var Field
* @since 3.2.0
* @var Field
* @since 5.0.2
*/
protected Field $field;
/**
* Compiler field name
* The Name Class.
*
* @var FieldName
* @since 3.2.0
* @var FieldName
* @since 5.0.2
*/
protected FieldName $fieldName;
protected FieldName $fieldname;
/**
* Compiler Files Folders
* The Filesfolders Class.
*
* @var Filesfolders
* @since 3.2.0
* @var Filesfolders
* @since 5.0.2
*/
protected Filesfolders $filesFolders;
protected Filesfolders $filesfolders;
/**
* Database object to query local DB
@ -118,32 +118,32 @@ class Data
protected $db;
/**
* Constructor
* Constructor.
*
* @param Config|null $config The compiler config object.
* @param Customcode|null $customcode The compiler customcode object.
* @param Gui|null $gui The compiler customcode gui.
* @param Placeholder|null $placeholder The compiler placeholder object.
* @param Language|null $language The compiler Language object.
* @param Field|null $field The compiler field data object.
* @param FieldName|null $fieldName The compiler field name object.
* @param Filesfolders|null $filesFolders The compiler files folders object.
* @param Config $config The Config Class.
* @param Customcode $customcode The Customcode Class.
* @param Gui $gui The Gui Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Language $language The Language Class.
* @param Field $field The Field Class.
* @param FieldName $fieldname The Name Class.
* @param Filesfolders $filesfolders The Filesfolders Class.
*
* @since 3.2.0
* @since 5.0.2
*/
public function __construct(?Config $config = null, ?Customcode $customcode = null,
?Gui $gui = null, ?Placeholder $placeholder = null,
?Language $language = null, ?Field $field = null, ?FieldName $fieldName = null,
?Filesfolders $filesFolders = null)
public function __construct(Config $config, Customcode $customcode, Gui $gui,
Placeholder $placeholder, Language $language,
Field $field, FieldName $fieldname,
Filesfolders $filesfolders)
{
$this->config = $config ?: Compiler::_('Config');
$this->customcode = $customcode ?: Compiler::_('Customcode');
$this->gui = $gui ?: Compiler::_('Customcode.Gui');
$this->placeholder = $placeholder ?: Compiler::_('Placeholder');
$this->language = $language ?: Compiler::_('Language');
$this->field = $field ?: Compiler::_('Field');
$this->fieldName = $fieldName ?: Compiler::_('Field.Name');
$this->filesFolders = $filesFolders ?: Compiler::_('Model.Filesfolders');
$this->config = $config;
$this->customcode = $customcode;
$this->gui = $gui;
$this->placeholder = $placeholder;
$this->language = $language;
$this->field = $field;
$this->fieldname = $fieldname;
$this->filesfolders = $filesfolders;
$this->db = Factory::getDbo();
}
@ -454,7 +454,7 @@ class Data
// set GUI mapper field
$guiMapper['field'] = 'head';
// base64 Decode head.
$plugin->head = $this->gui->set(
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->head)
@ -466,7 +466,7 @@ class Data
elseif (!empty($plugin->class_head))
{
// base64 Decode head.
$plugin->head = $this->gui->set(
$plugin->header = $this->gui->set(
$this->placeholder->update_(
$this->customcode->update(
base64_decode((string) $plugin->class_head)
@ -683,7 +683,7 @@ class Data
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldName->get(
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the global form file builder
@ -710,7 +710,7 @@ class Data
foreach ($form['fields'] as $field)
{
// so first we lock the field name in
$this->fieldName->get(
$this->fieldname->get(
$field, $plugin->key, $unique
);
// add the fields to the config builder
@ -730,19 +730,21 @@ class Data
unset($plugin->fields);
// set files and folders
$this->filesFolders->set($plugin);
$this->filesfolders->set($plugin);
// add PHP in plugin install
$plugin->add_install_script = true;
$addScriptMethods = [
'php_preflight',
'php_postflight',
'php_method'
'php_method',
'php_script'
];
$addScriptTypes = [
'install',
'update',
'uninstall'
'uninstall',
'construct'
];
foreach ($addScriptMethods as $scriptMethod)
{
@ -873,7 +875,6 @@ class Data
}
return false;
}
}
}

View File

@ -0,0 +1,338 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaThree;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HeaderInterface as Header;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface as Event;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as Data;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\GetScriptInterface as InstallScript;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ExtensionInterface as Extension;
use VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin\MainXMLInterface as MainXML;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentMulti;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetExtension;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\InfusionInterface;
/**
* Joomla 3 Plugin Infusion Class
*
* @since 5.0.2
*/
final class Infusion implements InfusionInterface
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 5.0.2
*/
protected Placeholder $placeholder;
/**
* The Header Class.
*
* @var Header
* @since 5.0.2
*/
protected Header $header;
/**
* The EventInterface Class.
*
* @var Event
* @since 5.0.2
*/
protected Event $event;
/**
* The Plugin Data Class.
*
* @var Data
* @since 5.0.2
*/
protected Data $data;
/**
* The Get Script Class.
*
* @var InstallScript
* @since 5.0.2
*/
protected InstallScript $installscript;
/**
* The Extension Class.
*
* @var Extension
* @since 5.0.2
*/
protected Extension $extension;
/**
* The Main XML Class.
*
* @var MainXML
* @since 5.0.2
*/
protected MainXML $mainxml;
/**
* The Content Multi Class.
*
* @var ContentMulti
* @since 5.0.2
*/
protected ContentMulti $contentmulti;
/**
* The Fieldset Extension Class.
*
* @var FieldsetExtension
* @since 5.0.2
*/
protected FieldsetExtension $fieldsetextension;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Header $header The HeaderInterface Class.
* @param Event $event The EventInterface Class.
* @param Data $data The PluginDataInterface Class.
* @param InstallScript $installscript The GetScriptInterface Class.
* @param Extension $extension The ExtensionInterface Class.
* @param MainXML $mainxml The MainXMLInterface Class.
* @param ContentMulti $contentmulti The ContentMulti Class.
* @param FieldsetExtension $fieldsetextension The FieldsetExtension Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Placeholder $placeholder, Header $header,
Event $event, Data $data, InstallScript $installscript,
Extension $extension, MainXML $mainxml,
ContentMulti $contentmulti,
FieldsetExtension $fieldsetextension)
{
$this->config = $config;
$this->placeholder = $placeholder;
$this->header = $header;
$this->event = $event;
$this->data = $data;
$this->installscript = $installscript;
$this->extension = $extension;
$this->mainxml = $mainxml;
$this->contentmulti = $contentmulti;
$this->fieldsetextension = $fieldsetextension;
}
/**
* Infuse the plugin data into the content.
*
* This method processes each plugin in the data set, triggering events
* before and after infusion, setting placeholders, and adding content
* such as headers, classes, and XML configurations.
*
* @return void
* @since 5.0.2
*/
public function set(): void
{
if (!$this->data->exists())
{
return;
}
foreach ($this->data->get() as $plugin)
{
if (!ObjectHelper::check($plugin))
{
continue;
}
$this->triggerBeforeInfusionEvent($plugin);
$this->setPlaceholders($plugin);
$this->buildPluginContent($plugin);
$this->triggerAfterInfusionEvent($plugin);
}
}
/**
* Trigger the event before infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerBeforeInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onBeforeInfusePluginData', [&$plugin]);
}
/**
* Set placeholders based on plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setPlaceholders($plugin): void
{
$this->placeholder->set('PluginGroupNamespace', $plugin->group_namespace ?? '');
$this->placeholder->set('PluginNamespace', $plugin->namespace ?? '');
$this->config->build_target = $plugin->key;
$this->config->lang_target = $plugin->key;
$this->config->set('lang_prefix', $plugin->lang_prefix);
}
/**
* Build and set the content related to the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function buildPluginContent($plugin): void
{
$this->setExtensionClassHeader($plugin);
$this->setExtensionClass($plugin);
if ($plugin->add_install_script)
{
$this->setInstallClass($plugin);
}
if (isset($plugin->form_files) && ArrayHelper::check($plugin->form_files))
{
$this->setFieldsets($plugin);
}
$this->setMainXml($plugin);
}
/**
* Set the extension class header content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClassHeader($plugin): void
{
$headerContent = trim(
$this->header->get('plugin.extension.header', $plugin->class_name)
. PHP_EOL . ($plugin->header ?? '')
);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS_HEADER", $headerContent);
}
/**
* Set the extension class content.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setExtensionClass($plugin): void
{
$extensionContent = $this->extension->get($plugin);
$this->contentmulti->set("{$plugin->key}|EXTENSION_CLASS", $extensionContent);
}
/**
* Set the install script content, if needed.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setInstallClass($plugin): void
{
$installContent = $this->installscript->get($plugin);
$this->contentmulti->set("{$plugin->key}|INSTALL_CLASS", $installContent);
}
/**
* Set fieldset content based on form files.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setFieldsets($plugin): void
{
foreach ($plugin->form_files as $file => $files)
{
foreach ($files as $field_name => $fieldsets)
{
foreach ($fieldsets as $fieldset => $fields)
{
$fieldsetContent = $this->fieldsetextension->get($plugin, $fields);
$this->contentmulti->set(
"{$plugin->key}|FIELDSET_{$file}{$field_name}{$fieldset}",
$fieldsetContent
);
}
}
}
}
/**
* Set the main XML content for the plugin.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function setMainXml($plugin): void
{
$mainXmlContent = $this->mainxml->get($plugin);
$this->contentmulti->set("{$plugin->key}|MAINXML", $mainXmlContent);
}
/**
* Trigger the event after infusing the plugin data.
*
* @param object $plugin The plugin object being processed.
*
* @return void
* @since 5.0.2
*/
protected function triggerAfterInfusionEvent(&$plugin): void
{
$this->event->trigger('jcb_ce_onAfterInfusePluginData', [&$plugin]);
}
}

View File

@ -9,10 +9,10 @@
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin;
namespace VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaThree;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\Data as Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
@ -29,14 +29,15 @@ use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\FileHelper;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\StructureInterface;
/**
* Joomla Plugin Builder Class
* Joomla 3 Plugin Builder Class
*
* @since 3.2.0
*/
class Structure
class Structure implements StructureInterface
{
/**
* The Data Class.
@ -306,9 +307,9 @@ class Structure
'<?php' . PHP_EOL . '// Plugin main class template' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');"
. PHP_EOL .
Placefix::_h('MAINCLASS')
"defined('_JEXEC') or die('Restricted access');" . PHP_EOL .
PHP_EOL . Placefix::_h('EXTENSION_CLASS_HEADER') .
PHP_EOL . PHP_EOL . Placefix::_h('EXTENSION_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);
@ -368,7 +369,7 @@ class Structure
PHP_EOL . Placefix::_h('BOM') . PHP_EOL .
PHP_EOL . '// No direct access to this file' . PHP_EOL .
"defined('_JEXEC') or die('Restricted access');" . PHP_EOL .
Placefix::_h('INSTALLCLASS')
Placefix::_h('INSTALL_CLASS')
);
$this->files->appendArray($plugin->key, $file_details);

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -24,7 +24,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Interfaces\LanguageInterface;
*
* @since 3.2.0
*/
class Language implements LanguageInterface
final class Language implements LanguageInterface
{
/**
* The language content

View File

@ -25,7 +25,7 @@ use VDM\Joomla\Utilities\GetHelper;
*
* @since 3.2.0
*/
class Extractor
final class Extractor
{
/**
* The lang keys for extensions

View File

@ -23,7 +23,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Builder\AccessSwitchList;
*
* @since 3.2.0
*/
class Fieldset
final class Fieldset
{
/**
* The Language Class.

View File

@ -0,0 +1,138 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
/**
* Compiler Insert New Language Strings
*
* @since 5.0.2
*/
final class Insert
{
/**
* The items to insert
*
* @var array
* @since 5.0.2
**/
protected array $items = [];
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* Constructor.
*
* @since 5.0.2
*/
public function __construct()
{
$this->db = Factory::getDbo();
}
/**
* Sets a value in a multi-dimensional array within the `items` property.
*
* This method ensures that the array structure is properly initialized before
* inserting the value at the specified target and counter position.
*
* @param string $target The key in the first dimension of the array.
* @param int $counter The key in the second dimension of the array.
* @param string $value The value to be inserted.
*
* @return void
* @since 5.0.2
*/
public function set(string $target, int $counter, string $value): void
{
// Ensure the target key exists in the items array
if (!isset($this->items[$target]))
{
$this->items[$target] = [];
}
// Ensure the counter key exists within the target array
if (!isset($this->items[$target][$counter]))
{
$this->items[$target][$counter] = [];
}
// Append the value to the array at the specified target and counter position
$this->items[$target][$counter][] = $this->db->quote($value);
}
/**
* Store the language placeholders and execute the database insert operation.
*
* This method checks if the target key exists in the `items` array and if the count
* of its elements meets or exceeds the specified threshold (`$when`). If the conditions
* are met, it constructs and executes a database insert query to store the language
* placeholders. The array of items for the target is then cleared.
*
* @param string $target The target extension type.
* @param int $when The threshold count to determine when to update. Default is 1.
*
* @return void
* @since 5.0.2
*/
public function execute(string $target, int $when = 1): void
{
if (isset($this->items[$target]) && count((array) $this->items[$target]) >= $when)
{
// Create a new query object.
$query = $this->db->getQuery(true);
$continue = false;
// Insert columns.
$columns = array($target, 'source', 'published', 'created', 'created_by', 'version', 'access');
// Prepare the insert query.
$query->insert($this->db->quoteName('#__componentbuilder_language_translation'));
$query->columns($this->db->quoteName($columns));
foreach ($this->items[$target] as $values)
{
if (count((array) $values) == 7)
{
$query->values(implode(',', $values));
$continue = true;
}
else
{
// TODO: Handle line mismatch, this should not happen.
}
}
// Clear the values array.
$this->items[$target] = [];
if (!$continue)
{
// Ensure we don't continue if no values were loaded.
return;
}
// Set the query using our newly populated query object and execute it.
$this->db->setQuery($query);
$this->db->execute();
}
}
}

View File

@ -0,0 +1,90 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
use VDM\Joomla\Utilities\ArrayHelper;
/**
* Compiler Language Multilingual
*
* @since 5.0.2
*/
final class Multilingual
{
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* Constructor.
*
* @since 5.0.2
*/
public function __construct()
{
$this->db = Factory::getDbo();
}
/**
* Get the other languages
*
* @param array $values The lang strings to get
*
* @return array
* @since 5.0.2
*/
public function get(array $values): ?array
{
// Create a new query object.
$query = $this->db->getQuery(true);
$query->from(
$this->db->quoteName(
'#__componentbuilder_language_translation', 'a'
)
);
if (ArrayHelper::check($values))
{
$query->select(
$this->db->quoteName(
array('a.id', 'a.translation', 'a.source', 'a.components',
'a.modules', 'a.plugins', 'a.published')
)
);
$query->where(
$this->db->quoteName('a.source') . ' IN (' . implode(
',', array_map(
fn($a) => $this->db->quote($a), $values
)
) . ')'
);
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
return $this->db->loadAssocList('source');
}
}
return null;
}
}

View File

@ -0,0 +1,198 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
use VDM\Joomla\Componentbuilder\Compiler\Language\Update;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\ArrayHelper;
/**
* Compiler Remove Existing Language Strings
*
* @since 5.0.2
*/
final class Purge
{
/**
* The Update Class.
*
* @var Update
* @since 5.0.2
*/
protected Update $update;
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* Constructor.
*
* @param Update $update The Update Class.
*
* @since 5.0.2
*/
public function __construct(Update $update)
{
$this->update = $update;
$this->db = Factory::getDbo();
}
/**
* Purge the unused language strings.
*
* This method removes or updates language strings that are no longer linked
* to the specified component. It checks if the strings are linked to other
* extensions and either updates, archives, or deletes them based on the
* conditions.
*
* @param array $values The active strings.
* @param int $targetId The target component ID.
* @param string $target The target extension type (default is 'components').
*
* @return void
* @since 5.0.2
*/
public function execute(array $values, int $targetId, string $target = 'components'): void
{
$target_types = ['components' => 'components', 'modules' => 'modules', 'plugins' => 'plugins'];
if (isset($target_types[$target]))
{
unset($target_types[$target]);
// Create a new query object.
$query = $this->db->getQuery(true);
$query->from($this->db->quoteName('#__componentbuilder_language_translation', 'a'))
->select($this->db->quoteName(['a.id', 'a.translation', 'a.components', 'a.modules', 'a.plugins']))
->where($this->db->quoteName('a.source') . ' NOT IN (' . implode(',', array_map(fn($a) => $this->db->quote($a), $values)) . ')')
->where($this->db->quoteName('a.published') . ' = 1');
$this->db->setQuery($query);
$this->db->execute();
if ($this->db->getNumRows())
{
$counterUpdate = 0;
$otherStrings = $this->db->loadAssocList();
$today = Factory::getDate()->toSql();
foreach ($otherStrings as $item)
{
if (JsonHelper::check($item[$target]))
{
$targets = (array) json_decode((string) $item[$target], true);
if (($key = array_search($targetId, $targets)) !== false)
{
unset($targets[$key]);
if (ArrayHelper::check($targets))
{
$this->update->set($item['id'], $target, $targets, 1, $today, $counterUpdate);
$counterUpdate++;
$this->update->execute(50);
}
else
{
$this->handleUnlinkedString($item, $target_types, $targets, $today, $counterUpdate);
}
}
}
}
$this->update->execute();
}
}
}
/**
* Handle strings that are unlinked from the current component.
*
* This method checks if a string is linked to other extensions and either updates,
* archives, or deletes it based on the conditions.
*
* @param array $item The language string item.
* @param array $targetTypes The target extension types.
* @param array $targets The targets to update.
* @param string $today The current date.
* @param int $counter The update counter.
*
* @return void
* @since 5.0.2
*/
protected function handleUnlinkedString(array $item, array $targetTypes, array $targets, string $today, int &$counter): void
{
// the action (1 = remove, 2 = archive, 0 = do nothing)
$action_with_string = 1;
foreach ($targetTypes as $other_target)
{
if ($action_with_string && JsonHelper::check($item[$other_target]))
{
$other_targets = (array) json_decode((string) $item[$other_target], true);
if (ArrayHelper::check($other_targets))
{
$action_with_string = 0;
}
}
}
if ($action_with_string && JsonHelper::check($item['translation']))
{
$translation = json_decode((string) $item['translation'], true);
if (ArrayHelper::check($translation))
{
$this->update->set($item['id'], $targets, $targets, 2, $today, $counter);
$counter++;
$this->update->execute(50);
$action_with_string = 2;
}
}
if ($action_with_string == 1)
{
$this->removeExitingLangString($item['id']);
}
}
/**
* Remove existing language translation strings.
*
* This method deletes a language string from the database based on its ID.
*
* @param int $id The string ID to remove.
*
* @return void
* @since 5.0.2
*/
protected function removeExitingLangString(int $id): void
{
$query = $this->db->getQuery(true);
$query->delete($this->db->quoteName('#__componentbuilder_language_translation'))
->where($this->db->quoteName('id') . ' = ' . (int) $id);
$this->db->setQuery($query);
$this->db->execute();
}
}

View File

@ -0,0 +1,277 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Multilingual;
use VDM\Joomla\Componentbuilder\Compiler\Builder\Languages;
use VDM\Joomla\Componentbuilder\Compiler\Language\Insert;
use VDM\Joomla\Componentbuilder\Compiler\Language\Update;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\MathHelper;
/**
* Compiler Set Language Strings
*
* @since 5.0.2
*/
final class Set
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Class.
*
* @var Language
* @since 5.0.2
*/
protected Language $language;
/**
* The Multilingual Class.
*
* @var Multilingual
* @since 5.0.2
*/
protected Multilingual $multilingual;
/**
* The Languages Class.
*
* @var Languages
* @since 5.0.2
*/
protected Languages $languages;
/**
* The Insert Class.
*
* @var Insert
* @since 5.0.2
*/
protected Insert $insert;
/**
* The Update Class.
*
* @var Update
* @since 5.0.2
*/
protected Update $update;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Language $language The Language Class.
* @param Messages $messages The Language Messages Class.
* @param Multilingual $multilingual The Multilingual Class.
* @param Languages $languages The Languages Class.
* @param Insert $insert The Insert Class.
* @param Update $update The Update Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Language $language,
Multilingual $multilingual, Languages $languages,
Insert $insert, Update $update)
{
$this->config = $config;
$this->language = $language;
$this->multilingual = $multilingual;
$this->languages = $languages;
$this->insert = $insert;
$this->update = $update;
}
/**
* Set the current language values to the database.
*
* This method inserts or updates language strings in the database based on the current state.
*
* @param array $strings The language strings to process.
* @param int $target_id The target component ID.
* @param string $target The target extension type (default is 'components').
*
* @return void
* @since 5.0.2
*/
public function execute(array $strings, int $target_id, string $target = 'components'): void
{
$counterInsert = 0;
$counterUpdate = 0;
$today = Factory::getDate()->toSql();
$langTag = $this->config->get('lang_tag', 'en-GB');
$multiLangString = $this->multilingual->get($target, []);
foreach ($this->languages->get("{$target}.{$langTag}") as $area => $placeholders)
{
foreach ($placeholders as $placeholder => $string)
{
if (StringHelper::check($string))
{
$this->processString(
$string, $strings, $area, $placeholder, $multiLangString, $target, $target_id, $today, $counterInsert, $counterUpdate
);
}
}
}
$this->multilingual->set($target, $multiLangString);
$this->update->execute();
$this->insert->execute($target);
}
/**
* Process an individual language string for database update or insert.
*
* @param string $string The language string to process.
* @param array $strings The language strings array.
* @param string $area The targeted area.
* @param string $placeholder The placeholder.
* @param array &$multiLangString The multilingual string array.
* @param string $target The target extension type.
* @param int $target_id The target component ID.
* @param string $today The current date.
* @param int &$counterInsert The insert counter.
* @param int &$counterUpdate The update counter.
*
* @return void
* @since 5.0.2
*/
protected function processString(string $string, array &$strings, string $area,
string $placeholder, array &$multiLangString, string $target,
int $target_id, string $today, int &$counterInsert, int &$counterUpdate): void
{
$remove = false;
if (isset($multiLangString[$string]))
{
if (isset($multiLangString[$string]['translation']) && JsonHelper::check($multiLangString[$string]['translation']))
{
$multiLangString[$string]['translation'] = json_decode((string) $multiLangString[$string]['translation'], true);
}
if (isset($multiLangString[$string]['translation']) && ArrayHelper::check($multiLangString[$string]['translation']))
{
foreach ($multiLangString[$string]['translation'] as $translations)
{
if (isset($translations['language']) && isset($translations['translation']))
{
$multiLangTag = $translations['language'];
$this->languages->set("{$target}.{$multiLangTag}.{$area}.{$placeholder}", $this->language->fix($translations['translation']));
}
}
}
else
{
$remove = true;
}
}
if (StringHelper::check($string) && ($key = array_search($string, $strings)) !== false)
{
$this->updateOrInsertString($string, $multiLangString, $target, $target_id, $today, $counterInsert, $counterUpdate);
if ($remove)
{
unset($multiLangString[$string]);
}
unset($strings[$key]);
}
}
/**
* Update or insert a language string in the database.
*
* @param string $string The language string to update or insert.
* @param array &$multiLangString The multilingual string array.
* @param string $target The target extension type.
* @param int $target_id The target component ID.
* @param string $today The current date.
* @param int &$counterInsert The insert counter.
* @param int &$counterUpdate The update counter.
*
* @return void
* @since 5.0.2
*/
protected function updateOrInsertString(string $string, array &$multiLangString, string $target, int $target_id, string $today, int &$counterInsert, int &$counterUpdate): void
{
if (isset($multiLangString[$string]))
{
$id = $multiLangString[$string]['id'];
$targets = $this->getTargets($multiLangString[$string], $target, $target_id);
$this->update->set($id, $target, $targets, 1, $today, $counterUpdate);
$counterUpdate++;
$this->update->execute(50);
}
else
{
$this->insert->set($target, $counterInsert, json_encode([$target_id]));
$this->insert->set($target, $counterInsert, $string);
$this->insert->set($target, $counterInsert, 1);
$this->insert->set($target, $counterInsert, $today);
$this->insert->set($target, $counterInsert, 1);
$this->insert->set($target, $counterInsert, 1);
$this->insert->set($target, $counterInsert, 1);
$counterInsert++;
$this->insert->execute($target, 100);
}
}
/**
* Get targets for a given string.
*
* @param array $multiLangString The multilingual string array.
* @param string $target The target extension type.
* @param int $target_id The target component ID.
*
* @return array The updated targets array.
* @since 5.0.2
*/
protected function getTargets(array $multiLangString, string $target, int $target_id): array
{
if (JsonHelper::check($multiLangString[$target]))
{
$targets = (array) json_decode((string) $multiLangString[$target], true);
if (!in_array($target_id, $targets))
{
$targets[] = $target_id;
}
}
else
{
$targets = [$target_id];
}
return $targets;
}
}

View File

@ -0,0 +1,101 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Builder\LanguageMessages as Messages;
/**
* Compiler Language Translation Checker
*
* @since 5.0.2
*/
final class Translation
{
/**
* The Config Class.
*
* @var Config
* @since 5.0.2
*/
protected Config $config;
/**
* The Language Messages Class.
*
* @var Messages
* @since 5.0.2
*/
protected Messages $messages;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Messages $messages The Language Messages Class.
*
* @since 5.0.2
*/
public function __construct(Config $config, Messages $messages)
{
$this->config = $config;
$this->messages = $messages;
}
/**
* Check if a translation should be added.
*
* This method determines if a translation should be included based on the percentage
* of translated strings and logs the decision.
*
* @param string $tag The language tag.
* @param array $languageStrings The active language strings.
* @param int $total The total number of strings.
* @param string $file_name The file name.
*
* @return bool Returns true if the translation should be added; false otherwise.
* @since 5.0.2
*/
public function check(string &$tag, array &$languageStrings, int &$total, string &$file_name): bool
{
$langTag = $this->config->get('lang_tag', 'en-GB');
if ($langTag !== $tag)
{
$langStringNr = count($languageStrings);
$percentage = ($langStringNr / $total) * 100;
$stringName = ($langStringNr == 1) ? "(string $tag translated)" : "(strings $tag translated)";
if (!$this->config->get('debug_line_nr', false))
{
if ($percentage < $this->config->percentage_language_add)
{
$this->messages->set(
"exclude.$file_name",
"<b>$total</b>(total " . $langTag . " strings) only <b>$langStringNr</b> $stringName = $percentage"
);
return false;
}
}
$this->messages->set(
"include.$file_name",
"<b>$total</b>(total " . $langTag . " strings) and <b>$langStringNr</b> $stringName = $percentage"
);
}
return true;
}
}

View File

@ -0,0 +1,129 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Language;
use Joomla\CMS\Factory;
/**
* Compiler Update Existing Language Strings
*
* @since 5.0.2
*/
final class Update
{
/**
* The items to update
*
* @var array
* @since 5.0.2
**/
protected array $items = [];
/**
* Database object to query local DB
*
* @since 5.0.2
**/
protected $db;
/**
* User object
*
* @since 5.0.2
**/
protected $user;
/**
* Constructor.
*
* @since 5.0.2
*/
public function __construct()
{
$this->db = Factory::getDbo();
$this->user = Factory::getUser();
}
/**
* Add a language string to the existing language strings array for updating.
*
* This method prepares and stores the update information for a language string
* in the `items` array, which is later used by the `execute` method to update
* the database.
*
* @param int $id The ID of the language string.
* @param string $target The target field to be updated.
* @param array $targets The new values for the target field.
* @param int $published The published state.
* @param string $today The current date.
* @param int $counter The counter for the items array.
*
* @return void
* @since 5.0.2
*/
public function set(int $id, string $target, array $targets, int $published, string $today, int $counter): void
{
// Start the bucket for this language item.
$this->items[$counter] = [];
$this->items[$counter]['id'] = (int) $id;
// Prepare the conditions for the update query.
$this->items[$counter]['conditions'] = [];
$this->items[$counter]['conditions'][] = $this->db->quoteName('id') . ' = ' . $this->db->quote($id);
// Prepare the fields for the update query.
$this->items[$counter]['fields'] = [];
$this->items[$counter]['fields'][] = $this->db->quoteName($target) . ' = ' . $this->db->quote(json_encode($targets));
$this->items[$counter]['fields'][] = $this->db->quoteName('published') . ' = ' . $this->db->quote($published);
$this->items[$counter]['fields'][] = $this->db->quoteName('modified') . ' = ' . $this->db->quote($today);
$this->items[$counter]['fields'][] = $this->db->quoteName('modified_by') . ' = ' . $this->db->quote((int) $this->user->id);
}
/**
* Update the language placeholders in the database.
*
* This method updates the language placeholders in the database if the number of items
* meets or exceeds the specified threshold (`$when`). It constructs and executes an
* update query for each set of values in the `items` array.
*
* @param int $when The threshold count to determine when to update. Default is 1.
*
* @return void
* @since 5.0.2
*/
public function execute(int $when = 1): void
{
if (count((array) $this->items) >= $when)
{
foreach ($this->items as $values)
{
// Create a new query object.
$query = $this->db->getQuery(true);
// Prepare the update query.
$query->update($this->db->quoteName('#__componentbuilder_language_translation'))
->set($values['fields'])
->where($values['conditions']);
// Set the query using our newly populated query object and execute it.
$this->db->setQuery($query);
$this->db->execute();
}
// Clear the items array.
$this->items = [];
}
}
}

View File

@ -13,7 +13,7 @@ namespace VDM\Joomla\Componentbuilder\Compiler\Model;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\Data as Plugin;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as Plugin;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\JsonHelper;

View File

@ -72,7 +72,7 @@ class Autoloader
*
* @param Power $power The Power Class.
* @param Config $config The Config Class.
* @param Content $content The ContentOne Class.
* @param Content $content The Content One Class.
*
* @since 3.2.0
*/

View File

@ -30,7 +30,7 @@ use VDM\Joomla\Utilities\ObjectHelper;
* Compiler Power Infusion
* @since 3.2.0
*/
class Infusion
final class Infusion
{
/**
* The Config Class.

View File

@ -16,6 +16,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PowerInterface as Power;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Power\ExtractorInterface as Extractor;
use VDM\Joomla\Componentbuilder\Power\Parser;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Power\InjectorInterface;
@ -476,6 +477,12 @@ class Injector implements InjectorInterface
*/
protected function addUseStatement(string &$name, string $className, string $namespaceStatement): void
{
// we don't add use statements with just one part
if ($this->countPartsInString($namespaceStatement) <= 1)
{
return; // we just update the code
}
if ($name !== $className)
{
$statement = 'use ' . $namespaceStatement . ' as ' . $name . ';';
@ -488,6 +495,27 @@ class Injector implements InjectorInterface
$this->useStatements[$name] = $statement;
}
/**
* Counts the number of parts in a string separated by backslashes.
*
* @param string $string The input string to be evaluated.
*
* @return int The number of parts separated by backslashes.
* @since 5.0.2
*/
protected function countPartsInString(string $string): int
{
// Split the string by the backslash
$parts = explode('\\', $string);
// Count the number of parts and return the result
if (($number = ArrayHelper::check($parts, true)) !== false)
{
return $number;
}
return 0;
}
/**
* Insert a line before the class declaration in the given class code.
*

View File

@ -0,0 +1,326 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ExtensionInterface as Extension;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin\Extension as J5Extension;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Plugin\Extension as J4Extension;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin\Extension as J3Extension;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Architecture\Plugin\ProviderInterface as Provider;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin\Provider as J5Provider;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Plugin\Provider as J4Provider;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin\Provider as J3Provider;
use VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin\MainXMLInterface as MainXML;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFive\Plugin\MainXML as J5MainXML;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaFour\Plugin\MainXML as J4MainXML;
use VDM\Joomla\Componentbuilder\Compiler\Architecture\JoomlaThree\Plugin\MainXML as J3MainXML;
/**
* Architecture Plugin Service Provider
*
* @since 5.0.2
*/
class ArchitecturePlugin implements ServiceProviderInterface
{
/**
* Current Joomla Version Being Build
*
* @var int
* @since 5.0.2
**/
protected int $targetVersion;
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
* @since 5.0.2
*/
public function register(Container $container)
{
$container->alias(Extension::class, 'Architecture.Plugin.Extension')
->share('Architecture.Plugin.Extension', [$this, 'getExtension'], true);
$container->alias(J5Extension::class, 'Architecture.Plugin.J5.Extension')
->share('Architecture.Plugin.J5.Extension', [$this, 'getJ5Extension'], true);
$container->alias(J4Extension::class, 'Architecture.Plugin.J4.Extension')
->share('Architecture.Plugin.J4.Extension', [$this, 'getJ4Extension'], true);
$container->alias(J3Extension::class, 'Architecture.Plugin.J3.Extension')
->share('Architecture.Plugin.J3.Extension', [$this, 'getJ3Extension'], true);
$container->alias(Provider::class, 'Architecture.Plugin.Provider')
->share('Architecture.Plugin.Provider', [$this, 'getProvider'], true);
$container->alias(J5Provider::class, 'Architecture.Plugin.J5.Provider')
->share('Architecture.Plugin.J5.Provider', [$this, 'getJ5Provider'], true);
$container->alias(J4Provider::class, 'Architecture.Plugin.J4.Provider')
->share('Architecture.Plugin.J4.Provider', [$this, 'getJ4Provider'], true);
$container->alias(J3Provider::class, 'Architecture.Plugin.J3.Provider')
->share('Architecture.Plugin.J3.Provider', [$this, 'getJ3Provider'], true);
$container->alias(MainXML::class, 'Architecture.Plugin.MainXML')
->share('Architecture.Plugin.MainXML', [$this, 'getMainXML'], true);
$container->alias(J5MainXML::class, 'Architecture.Plugin.J5.MainXML')
->share('Architecture.Plugin.J5.MainXML', [$this, 'getJ5MainXML'], true);
$container->alias(J4MainXML::class, 'Architecture.Plugin.J4.MainXML')
->share('Architecture.Plugin.J4.MainXML', [$this, 'getJ4MainXML'], true);
$container->alias(J3MainXML::class, 'Architecture.Plugin.J3.MainXML')
->share('Architecture.Plugin.J3.MainXML', [$this, 'getJ3MainXML'], true);
}
/**
* Get The Extension Class.
*
* @param Container $container The DI container.
*
* @return Extension
* @since 5.0.2
*/
public function getExtension(Container $container): Extension
{
if (empty($this->targetVersion))
{
$this->targetVersion = $container->get('Config')->joomla_version;
}
return $container->get('Architecture.Plugin.J' . $this->targetVersion . '.Extension');
}
/**
* Get The Extension Class.
*
* @param Container $container The DI container.
*
* @return J5Extension
* @since 5.0.2
*/
public function getJ5Extension(Container $container): J5Extension
{
return new J5Extension(
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.One'),
$container->get('Power.Parser')
);
}
/**
* Get The Extension Class.
*
* @param Container $container The DI container.
*
* @return J4Extension
* @since 5.0.2
*/
public function getJ4Extension(Container $container): J4Extension
{
return new J4Extension(
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.One'),
$container->get('Power.Parser')
);
}
/**
* Get The Extension Class.
*
* @param Container $container The DI container.
*
* @return J3Extension
* @since 5.0.2
*/
public function getJ3Extension(Container $container): J3Extension
{
return new J3Extension(
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.One')
);
}
/**
* Get The ProviderInterface Class.
*
* @param Container $container The DI container.
*
* @return Provider
* @since 5.0.2
*/
public function getProvider(Container $container): Provider
{
if (empty($this->targetVersion))
{
$this->targetVersion = $container->get('Config')->joomla_version;
}
return $container->get('Architecture.Plugin.J' . $this->targetVersion . '.Provider');
}
/**
* Get The Provider Class.
*
* @param Container $container The DI container.
*
* @return J5Provider
* @since 5.0.2
*/
public function getJ5Provider(Container $container): J5Provider
{
return new J5Provider(
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.One')
);
}
/**
* Get The Provider Class.
*
* @param Container $container The DI container.
*
* @return J4Provider
* @since 5.0.2
*/
public function getJ4Provider(Container $container): J4Provider
{
return new J4Provider(
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.One')
);
}
/**
* Get The Provider Class.
*
* @param Container $container The DI container.
*
* @return J3Provider
* @since 5.0.2
*/
public function getJ3Provider(Container $container): J3Provider
{
return new J3Provider(
$container->get('Placeholder'),
$container->get('Compiler.Builder.Content.One')
);
}
/**
* Get The MainXML Class.
*
* @param Container $container The DI container.
*
* @return MainXML
* @since 5.0.2
*/
public function getMainXML(Container $container): MainXML
{
if (empty($this->targetVersion))
{
$this->targetVersion = $container->get('Config')->joomla_version;
}
return $container->get('Architecture.Plugin.J' . $this->targetVersion . '.MainXML');
}
/**
* Get The MainXML Class.
*
* @param Container $container The DI container.
*
* @return J5MainXML
* @since 5.0.2
*/
public function getJ5MainXML(Container $container): J5MainXML
{
return new J5MainXML(
$container->get('Config'),
$container->get('Language'),
$container->get('Language.Set'),
$container->get('Language.Purge'),
$container->get('Language.Translation'),
$container->get('Language.Multilingual'),
$container->get('Event'),
$container->get('Compiler.Creator.Fieldset.Extension'),
$container->get('Compiler.Builder.Content.One'),
$container->get('Compiler.Builder.Languages'),
$container->get('Compiler.Builder.Multilingual'),
$container->get('Utilities.Counter'),
$container->get('Utilities.File')
);
}
/**
* Get The MainXML Class.
*
* @param Container $container The DI container.
*
* @return J4MainXML
* @since 5.0.2
*/
public function getJ4MainXML(Container $container): J4MainXML
{
return new J4MainXML(
$container->get('Config'),
$container->get('Language'),
$container->get('Language.Set'),
$container->get('Language.Purge'),
$container->get('Language.Translation'),
$container->get('Language.Multilingual'),
$container->get('Event'),
$container->get('Compiler.Creator.Fieldset.Extension'),
$container->get('Compiler.Builder.Content.One'),
$container->get('Compiler.Builder.Languages'),
$container->get('Compiler.Builder.Multilingual'),
$container->get('Utilities.Counter'),
$container->get('Utilities.File')
);
}
/**
* Get The MainXML Class.
*
* @param Container $container The DI container.
*
* @return J3MainXML
* @since 5.0.2
*/
public function getJ3MainXML(Container $container): J3MainXML
{
return new J3MainXML(
$container->get('Config'),
$container->get('Language'),
$container->get('Language.Set'),
$container->get('Language.Purge'),
$container->get('Language.Translation'),
$container->get('Language.Multilingual'),
$container->get('Event'),
$container->get('Compiler.Creator.Fieldset.Extension'),
$container->get('Compiler.Builder.Content.One'),
$container->get('Compiler.Builder.Languages'),
$container->get('Compiler.Builder.Multilingual'),
$container->get('Utilities.Counter'),
$container->get('Utilities.File')
);
}
}

View File

@ -38,6 +38,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Creator\RouterConstructorDefault;
use VDM\Joomla\Componentbuilder\Compiler\Creator\RouterConstructorManual;
use VDM\Joomla\Componentbuilder\Compiler\Creator\RouterMethodsDefault;
use VDM\Joomla\Componentbuilder\Compiler\Creator\RouterMethodsManual;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetExtension;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetString;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetXML;
use VDM\Joomla\Componentbuilder\Compiler\Creator\FieldsetDynamic;
@ -84,6 +85,9 @@ class Creator implements ServiceProviderInterface
$container->alias(CustomButtonPermissions::class, 'Compiler.Creator.Custom.Button.Permissions')
->share('Compiler.Creator.Custom.Button.Permissions', [$this, 'getCustomButtonPermissions'], true);
$container->alias(FieldsetExtension::class, 'Compiler.Creator.Fieldset.Extension')
->share('Compiler.Creator.Fieldset.Extension', [$this, 'getFieldsetExtension'], true);
$container->alias(ConfigFieldsets::class, 'Compiler.Creator.Config.Fieldsets')
->share('Compiler.Creator.Config.Fieldsets', [$this, 'getConfigFieldsets'], true);
@ -669,6 +673,22 @@ class Creator implements ServiceProviderInterface
);
}
/**
* Get The FieldsetExtension Class.
*
* @param Container $container The DI container.
*
* @return FieldsetExtension
* @since 5.0.2
*/
public function getFieldsetExtension(Container $container): FieldsetExtension
{
return new FieldsetExtension(
$container->get('Component.Placeholder'),
$container->get('Compiler.Creator.Fieldset.Dynamic')
);
}
/**
* Get The FieldsetString Class.
*

View File

@ -14,8 +14,18 @@ namespace VDM\Joomla\Componentbuilder\Compiler\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\Data;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\Structure;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaThree\Data as J3PluginData;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour\Data as J4PluginData;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFive\Data as J5PluginData;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\PluginDataInterface as PluginData;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaThree\Structure as J3Structure;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour\Structure as J4Structure;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFive\Structure as J5Structure;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\StructureInterface as Structure;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaThree\Infusion as J3Infusion;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFour\Infusion as J4Infusion;
use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\JoomlaFive\Infusion as J5Infusion;
use VDM\Joomla\Componentbuilder\Interfaces\Plugin\InfusionInterface as Infusion;
/**
@ -25,34 +35,134 @@ use VDM\Joomla\Componentbuilder\Compiler\Joomlaplugin\Structure;
*/
class Joomlaplugin implements ServiceProviderInterface
{
/**
* Current Joomla Version Being Build
*
* @var int
* @since 5.0.2
**/
protected $targetVersion;
/**
* Registers the service provider with a DI container.
*
* @param Container $container The DI container.
*
* @return void
* @since 3.2.0
* @since 3.2.0
*/
public function register(Container $container)
{
$container->alias(Data::class, 'Joomlaplugin.Data')
->share('Joomlaplugin.Data', [$this, 'getData'], true);
$container->alias(J3PluginData::class, 'Joomlaplugin.J3.Data')
->share('Joomlaplugin.J3.Data', [$this, 'getJ3PluginData'], true);
$container->alias(J4PluginData::class, 'Joomlaplugin.J4.Data')
->share('Joomlaplugin.J4.Data', [$this, 'getJ4PluginData'], true);
$container->alias(J5PluginData::class, 'Joomlaplugin.J5.Data')
->share('Joomlaplugin.J5.Data', [$this, 'getJ5PluginData'], true);
$container->alias(PluginData::class, 'Joomlaplugin.Data')
->share('Joomlaplugin.Data', [$this, 'getPluginData'], true);
$container->alias(J3Structure::class, 'Joomlaplugin.J3.Structure')
->share('Joomlaplugin.J3.Structure', [$this, 'getJ3Structure'], true);
$container->alias(J4Structure::class, 'Joomlaplugin.J4.Structure')
->share('Joomlaplugin.J4.Structure', [$this, 'getJ4Structure'], true);
$container->alias(J5Structure::class, 'Joomlaplugin.J5.Structure')
->share('Joomlaplugin.J5.Structure', [$this, 'getJ5Structure'], true);
$container->alias(Structure::class, 'Joomlaplugin.Structure')
->share('Joomlaplugin.Structure', [$this, 'getStructure'], true);
$container->alias(J3Infusion::class, 'Joomlaplugin.J3.Infusion')
->share('Joomlaplugin.J3.Infusion', [$this, 'getJ3Infusion'], true);
$container->alias(J4Infusion::class, 'Joomlaplugin.J4.Infusion')
->share('Joomlaplugin.J4.Infusion', [$this, 'getJ4Infusion'], true);
$container->alias(J5Infusion::class, 'Joomlaplugin.J5.Infusion')
->share('Joomlaplugin.J5.Infusion', [$this, 'getJ5Infusion'], true);
$container->alias(Infusion::class, 'Joomlaplugin.Infusion')
->share('Joomlaplugin.Infusion', [$this, 'getInfusion'], true);
}
/**
* Get the Joomla Plugin Data
* Get The Plug-in Data Class.
*
* @param Container $container The DI container.
*
* @return Data
* @since 3.2.0
* @return PluginData
* @since 5.0.2
*/
public function getData(Container $container): Data
public function getPluginData(Container $container): PluginData
{
return new Data(
if (empty($this->targetVersion))
{
$this->targetVersion = $container->get('Config')->joomla_version;
}
return $container->get('Joomlaplugin.J' . $this->targetVersion . '.Data');
}
/**
* Get The PluginData Class.
*
* @param Container $container The DI container.
*
* @return J3PluginData
* @since 5.0.2
*/
public function getJ3PluginData(Container $container): J3PluginData
{
return new J3PluginData(
$container->get('Config'),
$container->get('Customcode'),
$container->get('Customcode.Gui'),
$container->get('Placeholder'),
$container->get('Language'),
$container->get('Field'),
$container->get('Field.Name'),
$container->get('Model.Filesfolders')
);
}
/**
* Get The PluginData Class.
*
* @param Container $container The DI container.
*
* @return J4PluginData
* @since 5.0.2
*/
public function getJ4PluginData(Container $container): J4PluginData
{
return new J4PluginData(
$container->get('Config'),
$container->get('Customcode'),
$container->get('Customcode.Gui'),
$container->get('Placeholder'),
$container->get('Language'),
$container->get('Field'),
$container->get('Field.Name'),
$container->get('Model.Filesfolders')
);
}
/**
* Get The PluginData Class.
*
* @param Container $container The DI container.
*
* @return J5PluginData
* @since 5.0.2
*/
public function getJ5PluginData(Container $container): J5PluginData
{
return new J5PluginData(
$container->get('Config'),
$container->get('Customcode'),
$container->get('Customcode.Gui'),
@ -70,11 +180,29 @@ class Joomlaplugin implements ServiceProviderInterface
* @param Container $container The DI container.
*
* @return Structure
* @since 3.2.0
* @since 3.2.0
*/
public function getStructure(Container $container): Structure
{
return new Structure(
if (empty($this->targetVersion))
{
$this->targetVersion = $container->get('Config')->joomla_version;
}
return $container->get('Joomlaplugin.J' . $this->targetVersion . '.Structure');
}
/**
* Get the Joomla 3 Plugin Structure Builder
*
* @param Container $container The DI container.
*
* @return Structure
* @since 5.0.2
*/
public function getJ3Structure(Container $container): J3Structure
{
return new J3Structure(
$container->get('Joomlaplugin.Data'),
$container->get('Component'),
$container->get('Config'),
@ -87,6 +215,149 @@ class Joomlaplugin implements ServiceProviderInterface
$container->get('Utilities.Files')
);
}
/**
* Get the Joomla 4 Plugin Structure Builder
*
* @param Container $container The DI container.
*
* @return Structure
* @since 5.0.2
*/
public function getJ4Structure(Container $container): J4Structure
{
return new J4Structure(
$container->get('Joomlaplugin.Data'),
$container->get('Component'),
$container->get('Config'),
$container->get('Registry'),
$container->get('Customcode.Dispenser'),
$container->get('Event'),
$container->get('Utilities.Counter'),
$container->get('Utilities.Folder'),
$container->get('Utilities.File'),
$container->get('Utilities.Files'),
$container->get('Placeholder')
);
}
/**
* Get the Joomla 5 Plugin Structure Builder
*
* @param Container $container The DI container.
*
* @return Structure
* @since 5.0.2
*/
public function getJ5Structure(Container $container): J5Structure
{
return new J5Structure(
$container->get('Joomlaplugin.Data'),
$container->get('Component'),
$container->get('Config'),
$container->get('Registry'),
$container->get('Customcode.Dispenser'),
$container->get('Event'),
$container->get('Utilities.Counter'),
$container->get('Utilities.Folder'),
$container->get('Utilities.File'),
$container->get('Utilities.Files'),
$container->get('Placeholder')
);
}
/**
* Get The InfusionInterface Class.
*
* @param Container $container The DI container.
*
* @return Infusion
* @since 5.0.2
*/
public function getInfusion(Container $container): Infusion
{
if (empty($this->targetVersion))
{
$this->targetVersion = $container->get('Config')->joomla_version;
}
return $container->get('Joomlaplugin.J' . $this->targetVersion . '.Infusion');
}
/**
* Get The Infusion Class.
*
* @param Container $container The DI container.
*
* @return J3Infusion
* @since 5.0.2
*/
public function getJ3Infusion(Container $container): J3Infusion
{
return new J3Infusion(
$container->get('Config'),
$container->get('Placeholder'),
$container->get('Header'),
$container->get('Event'),
$container->get('Joomlaplugin.Data'),
$container->get('Extension.InstallScript'),
$container->get('Architecture.Plugin.Extension'),
$container->get('Architecture.Plugin.MainXML'),
$container->get('Compiler.Builder.Content.Multi'),
$container->get('Compiler.Creator.Fieldset.Extension')
);
}
/**
* Get The Infusion Class.
*
* @param Container $container The DI container.
*
* @return J4Infusion
* @since 5.0.2
*/
public function getJ4Infusion(Container $container): J4Infusion
{
return new J4Infusion(
$container->get('Config'),
$container->get('Placeholder'),
$container->get('Header'),
$container->get('Event'),
$container->get('Joomlaplugin.Data'),
$container->get('Extension.InstallScript'),
$container->get('Architecture.Plugin.Extension'),
$container->get('Architecture.Plugin.Provider'),
$container->get('Architecture.Plugin.MainXML'),
$container->get('Compiler.Builder.Content.Multi'),
$container->get('Compiler.Builder.Content.One'),
$container->get('Compiler.Creator.Fieldset.Extension')
);
}
/**
* Get The Infusion Class.
*
* @param Container $container The DI container.
*
* @return J5Infusion
* @since 5.0.2
*/
public function getJ5Infusion(Container $container): J5Infusion
{
return new J5Infusion(
$container->get('Config'),
$container->get('Placeholder'),
$container->get('Header'),
$container->get('Event'),
$container->get('Joomlaplugin.Data'),
$container->get('Extension.InstallScript'),
$container->get('Architecture.Plugin.Extension'),
$container->get('Architecture.Plugin.Provider'),
$container->get('Architecture.Plugin.MainXML'),
$container->get('Compiler.Builder.Content.Multi'),
$container->get('Compiler.Builder.Content.One'),
$container->get('Compiler.Creator.Fieldset.Extension')
);
}
}

View File

@ -15,8 +15,14 @@ namespace VDM\Joomla\Componentbuilder\Compiler\Service;
use Joomla\DI\Container;
use Joomla\DI\ServiceProviderInterface;
use VDM\Joomla\Componentbuilder\Compiler\Language as CompilerLanguage;
use VDM\Joomla\Componentbuilder\Compiler\Language\Set;
use VDM\Joomla\Componentbuilder\Compiler\Language\Purge;
use VDM\Joomla\Componentbuilder\Compiler\Language\Insert;
use VDM\Joomla\Componentbuilder\Compiler\Language\Update;
use VDM\Joomla\Componentbuilder\Compiler\Language\Extractor;
use VDM\Joomla\Componentbuilder\Compiler\Language\Fieldset;
use VDM\Joomla\Componentbuilder\Compiler\Language\Multilingual;
use VDM\Joomla\Componentbuilder\Compiler\Language\Translation;
/**
@ -39,11 +45,29 @@ class Language implements ServiceProviderInterface
$container->alias(CompilerLanguage::class, 'Language')
->share('Language', [$this, 'getCompilerLanguage'], true);
$container->alias(Set::class, 'Language.Set')
->share('Language.Set', [$this, 'getSet'], true);
$container->alias(Purge::class, 'Language.Purge')
->share('Language.Purge', [$this, 'getPurge'], true);
$container->alias(Insert::class, 'Language.Insert')
->share('Language.Insert', [$this, 'getInsert'], true);
$container->alias(Update::class, 'Language.Update')
->share('Language.Update', [$this, 'getUpdate'], true);
$container->alias(Extractor::class, 'Language.Extractor')
->share('Language.Extractor', [$this, 'getExtractor'], true);
$container->alias(Fieldset::class, 'Language.Fieldset')
->share('Language.Fieldset', [$this, 'getFieldset'], true);
$container->alias(Multilingual::class, 'Language.Multilingual')
->share('Language.Multilingual', [$this, 'getMultilingual'], true);
$container->alias(Translation::class, 'Language.Translation')
->share('Language.Translation', [$this, 'getTranslation'], true);
}
/**
@ -61,6 +85,67 @@ class Language implements ServiceProviderInterface
);
}
/**
* Get The Set Class.
*
* @param Container $container The DI container.
*
* @return Set
* @since 3.2.0
*/
public function getSet(Container $container): Set
{
return new Set(
$container->get('Config'),
$container->get('Language'),
$container->get('Compiler.Builder.Multilingual'),
$container->get('Compiler.Builder.Languages'),
$container->get('Language.Insert'),
$container->get('Language.Update')
);
}
/**
* Get The Purge Class.
*
* @param Container $container The DI container.
*
* @return Purge
* @since 5.0.2
*/
public function getPurge(Container $container): Purge
{
return new Purge(
$container->get('Language.Update')
);
}
/**
* Get The Insert Class.
*
* @param Container $container The DI container.
*
* @return Insert
* @since 5.0.2
*/
public function getInsert(Container $container): Insert
{
return new Insert();
}
/**
* Get The Update Class.
*
* @param Container $container The DI container.
*
* @return Update
* @since 5.0.2
*/
public function getUpdate(Container $container): Update
{
return new Update();
}
/**
* Get The Extractor Class.
*
@ -94,6 +179,35 @@ class Language implements ServiceProviderInterface
$container->get('Compiler.Builder.Access.Switch'),
$container->get('Compiler.Builder.Access.Switch.List')
);
}
/**
* Get The Multilingual Class.
*
* @param Container $container The DI container.
*
* @return Multilingual
* @since 5.0.2
*/
public function getMultilingual(Container $container): Multilingual
{
return new Multilingual();
}
/**
* Get The Translation Class.
*
* @param Container $container The DI container.
*
* @return Translation
* @since 3.2.0
*/
public function getTranslation(Container $container): Translation
{
return new Translation(
$container->get('Config'),
$container->get('Compiler.Builder.Language.Messages')
);
}
}

View File

@ -0,0 +1,32 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Interfaces\Architecture\Plugin;
/**
* Main XML Interface
*
* @since 5.0.0
*/
interface MainXMLInterface
{
/**
* Generates the main XML for the plugin.
*
* @param object $plugin The plugin object.
*
* @return string The generated XML.
* @since 5.0.2
*/
public function get(object $plugin): string;
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@ -0,0 +1,34 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Interfaces\Plugin;
/**
* Plug-in Infusion Interface
*
* @since 5.0.2
*/
interface InfusionInterface
{
/**
* Infuse the plugin data into the content.
*
* This method processes each plugin in the data set, triggering events
* before and after infusion, setting placeholders, and adding content
* such as headers, classes, and XML configurations.
*
* @return void
* @since 5.0.2
*/
public function set(): void;
}

View File

@ -0,0 +1,30 @@
<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Interfaces\Plugin;
/**
* Structure Interface
*
* @since 5.0.0
*/
interface StructureInterface
{
/**
* Build the Plug-ins files, folders, url's and configure
*
* @return void
* @since 5.0.0
*/
public function build();
}

View File

@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>