Release of v4.1.1-rc1
Move all banners to GitHub. Adds library phpspreadsheet to JCB. Add import item example to demo component. Updates the Superpower class with the GetRemote class in the plugin. Ensures the super power autoloader triggers the correct repositories. Adds the Import Function to the Demo Component. Resolves the Database Updating issue in the compiler. #1212,#1209. Adds the Component Commands Plugin to the CLI for Import of spreadsheet data-sets. Add all needed Powers to the release package, to speed-up the build of the demo component. Refactored initialization flow to accommodate future scalability and integration with all designated areas. Refactor the Creator Builders class. Adds new JCB package engine. Fix issue with loading the Component Builder Wiki. Adds advanced version update notice to the Component Builder Dashboard. Completely refactors the class that builds the Component Dashboard. #1134. Adds Initialize, Reset, and Push functionality to the Repository entities. Completely refactors the SQL teaks and SQL dump classes. Changes J4 fields to allow NULL. Fix a bug in Dynamic Get JavaScript that causes table columns to not load. Refactor the FieldString and FieldXML classes.
This commit is contained in:
28
CHANGELOG.md
28
CHANGELOG.md
@@ -1,19 +1,4 @@
|
||||
# v4.1.1-beta2
|
||||
|
||||
- Adds new JCB package engine.
|
||||
- Fix issue with loading the Component Builder Wiki.
|
||||
- Adds advanced version update notice to the Component Builder Dashboard.
|
||||
- Completely refactors the class that builds the Component Dashboard. #1134
|
||||
- Adds Initialize, Reset, and Push functionality to the Repository entities.
|
||||
- Completely refactors the SQL teaks and SQL dump classes.
|
||||
- Changes J4 fields to allow NULL.
|
||||
- Fix a bug in Dynamic Get JavaScript that causes table columns to not load.
|
||||
|
||||
# v4.1.1-beta
|
||||
|
||||
- Refactor the FieldString and FieldXML classes.
|
||||
|
||||
# v4.1.1-alpha
|
||||
# v4.1.1-rc1
|
||||
|
||||
- Move all banners to GitHub.
|
||||
- Adds library phpspreadsheet to JCB.
|
||||
@@ -25,7 +10,16 @@
|
||||
- Adds the Component Commands Plugin to the CLI for Import of spreadsheet data-sets.
|
||||
- Add all needed Powers to the release package, to speed-up the build of the demo component.
|
||||
- Refactored initialization flow to accommodate future scalability and integration with all designated areas.
|
||||
- Refactor the Creator Builders class.
|
||||
- Refactor the Creator Builders class.
|
||||
- Adds new JCB package engine.
|
||||
- Fix issue with loading the Component Builder Wiki.
|
||||
- Adds advanced version update notice to the Component Builder Dashboard.
|
||||
- Completely refactors the class that builds the Component Dashboard. #1134
|
||||
- Adds Initialize, Reset, and Push functionality to the Repository entities.
|
||||
- Completely refactors the SQL teaks and SQL dump classes.
|
||||
- Changes J4 fields to allow NULL.
|
||||
- Fix a bug in Dynamic Get JavaScript that causes table columns to not load.
|
||||
- Refactor the FieldString and FieldXML classes.
|
||||
|
||||
# v4.1.0
|
||||
|
||||
|
@@ -3292,7 +3292,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.1.1-beta2 Was Successful! Let us know if anything is not working as expected.</h3></div>';
|
||||
<h3>Upgrade to Version 4.1.1-rc1 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();
|
||||
|
@@ -9,7 +9,7 @@ This is a professional-grade [Joomla 4.x](https://extensions.joomla.org/extensio
|
||||
|
||||
JCB generates native Joomla components, plugins, and modules for Joomla 3.x, 4.x, and 5.x - and is already prepared for Joomla 6. Every compiled project is tailored for the specific version without needing backward compatibility plugins. With integrated version-aware compiling, smart boilerplating, and Git-powered project syncing, JCB is much more than a code generator-it's a **full-stack development pipeline for Joomla extensions**.
|
||||
|
||||
You can install this component easily. The latest release (**4.1.1-beta2**) is available on [Releases](https://git.vdm.dev/joomla/pkg-component-builder/releases) and updated frequently with full source access.
|
||||
You can install this component easily. The latest release (**4.1.1-rc1**) is available on [Releases](https://git.vdm.dev/joomla/pkg-component-builder/releases) and updated frequently with full source access.
|
||||
|
||||
Upgrades are seamless through Joomla's built-in extension update mechanism.
|
||||
|
||||
@@ -229,9 +229,9 @@ JCB is developed by developers for developers. Its purpose is to democratize hig
|
||||
* **Company:** [Vast Development Method](https://dev.vdm.io)
|
||||
* **Author:** [Llewellyn van der Merwe](mailto:joomla@vdm.io)
|
||||
* **Component:** [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
* **Created:** 30th April, 2015 · **Last Build:** 27th June, 2025 · **Version:** 4.1.1-beta2
|
||||
* **Created:** 30th April, 2015 · **Last Build:** 2nd July, 2025 · **Version:** 4.1.1-rc1
|
||||
* **License:** GNU General Public License version 2 or later; see LICENSE.txt · **Copyright:** Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* **Lines:** 1085476 · **Fields:** 2090 · **Files:** 7349 · **Folders:** 716
|
||||
* **Lines:** 1086394 · **Fields:** 2090 · **Files:** 7357 · **Folders:** 716
|
||||
|
||||
> Generated with [JCB](https://www.joomlacomponentbuilder.com) — The Smartest Way to Build Joomla Extensions.
|
||||
|
||||
|
@@ -9,7 +9,7 @@ This is a professional-grade [Joomla 4.x](https://extensions.joomla.org/extensio
|
||||
|
||||
JCB generates native Joomla components, plugins, and modules for Joomla 3.x, 4.x, and 5.x - and is already prepared for Joomla 6. Every compiled project is tailored for the specific version without needing backward compatibility plugins. With integrated version-aware compiling, smart boilerplating, and Git-powered project syncing, JCB is much more than a code generator-it's a **full-stack development pipeline for Joomla extensions**.
|
||||
|
||||
You can install this component easily. The latest release (**4.1.1-beta2**) is available on [Releases](https://git.vdm.dev/joomla/pkg-component-builder/releases) and updated frequently with full source access.
|
||||
You can install this component easily. The latest release (**4.1.1-rc1**) is available on [Releases](https://git.vdm.dev/joomla/pkg-component-builder/releases) and updated frequently with full source access.
|
||||
|
||||
Upgrades are seamless through Joomla's built-in extension update mechanism.
|
||||
|
||||
@@ -229,9 +229,9 @@ JCB is developed by developers for developers. Its purpose is to democratize hig
|
||||
* **Company:** [Vast Development Method](https://dev.vdm.io)
|
||||
* **Author:** [Llewellyn van der Merwe](mailto:joomla@vdm.io)
|
||||
* **Component:** [Component Builder](https://git.vdm.dev/joomla/Component-Builder)
|
||||
* **Created:** 30th April, 2015 · **Last Build:** 27th June, 2025 · **Version:** 4.1.1-beta2
|
||||
* **Created:** 30th April, 2015 · **Last Build:** 2nd July, 2025 · **Version:** 4.1.1-rc1
|
||||
* **License:** GNU General Public License version 2 or later; see LICENSE.txt · **Copyright:** Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||||
* **Lines:** 1085476 · **Fields:** 2090 · **Files:** 7349 · **Folders:** 716
|
||||
* **Lines:** 1086394 · **Fields:** 2090 · **Files:** 7357 · **Folders:** 716
|
||||
|
||||
> Generated with [JCB](https://www.joomlacomponentbuilder.com) — The Smartest Way to Build Joomla Extensions.
|
||||
|
||||
|
@@ -20,76 +20,104 @@ use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Mail\Mail;
|
||||
use Joomla\Registry\Registry;
|
||||
|
||||
// No direct access to this file
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* ###Component### component email helper
|
||||
*
|
||||
* @since 3.0
|
||||
* Provides a complete and configurable mailer integration for Joomla components.
|
||||
* Allows for custom headers, DKIM signing, embedded images, and HTML styling.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
abstract class ###Component###Email
|
||||
{
|
||||
/**
|
||||
* The active recipient
|
||||
* The active recipient.
|
||||
*
|
||||
* @var activeRecipient (array)
|
||||
* @var array<string, mixed>
|
||||
* @since 3.0
|
||||
*/
|
||||
public static $active = [];
|
||||
public static array $active = [];
|
||||
|
||||
/**
|
||||
* Configuration object
|
||||
* Mail instances container.
|
||||
*
|
||||
* @var Registry
|
||||
* @var Joomla___890fd6b1_0127_4f35_9b6e_ee6f2dc61bcc___Power[]
|
||||
* @since 1.7.3
|
||||
*/
|
||||
public static ?Registry $config = null;
|
||||
protected static array $instances = [];
|
||||
|
||||
/**
|
||||
* Mailer object
|
||||
* Global Configuration object.
|
||||
*
|
||||
* @var Mail
|
||||
* @var Registry|null
|
||||
* @since 5.1.1
|
||||
*/
|
||||
public static ?Mail $mailer = null;
|
||||
protected static ?Registry $gConfig = null;
|
||||
|
||||
/**
|
||||
* Custom Headers
|
||||
* Component Configuration object.
|
||||
*
|
||||
* @var array
|
||||
* @var Registry|null
|
||||
* @since 3.0
|
||||
*/
|
||||
protected static ?Registry $config = null;
|
||||
|
||||
/**
|
||||
* Mailer object.
|
||||
*
|
||||
* @var Joomla___890fd6b1_0127_4f35_9b6e_ee6f2dc61bcc___Power|null
|
||||
* @since 3.0
|
||||
*/
|
||||
protected static ?Joomla___890fd6b1_0127_4f35_9b6e_ee6f2dc61bcc___Power $mailer = null;
|
||||
|
||||
/**
|
||||
* Custom email headers.
|
||||
*
|
||||
* @var array<string, string>
|
||||
* @since 3.0
|
||||
*/
|
||||
protected static array $header = [];
|
||||
|
||||
/**
|
||||
* Get a configuration object
|
||||
* Retrieve the component configuration.
|
||||
*
|
||||
* @return Registry Component configuration object
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function getConfig()
|
||||
protected static function getConfig(): Registry
|
||||
{
|
||||
if (!self::$config)
|
||||
{
|
||||
self::$config = Joomla___aeb8e463_291f_4445_9ac4_34b637c12dbd___Power::getParams('com_###component###');
|
||||
}
|
||||
|
||||
return self::$config;
|
||||
return self::$config ??= Joomla___aeb8e463_291f_4445_9ac4_34b637c12dbd___Power::getParams('com_###component###');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the global mailer object, only creating it if it doesn't already exist.
|
||||
* Retrieve the global configuration.
|
||||
*
|
||||
* @return Registry Global configuration object
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function getMailerInstance()
|
||||
protected static function getGlobalConfig(): Registry
|
||||
{
|
||||
if (!self::$mailer)
|
||||
{
|
||||
self::$mailer = self::createMailer();
|
||||
}
|
||||
|
||||
return self::$mailer;
|
||||
return self::$gConfig ??= Joomla___39403062_84fb_46e0_bac4_0023f766e827___Power::getApplication()->getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a string looks like an email address.
|
||||
* @param string $address The email address to check
|
||||
* @param string|callable $patternselect A selector for the validation pattern to use :
|
||||
* Get or create a Mailer instance.
|
||||
*
|
||||
* @return Joomla___890fd6b1_0127_4f35_9b6e_ee6f2dc61bcc___Power A cloned Mail object instance
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function getMailer(): Joomla___890fd6b1_0127_4f35_9b6e_ee6f2dc61bcc___Power
|
||||
{
|
||||
return self::$mailer ??= self::createMailer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an email address using a selected pattern or callable.
|
||||
*
|
||||
* @param string $address Email address to validate.
|
||||
* @param string|callable|null $patternselect Validation pattern or callable.
|
||||
* * `auto` Pick best pattern automatically;
|
||||
* * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
|
||||
* * `pcre` Use old PCRE implementation;
|
||||
@@ -101,374 +129,357 @@ abstract class ###Component###Email
|
||||
* return (strpos($address, '@') !== false);
|
||||
* });
|
||||
* You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
|
||||
* @return boolean
|
||||
* @static
|
||||
* @access public
|
||||
*
|
||||
* @return bool True if valid, false otherwise
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function validateAddress($address, $patternselect = null): bool
|
||||
public static function validateAddress(string $address, $patternselect = null): bool
|
||||
{
|
||||
return self::getMailerInstance()->validateAddress($address, $patternselect);
|
||||
return self::getMailer()->validateAddress($address, $patternselect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mailer object.
|
||||
* Set a custom email header.
|
||||
*
|
||||
* Returns the global {@link Mail} object, only creating it if it doesn't already exist.
|
||||
* @param string $key Header name.
|
||||
* @param string $value Header value.
|
||||
*
|
||||
* @return Mail object
|
||||
*
|
||||
* @see Mail
|
||||
* @return void
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function getMailer(): Mail
|
||||
public static function setHeader(string $key, string $value): void
|
||||
{
|
||||
if (!self::$mailer)
|
||||
self::$header[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create a Mail instance with specific configuration.
|
||||
*
|
||||
* @param string $id Instance ID.
|
||||
* @param bool $exceptions Enable exceptions.
|
||||
*
|
||||
* @return Joomla___890fd6b1_0127_4f35_9b6e_ee6f2dc61bcc___Power Configured Mail instance
|
||||
* @since 5.1.1
|
||||
*/
|
||||
public static function getInstance(string $id = 'Joomla', bool $exceptions = true): Joomla___890fd6b1_0127_4f35_9b6e_ee6f2dc61bcc___Power
|
||||
{
|
||||
if (!isset(self::$instances[$id]))
|
||||
{
|
||||
self::$mailer = self::createMailer();
|
||||
$config = clone self::getGlobalConfig();
|
||||
$config->set('throw_exceptions', $exceptions);
|
||||
self::$instances[$id] = Joomla___39403062_84fb_46e0_bac4_0023f766e827___Power::getContainer()->get(Joomla___3e2779e9_b33f_42b8_a13b_53f08d99f15b___Power::class)->createMailer($config);
|
||||
}
|
||||
|
||||
$copy = clone self::$mailer;
|
||||
|
||||
return $copy;
|
||||
return self::$instances[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mailer object
|
||||
* Create a configured Mail instance.
|
||||
*
|
||||
* @return Mail object
|
||||
*
|
||||
* @see Mail
|
||||
* @return Joomla___890fd6b1_0127_4f35_9b6e_ee6f2dc61bcc___Power The created Mail object with sender, reply-to and transport settings.
|
||||
* @since 3.0
|
||||
*/
|
||||
protected static function createMailer(): Mail
|
||||
protected static function createMailer(): Joomla___890fd6b1_0127_4f35_9b6e_ee6f2dc61bcc___Power
|
||||
{
|
||||
// set component params
|
||||
$conf = self::getConfig();
|
||||
|
||||
// now load the mailer
|
||||
$conf = self::getConfig();
|
||||
$mailer = $conf->get('mailer', 'global');
|
||||
$mail = self::getInstance();
|
||||
|
||||
// Create a Mail object
|
||||
$mail = Mail::getInstance();
|
||||
|
||||
// check if set to global
|
||||
if ('global' == $mailer)
|
||||
if ($mailer === 'global')
|
||||
{
|
||||
// get the global details
|
||||
$globalConf = Joomla___39403062_84fb_46e0_bac4_0023f766e827___Power::getConfig();
|
||||
|
||||
$mailer = $globalConf->get('mailer');
|
||||
$smtpauth = ($globalConf->get('smtpauth') == 0) ? null : 1;
|
||||
$smtpuser = $globalConf->get('smtpuser');
|
||||
$smtppass = $globalConf->get('smtppass');
|
||||
$smtphost = $globalConf->get('smtphost');
|
||||
$smtpsecure = $globalConf->get('smtpsecure');
|
||||
$smtpport = $globalConf->get('smtpport');
|
||||
$sendmail = $globalConf->get('sendmail');
|
||||
$mailfrom = $globalConf->get('mailfrom');
|
||||
$fromname = $globalConf->get('fromname');
|
||||
$replyto = $globalConf->get('replyto');
|
||||
$replytoname = $globalConf->get('replytoname');
|
||||
$global = self::getGlobalConfig();
|
||||
$mailer = $global->get('mailer');
|
||||
$params = [
|
||||
'smtpauth' => $global->get('smtpauth') ? 1 : null,
|
||||
'smtpuser' => $global->get('smtpuser'),
|
||||
'smtppass' => $global->get('smtppass'),
|
||||
'smtphost' => $global->get('smtphost'),
|
||||
'smtpsecure' => $global->get('smtpsecure'),
|
||||
'smtpport' => $global->get('smtpport'),
|
||||
'sendmail' => $global->get('sendmail'),
|
||||
'from' => $global->get('mailfrom'),
|
||||
'name' => $global->get('fromname'),
|
||||
'replyto' => $global->get('replyto'),
|
||||
'replytoname' => $global->get('replytoname'),
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
$smtpauth = ($conf->get('smtpauth') == 0) ? null : 1;
|
||||
$smtpuser = $conf->get('smtpuser');
|
||||
$smtppass = $conf->get('smtppass');
|
||||
$smtphost = $conf->get('smtphost');
|
||||
$smtpsecure = $conf->get('smtpsecure');
|
||||
$smtpport = $conf->get('smtpport');
|
||||
$sendmail = $conf->get('sendmail');
|
||||
$mailfrom = $conf->get('emailfrom');
|
||||
$fromname = $conf->get('fromname');
|
||||
$replyto = $conf->get('replyto');
|
||||
$replytoname = $conf->get('replytoname');
|
||||
$params = [
|
||||
'smtpauth' => $conf->get('smtpauth') ? 1 : null,
|
||||
'smtpuser' => $conf->get('smtpuser'),
|
||||
'smtppass' => $conf->get('smtppass'),
|
||||
'smtphost' => $conf->get('smtphost'),
|
||||
'smtpsecure' => $conf->get('smtpsecure'),
|
||||
'smtpport' => $conf->get('smtpport'),
|
||||
'sendmail' => $conf->get('sendmail'),
|
||||
'from' => $conf->get('emailfrom'),
|
||||
'name' => $conf->get('fromname'),
|
||||
'replyto' => $conf->get('replyto'),
|
||||
'replytoname' => $conf->get('replytoname'),
|
||||
];
|
||||
}
|
||||
|
||||
// Set global sender
|
||||
$mail->setSender(array($mailfrom, $fromname));
|
||||
$mail->setSender([$params['from'], $params['name']]);
|
||||
|
||||
// set the global reply-to if found
|
||||
if ($replyto && $replytoname)
|
||||
{
|
||||
if (!empty($params['replyto']) && !empty($params['replytoname']))
|
||||
{
|
||||
$mail->ClearReplyTos();
|
||||
$mail->addReplyTo($replyto, $replytoname);
|
||||
$mail->addReplyTo($params['replyto'], $params['replytoname']);
|
||||
}
|
||||
|
||||
// Default mailer is to use PHP's mail function
|
||||
switch ($mailer)
|
||||
{
|
||||
case 'smtp':
|
||||
// set the SMTP option
|
||||
$mail->useSMTP($smtpauth, $smtphost, $smtpuser, $smtppass, $smtpsecure, $smtpport);
|
||||
$mail->useSMTP(
|
||||
$params['smtpauth'],
|
||||
$params['smtphost'],
|
||||
$params['smtpuser'],
|
||||
$params['smtppass'],
|
||||
$params['smtpsecure'],
|
||||
$params['smtpport']
|
||||
);
|
||||
break;
|
||||
|
||||
case 'sendmail':
|
||||
// set the sendmail option
|
||||
$mail->useSendmail($sendmail);
|
||||
$mail->useSendmail($params['sendmail']);
|
||||
$mail->IsSendmail();
|
||||
break;
|
||||
|
||||
default:
|
||||
$mail->IsMail();
|
||||
break;
|
||||
}
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a Mail custom header.
|
||||
* Compose and send an email with full options including attachments, HTML, DKIM, and reply-to support.
|
||||
*
|
||||
* @return void
|
||||
* @param string|array $recipient Email or list of recipients.
|
||||
* @param string $subject Subject line.
|
||||
* @param string $body HTML body.
|
||||
* @param string|null $textonly Optional plain text fallback.
|
||||
* @param int $mode 1 = HTML, 0 = plain text.
|
||||
* @param string|null $bounce_email Optional bounce email address.
|
||||
* @param string|null $idsession Optional message tracking tag.
|
||||
* @param string|array|null $mailreply Optional reply-to address(es).
|
||||
* @param string|array|null $replyname Optional reply-to name(s).
|
||||
* @param string|null $mailfrom Optional sender email override.
|
||||
* @param string|null $fromname Optional sender name override.
|
||||
* @param array|null $cc CC recipients.
|
||||
* @param array|null $bcc BCC recipients.
|
||||
* @param array|string|null $attachment Attachments.
|
||||
* @param bool $embeded Embed image flag.
|
||||
* @param array|null $embeds Embedded image definitions.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function setHeader($target, $value)
|
||||
{
|
||||
// set the header
|
||||
self::$header[$target] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email
|
||||
*
|
||||
* @return bool on success
|
||||
*
|
||||
*/
|
||||
public static function send($recipient, $subject, $body, $textonly, $mode = 0, $bounce_email = null, $idsession = null, $mailreply = null, $replyname = null , $mailfrom = null, $fromname = null, $cc = null, $bcc = null, $attachment = null, $embeded = null , $embeds = null)
|
||||
{
|
||||
// Get a Mail instance
|
||||
public static function send(
|
||||
$recipient,
|
||||
string $subject,
|
||||
string $body,
|
||||
?string $textonly,
|
||||
int $mode = 0,
|
||||
?string $bounce_email = null,
|
||||
?string $idsession = null,
|
||||
$mailreply = null,
|
||||
$replyname = null,
|
||||
?string $mailfrom = null,
|
||||
?string $fromname = null,
|
||||
?array $cc = null,
|
||||
?array $bcc = null,
|
||||
$attachment = null,
|
||||
bool $embeded = false,
|
||||
?array $embeds = null
|
||||
): bool {
|
||||
$mail = self::getMailer();
|
||||
|
||||
// set component params
|
||||
$conf = self::getConfig();
|
||||
|
||||
// set if we have override
|
||||
if ($mailfrom && $fromname)
|
||||
{
|
||||
$mail->setSender(array($mailfrom, $fromname));
|
||||
$mail->setSender([$mailfrom, $fromname]);
|
||||
}
|
||||
|
||||
// load the bounce email as sender if set
|
||||
if (!is_null($bounce_email))
|
||||
if ($bounce_email)
|
||||
{
|
||||
$mail->Sender = $bounce_email;
|
||||
}
|
||||
|
||||
// Add tag to email to identify it
|
||||
if (!is_null($idsession))
|
||||
if ($idsession)
|
||||
{
|
||||
$mail->addCustomHeader('X-VDMmethodID:'.$idsession);
|
||||
$mail->addCustomHeader('X-VDMmethodID:' . $idsession);
|
||||
}
|
||||
|
||||
// set headers if found
|
||||
if (isset(self::$header) && is_array(self::$header) && count((array)self::$header) > 0)
|
||||
foreach (self::$header as $key => $val)
|
||||
{
|
||||
foreach (self::$header as $_target => $_value)
|
||||
{
|
||||
$mail->addCustomHeader($_target.':'.$_value);
|
||||
}
|
||||
$mail->addCustomHeader($key . ':' . $val);
|
||||
}
|
||||
|
||||
// set the subject & Body
|
||||
$mail->setSubject($subject);
|
||||
$mail->setBody($body);
|
||||
|
||||
// Are we sending the email as HTML?
|
||||
if ($mode)
|
||||
{
|
||||
$mail->IsHTML(true);
|
||||
$mail->isHTML(true);
|
||||
$mail->AltBody = $textonly;
|
||||
}
|
||||
|
||||
//embed images
|
||||
if ($embeded)
|
||||
if ($embeded && !empty($embeds))
|
||||
{
|
||||
if(Super___0a59c65c_9daf_4bc9_baf4_e063ff9e6a8a___Power::check($embeds))
|
||||
foreach ($embeds as $embed)
|
||||
{
|
||||
foreach($embeds as $embed)
|
||||
{
|
||||
$mail->AddEmbeddedImage($embed->Path,$embed->FileName);
|
||||
}
|
||||
$mail->addEmbeddedImage($embed->Path, $embed->FileName);
|
||||
}
|
||||
}
|
||||
|
||||
$mail->addRecipient($recipient);
|
||||
$mail->addCC($cc);
|
||||
$mail->addBCC($bcc);
|
||||
$mail->addAttachment($attachment);
|
||||
if (!empty($cc)) $mail->addCC($cc);
|
||||
if (!empty($bcc)) $mail->addBCC($bcc);
|
||||
if (!empty($attachment)) $mail->addAttachment($attachment);
|
||||
|
||||
// Take care of reply email addresses
|
||||
if (is_array($mailreply))
|
||||
if (!empty($mailreply))
|
||||
{
|
||||
$mail->ClearReplyTos();
|
||||
$numReplyTo = count((array)$mailreply);
|
||||
for ($i=0; $i < $numReplyTo; $i++)
|
||||
if (is_array($mailreply))
|
||||
{
|
||||
$mail->addReplyTo($mailreply[$i], $replyname[$i]);
|
||||
foreach ($mailreply as $i => $reply)
|
||||
{
|
||||
$mail->addReplyTo($reply, $replyname[$i] ?? '');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$mail->addReplyTo($mailreply, (string) $replyname);
|
||||
}
|
||||
}
|
||||
elseif (!empty($mailreply))
|
||||
{
|
||||
$mail->ClearReplyTos();
|
||||
$mail->addReplyTo($mailreply, $replyname);
|
||||
}
|
||||
|
||||
// check if we can add the DKIM to email
|
||||
if ($conf->get('enable_dkim'))
|
||||
{
|
||||
if (!empty($conf->get('dkim_domain')) && !empty($conf->get('dkim_selector')) && !empty($conf->get('dkim_private')) && !empty($conf->get('dkim_public')))
|
||||
{
|
||||
$mail->DKIM_domain = $conf->get('dkim_domain');
|
||||
$mail->DKIM_selector = $conf->get('dkim_selector');
|
||||
$mail->DKIM_identity = $conf->get('dkim_identity');
|
||||
$mail->DKIM_passphrase = $conf->get('dkim_passphrase');
|
||||
$sent = false;
|
||||
$tmp = null;
|
||||
|
||||
try {
|
||||
if (
|
||||
$conf->get('enable_dkim') &&
|
||||
($domain = $conf->get('dkim_domain')) &&
|
||||
($selector = $conf->get('dkim_selector')) &&
|
||||
($privateKey = $conf->get('dkim_private'))
|
||||
) {
|
||||
$mail->DKIM_domain = $domain;
|
||||
$mail->DKIM_selector = $selector;
|
||||
$mail->DKIM_identity = $conf->get('dkim_identity') ?: $domain;
|
||||
$mail->DKIM_passphrase = $conf->get('dkim_passphrase');
|
||||
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'VDM');
|
||||
$h = fopen($tmp, 'w');
|
||||
fwrite($h, $conf->get('dkim_private'));
|
||||
fclose($h);
|
||||
$mail->DKIM_private = $tmp;
|
||||
if ($tmp === false || file_put_contents($tmp, $privateKey) === false)
|
||||
{
|
||||
throw new \RuntimeException('Failed to create temporary DKIM private key file.');
|
||||
}
|
||||
|
||||
$mail->DKIM_private = $tmp;
|
||||
}
|
||||
|
||||
$sent = $mail->Send();
|
||||
} finally {
|
||||
if ($tmp && file_exists($tmp))
|
||||
{
|
||||
@unlink($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
$sendmail = $mail->Send();
|
||||
$sent = $mail->Send();
|
||||
|
||||
if ($conf->get('enable_dkim') && !empty($conf->get('dkim_domain')) && !empty($conf->get('dkim_selector')) && !empty($conf->get('dkim_private')) && !empty($conf->get('dkim_public')))
|
||||
if ($tmp)
|
||||
{
|
||||
@unlink($tmp);
|
||||
}
|
||||
|
||||
if (method_exists('###Component###Helper','storeMessage'))
|
||||
if (method_exists('###Component###Helper', 'storeMessage'))
|
||||
{
|
||||
// if we have active recipient details
|
||||
if (isset(self::$active[$recipient]))
|
||||
{
|
||||
// store the massage if the method is set
|
||||
###Component###Helper::storeMessage($sendmail, self::$active[$recipient], $subject, $body, $textonly, $mode, 'email');
|
||||
// clear memory
|
||||
unset(self::$active[$recipient]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// store the massage if the method is set
|
||||
###Component###Helper::storeMessage($sendmail, $recipient, $subject, $body, $textonly, $mode, 'email');
|
||||
}
|
||||
$data = self::$active[$recipient] ?? $recipient;
|
||||
###Component###Helper::storeMessage($sent, $data, $subject, $body, $textonly, $mode, 'email');
|
||||
unset(self::$active[$recipient]);
|
||||
}
|
||||
|
||||
return $sendmail;
|
||||
return $sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set html text (in a row) and subject (as title) to a email table.
|
||||
* do not use <p> instead use <br />
|
||||
* in your html that you pass to this method
|
||||
* since it is a table row it does not
|
||||
* work well with paragraphs
|
||||
* Build a complete minimal HTML email body with basic headers.
|
||||
* Use <br /> instead of <p> for layout consistency in emails.
|
||||
*
|
||||
* @return string on success
|
||||
* @param string $html Body HTML content.
|
||||
* @param string $subject Email subject/title used in the <title> tag.
|
||||
*
|
||||
* @return string Full HTML email body.
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function setBasicBody($html, $subject)
|
||||
public static function setBasicBody(string $html, string $subject): string
|
||||
{
|
||||
$body = [];
|
||||
$body[] = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
|
||||
$body[] = "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
|
||||
$body[] = "<head>";
|
||||
$body[] = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
|
||||
$body[] = "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>";
|
||||
$body[] = "<title>" . $subject . "</title>";
|
||||
$body[] = "<style type=\"text/css\">";
|
||||
$body[] = "#outlook a {padding:0;}";
|
||||
$body[] = ".ExternalClass {width:100%;}";
|
||||
$body[] = ".ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} ";
|
||||
$body[] = "p {margin: 0; padding: 0; font-size: 0px; line-height: 0px;} ";
|
||||
$body[] = "table td {border-collapse: collapse;}";
|
||||
$body[] = "table {border-collapse: collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; }";
|
||||
$body[] = "img {display: block; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;}";
|
||||
$body[] = "a img {border: none;}";
|
||||
$body[] = "a {text-decoration: none; color: #000001;}";
|
||||
$body[] = "a.phone {text-decoration: none; color: #000001 !important; pointer-events: auto; cursor: default;}";
|
||||
$body[] = "span {font-size: 13px; line-height: 17px; font-family: monospace; color: #000001;}";
|
||||
$body[] = "</style>";
|
||||
$body[] = "<!--[if gte mso 9]>";
|
||||
$body[] = "<style>";
|
||||
$body[] = "/* Target Outlook 2007 and 2010 */";
|
||||
$body[] = "</style>";
|
||||
$body[] = "<![endif]-->";
|
||||
$body[] = "</head>";
|
||||
$body[] = "<body style=\"width:100%; margin:0; padding:0; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;\">";
|
||||
$body[] = $html;
|
||||
$body[] = "</body>";
|
||||
$body[] = "</html>";
|
||||
|
||||
return implode("\n", $body);
|
||||
return implode("\n", [
|
||||
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||
'<html xmlns="http://www.w3.org/1999/xhtml">',
|
||||
'<head>',
|
||||
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
|
||||
'<meta name="viewport" content="width=device-width, initial-scale=1.0"/>',
|
||||
'<title>' . htmlspecialchars($subject) . '</title>',
|
||||
'<style type="text/css">',
|
||||
'#outlook a {padding:0;} .ExternalClass {width:100%;} .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height:100%;}',
|
||||
// 'p {margin: 0; padding: 0; font-size: 0px; line-height: 0px;}',
|
||||
'table, table td {border-collapse: collapse;}',
|
||||
'img {display:block; outline:none; text-decoration:none; -ms-interpolation-mode:bicubic;}',
|
||||
'a img {border:none;} a {text-decoration:none; color:#000001;} a.phone {pointer-events:auto; cursor:default; color:#000001 !important;}',
|
||||
'span {font-size:13px; line-height:17px; font-family:monospace; color:#000001;}',
|
||||
'</style>',
|
||||
'<!--[if gte mso 9]><style>/* Target Outlook 2007 and 2010 */</style><![endif]-->',
|
||||
'</head>',
|
||||
'<body style="width:100%; margin:0; padding:0; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;">',
|
||||
$html,
|
||||
'</body>',
|
||||
'</html>'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set html text (in a row) and subject (as title) to a email table.
|
||||
* do not use <p> instead use <br />
|
||||
* in your html that you pass to this method
|
||||
* since it is a table row it does not
|
||||
* work well with paragraphs
|
||||
* Build a styled HTML email with outer table formatting for wide layout support.
|
||||
* Suitable for rich content emails that need outer table structure.
|
||||
*
|
||||
* @return string on success
|
||||
* @param string $html Inner body HTML content.
|
||||
* @param string $subject Email subject/title used in the <title> tag.
|
||||
*
|
||||
* @return string Complete HTML email content.
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function setTableBody($html, $subject)
|
||||
public static function setTableBody(string $html, string $subject): string
|
||||
{
|
||||
$body = [];
|
||||
$body[] = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
|
||||
$body[] = "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
|
||||
$body[] = "<head>";
|
||||
$body[] = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
|
||||
$body[] = "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>";
|
||||
$body[] = "<title>" . $subject . "</title>";
|
||||
$body[] = "<style type=\"text/css\">";
|
||||
$body[] = "#outlook a {padding:0;}";
|
||||
$body[] = ".ExternalClass {width:100%;}";
|
||||
$body[] = ".ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} ";
|
||||
$body[] = "p {margin: 0; padding: 0; font-size: 0px; line-height: 0px;} ";
|
||||
$body[] = "table td {border-collapse: collapse;}";
|
||||
$body[] = "table {border-collapse: collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; }";
|
||||
$body[] = "img {display: block; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;}";
|
||||
$body[] = "a img {border: none;}";
|
||||
$body[] = "a {text-decoration: none; color: #000001;}";
|
||||
$body[] = "a.phone {text-decoration: none; color: #000001 !important; pointer-events: auto; cursor: default;}";
|
||||
$body[] = "span {font-size: 13px; line-height: 17px; font-family: monospace; color: #000001;}";
|
||||
$body[] = "</style>";
|
||||
$body[] = "<!--[if gte mso 9]>";
|
||||
$body[] = "<style>";
|
||||
$body[] = "/* Target Outlook 2007 and 2010 */";
|
||||
$body[] = "</style>";
|
||||
$body[] = "<![endif]-->";
|
||||
$body[] = "</head>";
|
||||
$body[] = "<body style=\"width:100%; margin:0; padding:0; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;\">";
|
||||
$body[] = "\n<!-- body wrapper -->";
|
||||
$body[] = "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin:0; padding:0; width:100%; line-height: 100% !important;\">";
|
||||
$body[] = "<tr>";
|
||||
$body[] = "<td valign=\"top\">";
|
||||
$body[] = "<!-- edge wrapper -->";
|
||||
$body[] = "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"center\" width=\"800\" >";
|
||||
$body[] = "<tr>";
|
||||
$body[] = "<td valign=\"top\">";
|
||||
$body[] = "<!-- content wrapper -->";
|
||||
$body[] = "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"center\" width=\"780\">";
|
||||
$body[] = "<tr>";
|
||||
$body[] = "<td valign=\"top\" style=\"vertical-align: top;\">";
|
||||
$body[] = $html;
|
||||
$body[] = "</td>";
|
||||
$body[] = "</tr>";
|
||||
$body[] = "</table>";
|
||||
$body[] = "<!-- / content wrapper -->";
|
||||
$body[] = "</td>";
|
||||
$body[] = "</tr>";
|
||||
$body[] = "</table>";
|
||||
$body[] = "<!-- / edge wrapper -->";
|
||||
$body[] = "</td>";
|
||||
$body[] = "</tr>";
|
||||
$body[] = "</table>";
|
||||
$body[] = "<!-- / page wrapper -->";
|
||||
$body[] = "</body>";
|
||||
$body[] = "</html>";
|
||||
|
||||
return implode("\n", $body);
|
||||
return implode("\n", [
|
||||
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||
'<html xmlns="http://www.w3.org/1999/xhtml">',
|
||||
'<head>',
|
||||
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
|
||||
'<meta name="viewport" content="width=device-width, initial-scale=1.0"/>',
|
||||
'<title>' . htmlspecialchars($subject) . '</title>',
|
||||
'<style type="text/css">',
|
||||
'#outlook a {padding:0;} .ExternalClass {width:100%;} .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height:100%;}',
|
||||
// 'p {margin: 0; padding: 0; font-size: 0px; line-height: 0px;}',
|
||||
'table, table td {border-collapse: collapse;}',
|
||||
'img {display:block; outline:none; text-decoration:none; -ms-interpolation-mode:bicubic;}',
|
||||
'a img {border:none;} a {text-decoration:none; color:#000001;} a.phone {pointer-events:auto; cursor:default; color:#000001 !important;}',
|
||||
'span {font-size:13px; line-height:17px; font-family:monospace; color:#000001;}',
|
||||
'</style>',
|
||||
'<!--[if gte mso 9]><style>/* Target Outlook 2007 and 2010 */</style><![endif]-->',
|
||||
'</head>',
|
||||
'<body style="width:100%; margin:0; padding:0; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;">',
|
||||
'<table cellpadding="0" cellspacing="0" border="0" width="100%" style="line-height:100% !important;">',
|
||||
'<tr><td valign="top">',
|
||||
'<table cellpadding="0" cellspacing="0" border="0" align="center" width="800">',
|
||||
'<tr><td valign="top">',
|
||||
'<table cellpadding="0" cellspacing="0" border="0" align="center" width="780">',
|
||||
'<tr><td valign="top" style="vertical-align:top;">',
|
||||
$html,
|
||||
'</td></tr></table>',
|
||||
'</td></tr></table>',
|
||||
'</td></tr></table>',
|
||||
'</body>',
|
||||
'</html>'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@@ -138,18 +138,18 @@ class HtmlView extends BaseHtmlView
|
||||
if ($this->refid && $this->ref)
|
||||
{
|
||||
// return to the item that referred to this item
|
||||
$this->referral = '&ref=' . (string)$this->ref . '&refid=' . (int)$this->refid;
|
||||
$this->referral = '&ref=' . (string) $this->ref . '&refid=' . (int) $this->refid;
|
||||
}
|
||||
elseif($this->ref)
|
||||
{
|
||||
// return to the list view that referred to this item
|
||||
$this->referral = '&ref=' . (string)$this->ref;
|
||||
$this->referral = '&ref=' . (string) $this->ref;
|
||||
}
|
||||
// check return value
|
||||
if (!is_null($return))
|
||||
{
|
||||
// add the return value
|
||||
$this->referral .= '&return=' . (string)$return;
|
||||
$this->referral .= '&return=' . (string) $return;
|
||||
}###LINKEDVIEWITEMS###
|
||||
|
||||
// Set the toolbar
|
||||
@@ -178,8 +178,8 @@ class HtmlView extends BaseHtmlView
|
||||
{
|
||||
###ADDTOOLBAR###
|
||||
|
||||
// now initiate the toolbar
|
||||
$this->toolbar ??= Toolbar::getInstance();
|
||||
// add the toolbar if it's not already loaded
|
||||
$this->toolbar ??= Joomla___39403062_84fb_46e0_bac4_0023f766e827___Power::getContainer()->get(Joomla___5d2ae99b_1ea1_44f0_9b59_f1aa7eab9e2e___Power::class)->createToolbar('toolbar');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -51,6 +51,13 @@
|
||||
multiple="false"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
<field
|
||||
type="repositoriesfiltertype"
|
||||
name="type"
|
||||
label="COM_COMPONENTBUILDER_REPOSITORY_TYPE_LABEL"
|
||||
multiple="false"
|
||||
class="js-select-submit-on-change"
|
||||
/>
|
||||
<field
|
||||
type="repositoriesfilterbase"
|
||||
name="base"
|
||||
|
@@ -1302,6 +1302,7 @@ COM_COMPONENTBUILDER_BGET_THE_KEY_FROMB_A_SSA="<b>Get the key from</b> <a %s>%s<
|
||||
COM_COMPONENTBUILDER_BGET_THE_KEY_FROM_SB_FOR_A_SSA="<b>Get the key from %s</b> for <a %s>%s</a>"
|
||||
COM_COMPONENTBUILDER_BIMAGESB_NOT_MOVED_TO_CORRECT_LOCATION="<b>Images</b> not moved to correct location!"
|
||||
COM_COMPONENTBUILDER_BMULTIPLE_FIELD_REPEATABLE_MODEB_IDS_MISMATCH_IN_BFIELDSB_AND_WAS_EMREMOVEDEM_FROM_THE_FIELD="<b>Multiple Field (repeatable mode)</b> id:%s mismatch in <b>field:%s</b>, and was <em>removed</em> from the field."
|
||||
COM_COMPONENTBUILDER_BOTH_BRANCHES_SET="Both Branches Set"
|
||||
COM_COMPONENTBUILDER_BRANCH="Branch"
|
||||
COM_COMPONENTBUILDER_BSBS_IN_BSB_HAS_ID_MISMATCH_SO_THE_BSB_WAS_REMOVED="<b>%s</b>->%s in <b>%s</b> has id mismatch. So the <b>%s</b> was removed!"
|
||||
COM_COMPONENTBUILDER_BSB_COULD_NOT_BE_IMPORTEDS="<b>%s</b> could not be imported%s"
|
||||
@@ -4566,23 +4567,19 @@ COM_COMPONENTBUILDER_EMPTY_TRASH="Empty trash"
|
||||
COM_COMPONENTBUILDER_ENTER_YOUR_REPLACE_TEXT="Enter your replace text"
|
||||
COM_COMPONENTBUILDER_ENTER_YOUR_SEARCH_TEXT="Enter your search text"
|
||||
COM_COMPONENTBUILDER_ERROR="Error"
|
||||
COM_COMPONENTBUILDER_ERROR_BR_S="Error! <br />%s"
|
||||
COM_COMPONENTBUILDER_ERROR_FETCHING_COMPONENT_GUIDS_FROM_THE_DATABASE="Error fetching component GUIDs from the database."
|
||||
COM_COMPONENTBUILDER_ERROR_FETCHING_COMPONENT_IDS_FROM_THE_DATABASE="Error fetching component IDs from the database."
|
||||
COM_COMPONENTBUILDER_ERROR_FETCHING_FIELD_TYPES_PROPERTIES_FROM_THE_DATABASE="Error fetching field types properties from the database."
|
||||
COM_COMPONENTBUILDER_ERROR_INVALID_ARGUMENT_S="Error: Invalid argument - %s"
|
||||
COM_COMPONENTBUILDER_ERROR_OCCURRED_WHILE_INITIALIZING_POWERS="Error occurred while initializing powers."
|
||||
COM_COMPONENTBUILDER_ERROR_OUT_OF_RANGE_S="Error: Out of range - %s"
|
||||
COM_COMPONENTBUILDER_ERROR_THE_PATH_HAS_A_MISMATCH_AND_COULD_THEREFORE_NOT_RETRIEVE_THE_SNIPPET_FROM_GITHUB="Error! The path has a mismatch and could therefore not retrieve the snippet from gitHub!"
|
||||
COM_COMPONENTBUILDER_ERROR_THE_SNIPPET_IS_FAULTY_AND_COULD_NOT_BE_SAVED="Error! The snippet is faulty and could not be saved."
|
||||
COM_COMPONENTBUILDER_ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THE_SNIPPETS="Error! You do not have access to the snippets."
|
||||
COM_COMPONENTBUILDER_ERROR_YOU_DO_NOT_HAVE_PERMISSION_TO_CREATE_THE_SNIPPET="Error! You do not have permission to create the snippet."
|
||||
COM_COMPONENTBUILDER_EVERY_LANGUAGE="Every language"
|
||||
COM_COMPONENTBUILDER_EXACT_LENGTH_ONLY_FOUR_TEXT_FIELD="Exact Length (only 4 text_field)"
|
||||
COM_COMPONENTBUILDER_EXAMPLE="Example"
|
||||
COM_COMPONENTBUILDER_EXIT_TRASH="Exit trash"
|
||||
COM_COMPONENTBUILDER_EXPLORE_LEARN_AND_CREATE_WITH_LLEWELLYN_ON_YOUTUBE_YOUR_GATEWAY_TO_INSPIRATION="Explore, Learn, and Create with Llewellyn on YouTube: Your Gateway to Inspiration!"
|
||||
COM_COMPONENTBUILDER_EXPORTIMPORT_DATA="Export/Import Data"
|
||||
COM_COMPONENTBUILDER_EXPORT_TRANSLATIONS="Export Translations"
|
||||
COM_COMPONENTBUILDER_EXTENDS="Extends"
|
||||
COM_COMPONENTBUILDER_EXTRA_PROPERTIES_LIKE_LISTCLASS_ESCAPE_DISPLAY_VALIDATEBR_SMALLHERE_YOU_CAN_SET_THE_EXTRA_PROPERTIES_FOR_THIS_FIELDSMALL="Extra properties like (listclass, escape, display, validate)<br /><small>Here you can set the extra properties for this field</small>"
|
||||
COM_COMPONENTBUILDER_FADE_IN="Fade In"
|
||||
@@ -7579,6 +7576,7 @@ COM_COMPONENTBUILDER_NO_ACCESS_GRANTED="No Access Granted!"
|
||||
COM_COMPONENTBUILDER_NO_ACTIVE_REPOSITORIES_FOUND="No Active Repositories Found"
|
||||
COM_COMPONENTBUILDER_NO_ACTIVE_REPOSITORIES_FOUND_FOR_THIS_AREA_YOU_CAN_ADD_REPOSITORIES_IN_THE_REPOSITORIES_SECTION_OF_JCB="No active repositories found for this area. You can add repositories in the Repositories section of JCB."
|
||||
COM_COMPONENTBUILDER_NO_ADMIN_VIEWS_FOUND="No Admin Views Found"
|
||||
COM_COMPONENTBUILDER_NO_BRANCHES_SET="No Branches Set"
|
||||
COM_COMPONENTBUILDER_NO_CHANGE_S_ITEM_S_IN_REPO_S_IS_ALREADY_IN_SYNC="NO CHANGE: %s item [%s] in repo (%s) is already in sync."
|
||||
COM_COMPONENTBUILDER_NO_COMPONENTS_FOUND="No Components Found"
|
||||
COM_COMPONENTBUILDER_NO_COMPONENT_DETAILS_FOUND_SO_IT_IS_NOT_SAFE_TO_CONTINUE="No component details found, so it is not safe to continue!"
|
||||
@@ -7591,8 +7589,10 @@ COM_COMPONENTBUILDER_NO_ITEMS_SELECTED="No items selected."
|
||||
COM_COMPONENTBUILDER_NO_ITEM_FOUND="No Item Found"
|
||||
COM_COMPONENTBUILDER_NO_LANGUAGES_FOUND="No Languages Found"
|
||||
COM_COMPONENTBUILDER_NO_LANGUAGES_UPDATE_SERVER_FOUND="No Languages Update server found."
|
||||
COM_COMPONENTBUILDER_NO_LANGUAGE_STRINGS_FOUND="No language strings found."
|
||||
COM_COMPONENTBUILDER_NO_NAMESPACE_FOUND="No Namespace Found"
|
||||
COM_COMPONENTBUILDER_NO_PATHS_FOUND="No Paths Found"
|
||||
COM_COMPONENTBUILDER_NO_READ_BRANCH_SET="No Read Branch Set"
|
||||
COM_COMPONENTBUILDER_NO_RESULTS_MATCH="No results match"
|
||||
COM_COMPONENTBUILDER_NO_ROWS_FOUND_FOR_THIS_TARGET_AREA="No rows found for this target area"
|
||||
COM_COMPONENTBUILDER_NO_ROWS_WERE_PROCESSED="No rows were processed."
|
||||
@@ -7604,6 +7604,7 @@ COM_COMPONENTBUILDER_NO_TYPE="No Type"
|
||||
COM_COMPONENTBUILDER_NO_UPLOAD_SELECTED="No upload selected"
|
||||
COM_COMPONENTBUILDER_NO_VALIDATION_RULES_FOUND="No validation rules found."
|
||||
COM_COMPONENTBUILDER_NO_VALID_MODE_HAS_BEEN_SPECIFIED="No valid mode has been specified!"
|
||||
COM_COMPONENTBUILDER_NO_WRITE_BRANCH_SET="No Write Branch Set"
|
||||
COM_COMPONENTBUILDER_OFFICIAL_VDM_PACKAGES="Official VDM Packages"
|
||||
COM_COMPONENTBUILDER_ONLY_IN_ADMIN_LIST_VIEW="Only in Admin List View"
|
||||
COM_COMPONENTBUILDER_ONLY_IN_LINKED_LIST_VIEWS="Only in Linked List Views"
|
||||
@@ -7923,6 +7924,8 @@ COM_COMPONENTBUILDER_PUSH_FAILED="Push Failed!"
|
||||
COM_COMPONENTBUILDER_PUSH_UNSUCCESSFUL="Push Unsuccessful!"
|
||||
COM_COMPONENTBUILDER_PUSH_WAS_UNSUCCESSFUL="Push Was Unsuccessful!"
|
||||
COM_COMPONENTBUILDER_READY_TO_COMPILE_A_COMPONENT="Ready to compile a component"
|
||||
COM_COMPONENTBUILDER_READ_BRANCH="Read Branch"
|
||||
COM_COMPONENTBUILDER_READ_BRANCH_SET="Read Branch Set"
|
||||
COM_COMPONENTBUILDER_REFRESH="Refresh"
|
||||
COM_COMPONENTBUILDER_REFRESH_FEED="Refresh Feed"
|
||||
COM_COMPONENTBUILDER_REGEX_SEARCH="Regex Search"
|
||||
@@ -8124,6 +8127,7 @@ COM_COMPONENTBUILDER_SELECT_A_PROPERTY="Select a property"
|
||||
COM_COMPONENTBUILDER_SELECT_A_REPOSITORY_TO_FETCH_ITEMS_FOR_INITIALIZATION="Select a repository to fetch items for initialization"
|
||||
COM_COMPONENTBUILDER_SELECT_A_SITE_VIEW="Select a site view"
|
||||
COM_COMPONENTBUILDER_SELECT_A_SNIPPET="select a snippet"
|
||||
COM_COMPONENTBUILDER_SELECT_BRANCH_STATE="Select Branch State"
|
||||
COM_COMPONENTBUILDER_SELECT_BUILD_DATE="Select Build Date"
|
||||
COM_COMPONENTBUILDER_SELECT_COMPONENT="Select Component"
|
||||
COM_COMPONENTBUILDER_SELECT_EXTENSION="Select Extension"
|
||||
@@ -8942,8 +8946,6 @@ COM_COMPONENTBUILDER_SUBMENU_SNIPPETS="Snippets"
|
||||
COM_COMPONENTBUILDER_SUBMENU_TEMPLATES="Templates"
|
||||
COM_COMPONENTBUILDER_SUBMENU_VALIDATION_RULES="Validation Rules"
|
||||
COM_COMPONENTBUILDER_SUCCESS="Success"
|
||||
COM_COMPONENTBUILDER_SUCCESS_THE_SNIPPET_WAS_SAVED="Success! The snippet was saved."
|
||||
COM_COMPONENTBUILDER_SUCCESS_THE_SNIPPET_WAS_SAVED_BUT_THE_MODIFIED_DATE_COULD_NOT_BE_ADJUSTED_BR_BR_BTHIS_MEANS_THE_SNIPPETS_WILL_CONTINUE_TO_APPEAR_OUT_OF_DATEB="Success! The snippet was saved. But the modified date could not be adjusted. <br /><br /><b>This means the snippets will continue to appear out of date.</b>"
|
||||
COM_COMPONENTBUILDER_SUPER_POWER="Super Power"
|
||||
COM_COMPONENTBUILDER_SUPPORT_JCB_TODAY="Support JCB Today"
|
||||
COM_COMPONENTBUILDER_SUPPORT_JOOMLA_COMPONENT_BUILDER_JCB_WITH_A_BFINANCIAL_DONATIONB_TO_SHOW_GRATITUDE_FOR_THE_TIME_AND_EFFORT_SAVED_IN_YOUR_DEVELOPMENT_PROCESS_YOUR_CONTRIBUTION_NO_MATTER_THE_SIZE_WILL_BE_APPRECIATED_BY_THE_PROJECTS_TEAM_AND_THE_WIDER_COMMUNITY_HELP_ENSURE_THE_GROWTH_AND_RELEVANCE_OF_THIS_ESSENTIAL_TOOL="Support Joomla Component Builder (JCB) with a <b>financial donation</b> to show gratitude for the time and effort saved in your development process. Your contribution, no matter the size, will be appreciated by the project's team and the wider community. Help ensure the growth and relevance of this essential tool."
|
||||
@@ -9621,6 +9623,8 @@ COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_DO_A_REVERSE_SEARCH="Would you like to do
|
||||
COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_OVERRIDE_THE_BUILD_DATE="Would you like to override the build date."
|
||||
COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_REPEAT_THE_SAME_SEARCH="Would you like to repeat the same search?"
|
||||
COM_COMPONENTBUILDER_WOULD_YOU_LIKE_TO_SEE_THE_ADVANCED_COMPILER_OPTIONS="Would you like to see the advanced compiler options?"
|
||||
COM_COMPONENTBUILDER_WRITE_BRANCH="Write Branch"
|
||||
COM_COMPONENTBUILDER_WRITE_BRANCH_SET="Write Branch Set"
|
||||
COM_COMPONENTBUILDER_YES="Yes"
|
||||
COM_COMPONENTBUILDER_YES_UPDATE_ALL="Yes! Update ALL"
|
||||
COM_COMPONENTBUILDER_YOUR_ARE_ABOUT_TO_UPDATE_BALLB_VALUES_THAT_CAN_BE_FOUND_IN_THE_DATABASE="Your are about to update <b>ALL</b> values that can be found in the database."
|
||||
|
134
admin/layouts/exportlanguagetranslations.php
Normal file
134
admin/layouts/exportlanguagetranslations.php
Normal file
@@ -0,0 +1,134 @@
|
||||
<?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
|
||||
*/
|
||||
|
||||
|
||||
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Language\Text;
|
||||
use Joomla\CMS\HTML\HTMLHelper as Html;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use VDM\Component\Componentbuilder\Administrator\Helper\ComponentbuilderHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use Joomla\CMS\Session\Session;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
|
||||
// No direct access to this file
|
||||
defined('JPATH_BASE') or die;
|
||||
|
||||
// always load these files.
|
||||
Html::_('stylesheet', "media/com_componentbuilder/datatable/css/datatables.min.css", ['version' => 'auto']);
|
||||
Html::_('script', "media/com_componentbuilder/datatable/js/pdfmake.min.js", ['version' => 'auto']);
|
||||
Html::_('script', "media/com_componentbuilder/datatable/js/vfs_fonts.js", ['version' => 'auto']);
|
||||
Html::_('script', "media/com_componentbuilder/datatable/js/datatables.min.js", ['version' => 'auto']);
|
||||
|
||||
// set the table details
|
||||
$table_id = StringHelper::random(7);
|
||||
$headers = ComponentbuilderHelper::getLanguageTranslationsHeaders() ?? [];
|
||||
$fields = array_keys($headers);
|
||||
$items = 1;
|
||||
// set the file name
|
||||
$file_name = 'Language_Translations';
|
||||
|
||||
?>
|
||||
<div style="display: none;">
|
||||
<?php echo LayoutHelper::render('table',
|
||||
[
|
||||
'id' => $table_id,
|
||||
'name' => $name,
|
||||
'headers' => $headers,
|
||||
'items' => $items,
|
||||
'init' => false
|
||||
]
|
||||
); ?>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// Create the toolbar export button using DOM methods
|
||||
function createExportButton() {
|
||||
const wrapper = document.createElement('joomla-toolbar-button');
|
||||
wrapper.innerHTML = `
|
||||
<button id="toolbar-export-language-translations" class="button-export btn btn-primary" type="button">
|
||||
<span aria-hidden="true" class="icon-download"></span>
|
||||
<?php echo Text::_('COM_COMPONENTBUILDER_EXPORT_TRANSLATIONS'); ?>
|
||||
</button>
|
||||
`;
|
||||
return wrapper;
|
||||
}
|
||||
// Insert the export button next to the Edit button
|
||||
function insertExportButton() {
|
||||
const editButton = document.getElementById('toolbar-edit');
|
||||
if (!editButton || !editButton.parentNode) {
|
||||
console.warn('Edit button not found. Export button not inserted.');
|
||||
return;
|
||||
}
|
||||
const exportButton = createExportButton();
|
||||
editButton.parentNode.insertBefore(exportButton, editButton.nextSibling);
|
||||
// Attach click event
|
||||
const exportBtn = document.getElementById('toolbar-export-language-translations');
|
||||
if (exportBtn) {
|
||||
exportBtn.addEventListener('click', exportLanguageTranslations);
|
||||
} else {
|
||||
console.warn('Export button element not found for event binding.');
|
||||
}
|
||||
}
|
||||
// Run insertion
|
||||
insertExportButton();
|
||||
});
|
||||
function exportLanguageTranslations() {
|
||||
document.getElementById("loading").style.display = 'block';
|
||||
const filterExtension = (() => {
|
||||
const val = document.getElementById('filter_extension')?.value;
|
||||
return val !== undefined && val !== '' ? val : 0;
|
||||
})();
|
||||
const filterTranslated = (() => {
|
||||
const val = document.getElementById('filter_translated')?.value;
|
||||
return val !== undefined && val !== '' ? val : 0;
|
||||
})();
|
||||
const filterNotTranslated = (() => {
|
||||
const val = document.getElementById('filter_not_translated')?.value;
|
||||
return val !== undefined && val !== '' ? val : 0;
|
||||
})();
|
||||
const token = '<?php echo Session::getFormToken(); ?>=1';
|
||||
const ajaxUrl = `<?php echo Uri::base(); ?>index.php?option=com_componentbuilder&task=ajax.exportLanguageTranslations&format=json&raw=true&${token}&filter_extension=${encodeURIComponent(filterExtension)}&filter_translated=${encodeURIComponent(filterTranslated)}&filter_not_translated=${encodeURIComponent(filterNotTranslated)}`;
|
||||
const tableElement = document.getElementById('<?php echo $table_id; ?>');
|
||||
if ($.fn.DataTable.isDataTable(tableElement)) {
|
||||
const table = $(tableElement).DataTable();
|
||||
table.ajax.url(ajaxUrl).load();
|
||||
table.off('draw.dt');
|
||||
table.on('draw.dt', function () {
|
||||
table.button(`.buttons-excel`).trigger();
|
||||
document.getElementById("loading").style.display = 'none';
|
||||
});
|
||||
} else {
|
||||
const table = $(tableElement).DataTable({
|
||||
dom: 'Bfrtip',
|
||||
buttons: [
|
||||
{
|
||||
extend: 'excel',
|
||||
text: 'Excel',
|
||||
title: '<?php echo Text::_('COM_COMPONENTBUILDER_LANGUAGE_TRANSLATIONS'); ?>',
|
||||
filename: '<?php echo $file_name; ?>'
|
||||
}
|
||||
],
|
||||
select: false,
|
||||
ajax: { url: ajaxUrl },
|
||||
deferRender: true,
|
||||
columns: [<?php foreach ($fields as $field): ?>
|
||||
{ data: '<?php echo $field; ?>' },
|
||||
<?php endforeach; ?>]
|
||||
});
|
||||
table.on('draw.dt', function () {
|
||||
table.button(`.buttons-excel`).trigger();
|
||||
document.getElementById("loading").style.display = 'none';
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -28,7 +28,7 @@ extract($displayData);
|
||||
* Layout variables
|
||||
* -----------------
|
||||
* @var Form $tmpl The Empty form for template
|
||||
* @var array $forms Array of JForm instances for render the rows
|
||||
* @var array $forms Array of Form instances for render the rows
|
||||
* @var bool $multiple The multiple state for the form field
|
||||
* @var int $min Count of minimum repeating in multiple mode
|
||||
* @var int $max Count of maximum repeating in multiple mode
|
||||
|
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
|
@@ -1 +0,0 @@
|
||||
|
@@ -76,14 +76,12 @@ class AjaxController extends BaseController
|
||||
$this->registerTask('getEditCustomCodeButtons', 'ajax');
|
||||
$this->registerTask('placedin', 'ajax');
|
||||
$this->registerTask('checkPlaceholderName', 'ajax');
|
||||
$this->registerTask('snippetDetails', 'ajax');
|
||||
$this->registerTask('setSnippetGithub', 'ajax');
|
||||
$this->registerTask('getSnippets', 'ajax');
|
||||
$this->registerTask('getExistingValidationRuleCode', 'ajax');
|
||||
$this->registerTask('getValidationRulesTable', 'ajax');
|
||||
$this->registerTask('checkRuleName', 'ajax');
|
||||
$this->registerTask('fieldTypeProperties', 'ajax');
|
||||
$this->registerTask('getFieldPropertyDesc', 'ajax');
|
||||
$this->registerTask('exportLanguageTranslations', 'ajax');
|
||||
$this->registerTask('getCodeGlueOptions', 'ajax');
|
||||
$this->registerTask('doSearch', 'ajax');
|
||||
$this->registerTask('replaceAll', 'ajax');
|
||||
@@ -1459,154 +1457,6 @@ class AjaxController extends BaseController
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'snippetDetails':
|
||||
try
|
||||
{
|
||||
$idValue = $jinput->get('id', NULL, 'STRING');
|
||||
if($idValue && $user->id != 0)
|
||||
{
|
||||
$ajaxModule = $this->getModel('ajax', 'Administrator');
|
||||
if ($ajaxModule)
|
||||
{
|
||||
$result = $ajaxModule->getSnippetDetails($idValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = ['error' => 'There was an error! [149]'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = ['error' => 'There was an error! [149]'];
|
||||
}
|
||||
if($callback)
|
||||
{
|
||||
echo $callback . "(".json_encode($result).");";
|
||||
}
|
||||
elseif($returnRaw)
|
||||
{
|
||||
echo json_encode($result);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "(".json_encode($result).");";
|
||||
}
|
||||
}
|
||||
catch(\Exception $e)
|
||||
{
|
||||
if($callback)
|
||||
{
|
||||
echo $callback."(".json_encode($e).");";
|
||||
}
|
||||
elseif($returnRaw)
|
||||
{
|
||||
echo json_encode($e);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "(".json_encode($e).");";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'setSnippetGithub':
|
||||
try
|
||||
{
|
||||
$pathValue = $jinput->get('path', NULL, 'STRING');
|
||||
$statusValue = $jinput->get('status', NULL, 'WORD');
|
||||
if($pathValue && $user->id != 0 && $statusValue)
|
||||
{
|
||||
$ajaxModule = $this->getModel('ajax', 'Administrator');
|
||||
if ($ajaxModule)
|
||||
{
|
||||
$result = $ajaxModule->setSnippetGithub($pathValue, $statusValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = ['error' => 'There was an error! [149]'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = ['error' => 'There was an error! [149]'];
|
||||
}
|
||||
if($callback)
|
||||
{
|
||||
echo $callback . "(".json_encode($result).");";
|
||||
}
|
||||
elseif($returnRaw)
|
||||
{
|
||||
echo json_encode($result);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "(".json_encode($result).");";
|
||||
}
|
||||
}
|
||||
catch(\Exception $e)
|
||||
{
|
||||
if($callback)
|
||||
{
|
||||
echo $callback."(".json_encode($e).");";
|
||||
}
|
||||
elseif($returnRaw)
|
||||
{
|
||||
echo json_encode($e);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "(".json_encode($e).");";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'getSnippets':
|
||||
try
|
||||
{
|
||||
$librariesValue = $jinput->get('libraries', NULL, 'STRING');
|
||||
if($librariesValue && $user->id != 0)
|
||||
{
|
||||
$ajaxModule = $this->getModel('ajax', 'Administrator');
|
||||
if ($ajaxModule)
|
||||
{
|
||||
$result = $ajaxModule->getSnippets($librariesValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = ['error' => 'There was an error! [149]'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = ['error' => 'There was an error! [149]'];
|
||||
}
|
||||
if($callback)
|
||||
{
|
||||
echo $callback . "(".json_encode($result).");";
|
||||
}
|
||||
elseif($returnRaw)
|
||||
{
|
||||
echo json_encode($result);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "(".json_encode($result).");";
|
||||
}
|
||||
}
|
||||
catch(\Exception $e)
|
||||
{
|
||||
if($callback)
|
||||
{
|
||||
echo $callback."(".json_encode($e).");";
|
||||
}
|
||||
elseif($returnRaw)
|
||||
{
|
||||
echo json_encode($e);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "(".json_encode($e).");";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'getExistingValidationRuleCode':
|
||||
try
|
||||
{
|
||||
@@ -1854,6 +1704,57 @@ class AjaxController extends BaseController
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'exportLanguageTranslations':
|
||||
try
|
||||
{
|
||||
$filter_extensionValue = $jinput->get('filter_extension', NULL, 'STRING');
|
||||
$filter_translatedValue = $jinput->get('filter_translated', NULL, 'STRING');
|
||||
$filter_not_translatedValue = $jinput->get('filter_not_translated', NULL, 'STRING');
|
||||
if($user->id != 0)
|
||||
{
|
||||
$ajaxModule = $this->getModel('ajax', 'Administrator');
|
||||
if ($ajaxModule)
|
||||
{
|
||||
$result = $ajaxModule->exportLanguageTranslations($filter_extensionValue, $filter_translatedValue, $filter_not_translatedValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = ['error' => 'There was an error! [149]'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$result = ['error' => 'There was an error! [149]'];
|
||||
}
|
||||
if($callback)
|
||||
{
|
||||
echo $callback . "(".json_encode($result).");";
|
||||
}
|
||||
elseif($returnRaw)
|
||||
{
|
||||
echo json_encode($result);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "(".json_encode($result).");";
|
||||
}
|
||||
}
|
||||
catch(\Exception $e)
|
||||
{
|
||||
if($callback)
|
||||
{
|
||||
echo $callback."(".json_encode($e).");";
|
||||
}
|
||||
elseif($returnRaw)
|
||||
{
|
||||
echo json_encode($e);
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "(".json_encode($e).");";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'getCodeGlueOptions':
|
||||
try
|
||||
{
|
||||
|
78
admin/src/Field/RepositoriesfiltertypeField.php
Normal file
78
admin/src/Field/RepositoriesfiltertypeField.php
Normal file
@@ -0,0 +1,78 @@
|
||||
<?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;
|
||||
|
||||
/**
|
||||
* Repositoriesfiltertype Form Field class for the Componentbuilder component
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class RepositoriesfiltertypeField extends ListField
|
||||
{
|
||||
/**
|
||||
* The repositoriesfiltertype field type.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $type = 'Repositoriesfiltertype';
|
||||
|
||||
/**
|
||||
* 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 a db connection.
|
||||
$db = Factory::getContainer()->get(\Joomla\Database\DatabaseInterface::class);
|
||||
|
||||
// Create a new query object.
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
// Select the text.
|
||||
$query->select($db->quoteName('type'));
|
||||
$query->from($db->quoteName('#__componentbuilder_repository'));
|
||||
$query->order($db->quoteName('type') . ' ASC');
|
||||
|
||||
// Reset the query using our newly populated query object.
|
||||
$db->setQuery($query);
|
||||
|
||||
$_results = $db->loadColumn();
|
||||
$_filter = [];
|
||||
$_filter[] = Html::_('select.option', '', '- ' . Text::_('COM_COMPONENTBUILDER_FILTER_SELECT_TYPE') . ' -');
|
||||
|
||||
if ($_results)
|
||||
{
|
||||
// get repositoriesmodel
|
||||
$_model = ComponentbuilderHelper::getModel('repositories');
|
||||
$_results = array_unique($_results);
|
||||
foreach ($_results as $type)
|
||||
{
|
||||
// Translate the type selection
|
||||
$_text = $_model->selectionTranslation($type,'type');
|
||||
// Now add the type and its text to the options array
|
||||
$_filter[] = Html::_('select.option', $type, Text::_($_text));
|
||||
}
|
||||
}
|
||||
return $_filter;
|
||||
}
|
||||
}
|
@@ -14,78 +14,107 @@ use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\CMS\Mail\Mail;
|
||||
use Joomla\Registry\Registry;
|
||||
use VDM\Joomla\Utilities\ArrayHelper;
|
||||
use Joomla\CMS\Mail\MailerInterface;
|
||||
use Joomla\CMS\Mail\MailerFactoryInterface;
|
||||
|
||||
// No direct access to this file
|
||||
\defined('_JEXEC') or die;
|
||||
|
||||
/**
|
||||
* Componentbuilder component email helper
|
||||
*
|
||||
* @since 3.0
|
||||
* Provides a complete and configurable mailer integration for Joomla components.
|
||||
* Allows for custom headers, DKIM signing, embedded images, and HTML styling.
|
||||
*
|
||||
* @since 3.0
|
||||
*/
|
||||
abstract class ComponentbuilderEmail
|
||||
{
|
||||
/**
|
||||
* The active recipient
|
||||
* The active recipient.
|
||||
*
|
||||
* @var activeRecipient (array)
|
||||
* @var array<string, mixed>
|
||||
* @since 3.0
|
||||
*/
|
||||
public static $active = [];
|
||||
public static array $active = [];
|
||||
|
||||
/**
|
||||
* Configuration object
|
||||
* Mail instances container.
|
||||
*
|
||||
* @var Registry
|
||||
* @var MailerInterface[]
|
||||
* @since 1.7.3
|
||||
*/
|
||||
public static ?Registry $config = null;
|
||||
protected static array $instances = [];
|
||||
|
||||
/**
|
||||
* Mailer object
|
||||
* Global Configuration object.
|
||||
*
|
||||
* @var Mail
|
||||
* @var Registry|null
|
||||
* @since 5.1.1
|
||||
*/
|
||||
public static ?Mail $mailer = null;
|
||||
protected static ?Registry $gConfig = null;
|
||||
|
||||
/**
|
||||
* Custom Headers
|
||||
* Component Configuration object.
|
||||
*
|
||||
* @var array
|
||||
* @var Registry|null
|
||||
* @since 3.0
|
||||
*/
|
||||
protected static ?Registry $config = null;
|
||||
|
||||
/**
|
||||
* Mailer object.
|
||||
*
|
||||
* @var MailerInterface|null
|
||||
* @since 3.0
|
||||
*/
|
||||
protected static ?MailerInterface $mailer = null;
|
||||
|
||||
/**
|
||||
* Custom email headers.
|
||||
*
|
||||
* @var array<string, string>
|
||||
* @since 3.0
|
||||
*/
|
||||
protected static array $header = [];
|
||||
|
||||
/**
|
||||
* Get a configuration object
|
||||
* Retrieve the component configuration.
|
||||
*
|
||||
* @return Registry Component configuration object
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function getConfig()
|
||||
protected static function getConfig(): Registry
|
||||
{
|
||||
if (!self::$config)
|
||||
{
|
||||
self::$config = ComponentHelper::getParams('com_componentbuilder');
|
||||
}
|
||||
|
||||
return self::$config;
|
||||
return self::$config ??= ComponentHelper::getParams('com_componentbuilder');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the global mailer object, only creating it if it doesn't already exist.
|
||||
* Retrieve the global configuration.
|
||||
*
|
||||
* @return Registry Global configuration object
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function getMailerInstance()
|
||||
protected static function getGlobalConfig(): Registry
|
||||
{
|
||||
if (!self::$mailer)
|
||||
{
|
||||
self::$mailer = self::createMailer();
|
||||
}
|
||||
|
||||
return self::$mailer;
|
||||
return self::$gConfig ??= Factory::getApplication()->getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a string looks like an email address.
|
||||
* @param string $address The email address to check
|
||||
* @param string|callable $patternselect A selector for the validation pattern to use :
|
||||
* Get or create a Mailer instance.
|
||||
*
|
||||
* @return MailerInterface A cloned Mail object instance
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function getMailer(): MailerInterface
|
||||
{
|
||||
return self::$mailer ??= self::createMailer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an email address using a selected pattern or callable.
|
||||
*
|
||||
* @param string $address Email address to validate.
|
||||
* @param string|callable|null $patternselect Validation pattern or callable.
|
||||
* * `auto` Pick best pattern automatically;
|
||||
* * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;
|
||||
* * `pcre` Use old PCRE implementation;
|
||||
@@ -97,374 +126,357 @@ abstract class ComponentbuilderEmail
|
||||
* return (strpos($address, '@') !== false);
|
||||
* });
|
||||
* You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.
|
||||
* @return boolean
|
||||
* @static
|
||||
* @access public
|
||||
*
|
||||
* @return bool True if valid, false otherwise
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function validateAddress($address, $patternselect = null): bool
|
||||
public static function validateAddress(string $address, $patternselect = null): bool
|
||||
{
|
||||
return self::getMailerInstance()->validateAddress($address, $patternselect);
|
||||
return self::getMailer()->validateAddress($address, $patternselect);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mailer object.
|
||||
* Set a custom email header.
|
||||
*
|
||||
* Returns the global {@link Mail} object, only creating it if it doesn't already exist.
|
||||
* @param string $key Header name.
|
||||
* @param string $value Header value.
|
||||
*
|
||||
* @return Mail object
|
||||
*
|
||||
* @see Mail
|
||||
* @return void
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function getMailer(): Mail
|
||||
public static function setHeader(string $key, string $value): void
|
||||
{
|
||||
if (!self::$mailer)
|
||||
self::$header[$key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create a Mail instance with specific configuration.
|
||||
*
|
||||
* @param string $id Instance ID.
|
||||
* @param bool $exceptions Enable exceptions.
|
||||
*
|
||||
* @return MailerInterface Configured Mail instance
|
||||
* @since 5.1.1
|
||||
*/
|
||||
public static function getInstance(string $id = 'Joomla', bool $exceptions = true): MailerInterface
|
||||
{
|
||||
if (!isset(self::$instances[$id]))
|
||||
{
|
||||
self::$mailer = self::createMailer();
|
||||
$config = clone self::getGlobalConfig();
|
||||
$config->set('throw_exceptions', $exceptions);
|
||||
self::$instances[$id] = Factory::getContainer()->get(MailerFactoryInterface::class)->createMailer($config);
|
||||
}
|
||||
|
||||
$copy = clone self::$mailer;
|
||||
|
||||
return $copy;
|
||||
return self::$instances[$id];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mailer object
|
||||
* Create a configured Mail instance.
|
||||
*
|
||||
* @return Mail object
|
||||
*
|
||||
* @see Mail
|
||||
* @return MailerInterface The created Mail object with sender, reply-to and transport settings.
|
||||
* @since 3.0
|
||||
*/
|
||||
protected static function createMailer(): Mail
|
||||
protected static function createMailer(): MailerInterface
|
||||
{
|
||||
// set component params
|
||||
$conf = self::getConfig();
|
||||
|
||||
// now load the mailer
|
||||
$conf = self::getConfig();
|
||||
$mailer = $conf->get('mailer', 'global');
|
||||
$mail = self::getInstance();
|
||||
|
||||
// Create a Mail object
|
||||
$mail = Mail::getInstance();
|
||||
|
||||
// check if set to global
|
||||
if ('global' == $mailer)
|
||||
if ($mailer === 'global')
|
||||
{
|
||||
// get the global details
|
||||
$globalConf = Factory::getConfig();
|
||||
|
||||
$mailer = $globalConf->get('mailer');
|
||||
$smtpauth = ($globalConf->get('smtpauth') == 0) ? null : 1;
|
||||
$smtpuser = $globalConf->get('smtpuser');
|
||||
$smtppass = $globalConf->get('smtppass');
|
||||
$smtphost = $globalConf->get('smtphost');
|
||||
$smtpsecure = $globalConf->get('smtpsecure');
|
||||
$smtpport = $globalConf->get('smtpport');
|
||||
$sendmail = $globalConf->get('sendmail');
|
||||
$mailfrom = $globalConf->get('mailfrom');
|
||||
$fromname = $globalConf->get('fromname');
|
||||
$replyto = $globalConf->get('replyto');
|
||||
$replytoname = $globalConf->get('replytoname');
|
||||
$global = self::getGlobalConfig();
|
||||
$mailer = $global->get('mailer');
|
||||
$params = [
|
||||
'smtpauth' => $global->get('smtpauth') ? 1 : null,
|
||||
'smtpuser' => $global->get('smtpuser'),
|
||||
'smtppass' => $global->get('smtppass'),
|
||||
'smtphost' => $global->get('smtphost'),
|
||||
'smtpsecure' => $global->get('smtpsecure'),
|
||||
'smtpport' => $global->get('smtpport'),
|
||||
'sendmail' => $global->get('sendmail'),
|
||||
'from' => $global->get('mailfrom'),
|
||||
'name' => $global->get('fromname'),
|
||||
'replyto' => $global->get('replyto'),
|
||||
'replytoname' => $global->get('replytoname'),
|
||||
];
|
||||
}
|
||||
else
|
||||
{
|
||||
$smtpauth = ($conf->get('smtpauth') == 0) ? null : 1;
|
||||
$smtpuser = $conf->get('smtpuser');
|
||||
$smtppass = $conf->get('smtppass');
|
||||
$smtphost = $conf->get('smtphost');
|
||||
$smtpsecure = $conf->get('smtpsecure');
|
||||
$smtpport = $conf->get('smtpport');
|
||||
$sendmail = $conf->get('sendmail');
|
||||
$mailfrom = $conf->get('emailfrom');
|
||||
$fromname = $conf->get('fromname');
|
||||
$replyto = $conf->get('replyto');
|
||||
$replytoname = $conf->get('replytoname');
|
||||
$params = [
|
||||
'smtpauth' => $conf->get('smtpauth') ? 1 : null,
|
||||
'smtpuser' => $conf->get('smtpuser'),
|
||||
'smtppass' => $conf->get('smtppass'),
|
||||
'smtphost' => $conf->get('smtphost'),
|
||||
'smtpsecure' => $conf->get('smtpsecure'),
|
||||
'smtpport' => $conf->get('smtpport'),
|
||||
'sendmail' => $conf->get('sendmail'),
|
||||
'from' => $conf->get('emailfrom'),
|
||||
'name' => $conf->get('fromname'),
|
||||
'replyto' => $conf->get('replyto'),
|
||||
'replytoname' => $conf->get('replytoname'),
|
||||
];
|
||||
}
|
||||
|
||||
// Set global sender
|
||||
$mail->setSender(array($mailfrom, $fromname));
|
||||
$mail->setSender([$params['from'], $params['name']]);
|
||||
|
||||
// set the global reply-to if found
|
||||
if ($replyto && $replytoname)
|
||||
{
|
||||
if (!empty($params['replyto']) && !empty($params['replytoname']))
|
||||
{
|
||||
$mail->ClearReplyTos();
|
||||
$mail->addReplyTo($replyto, $replytoname);
|
||||
$mail->addReplyTo($params['replyto'], $params['replytoname']);
|
||||
}
|
||||
|
||||
// Default mailer is to use PHP's mail function
|
||||
switch ($mailer)
|
||||
{
|
||||
case 'smtp':
|
||||
// set the SMTP option
|
||||
$mail->useSMTP($smtpauth, $smtphost, $smtpuser, $smtppass, $smtpsecure, $smtpport);
|
||||
$mail->useSMTP(
|
||||
$params['smtpauth'],
|
||||
$params['smtphost'],
|
||||
$params['smtpuser'],
|
||||
$params['smtppass'],
|
||||
$params['smtpsecure'],
|
||||
$params['smtpport']
|
||||
);
|
||||
break;
|
||||
|
||||
case 'sendmail':
|
||||
// set the sendmail option
|
||||
$mail->useSendmail($sendmail);
|
||||
$mail->useSendmail($params['sendmail']);
|
||||
$mail->IsSendmail();
|
||||
break;
|
||||
|
||||
default:
|
||||
$mail->IsMail();
|
||||
break;
|
||||
}
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a Mail custom header.
|
||||
* Compose and send an email with full options including attachments, HTML, DKIM, and reply-to support.
|
||||
*
|
||||
* @return void
|
||||
* @param string|array $recipient Email or list of recipients.
|
||||
* @param string $subject Subject line.
|
||||
* @param string $body HTML body.
|
||||
* @param string|null $textonly Optional plain text fallback.
|
||||
* @param int $mode 1 = HTML, 0 = plain text.
|
||||
* @param string|null $bounce_email Optional bounce email address.
|
||||
* @param string|null $idsession Optional message tracking tag.
|
||||
* @param string|array|null $mailreply Optional reply-to address(es).
|
||||
* @param string|array|null $replyname Optional reply-to name(s).
|
||||
* @param string|null $mailfrom Optional sender email override.
|
||||
* @param string|null $fromname Optional sender name override.
|
||||
* @param array|null $cc CC recipients.
|
||||
* @param array|null $bcc BCC recipients.
|
||||
* @param array|string|null $attachment Attachments.
|
||||
* @param bool $embeded Embed image flag.
|
||||
* @param array|null $embeds Embedded image definitions.
|
||||
*
|
||||
* @return bool True on success, false on failure.
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function setHeader($target, $value)
|
||||
{
|
||||
// set the header
|
||||
self::$header[$target] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an email
|
||||
*
|
||||
* @return bool on success
|
||||
*
|
||||
*/
|
||||
public static function send($recipient, $subject, $body, $textonly, $mode = 0, $bounce_email = null, $idsession = null, $mailreply = null, $replyname = null , $mailfrom = null, $fromname = null, $cc = null, $bcc = null, $attachment = null, $embeded = null , $embeds = null)
|
||||
{
|
||||
// Get a Mail instance
|
||||
public static function send(
|
||||
$recipient,
|
||||
string $subject,
|
||||
string $body,
|
||||
?string $textonly,
|
||||
int $mode = 0,
|
||||
?string $bounce_email = null,
|
||||
?string $idsession = null,
|
||||
$mailreply = null,
|
||||
$replyname = null,
|
||||
?string $mailfrom = null,
|
||||
?string $fromname = null,
|
||||
?array $cc = null,
|
||||
?array $bcc = null,
|
||||
$attachment = null,
|
||||
bool $embeded = false,
|
||||
?array $embeds = null
|
||||
): bool {
|
||||
$mail = self::getMailer();
|
||||
|
||||
// set component params
|
||||
$conf = self::getConfig();
|
||||
|
||||
// set if we have override
|
||||
if ($mailfrom && $fromname)
|
||||
{
|
||||
$mail->setSender(array($mailfrom, $fromname));
|
||||
$mail->setSender([$mailfrom, $fromname]);
|
||||
}
|
||||
|
||||
// load the bounce email as sender if set
|
||||
if (!is_null($bounce_email))
|
||||
if ($bounce_email)
|
||||
{
|
||||
$mail->Sender = $bounce_email;
|
||||
}
|
||||
|
||||
// Add tag to email to identify it
|
||||
if (!is_null($idsession))
|
||||
if ($idsession)
|
||||
{
|
||||
$mail->addCustomHeader('X-VDMmethodID:'.$idsession);
|
||||
$mail->addCustomHeader('X-VDMmethodID:' . $idsession);
|
||||
}
|
||||
|
||||
// set headers if found
|
||||
if (isset(self::$header) && is_array(self::$header) && count((array)self::$header) > 0)
|
||||
foreach (self::$header as $key => $val)
|
||||
{
|
||||
foreach (self::$header as $_target => $_value)
|
||||
{
|
||||
$mail->addCustomHeader($_target.':'.$_value);
|
||||
}
|
||||
$mail->addCustomHeader($key . ':' . $val);
|
||||
}
|
||||
|
||||
// set the subject & Body
|
||||
$mail->setSubject($subject);
|
||||
$mail->setBody($body);
|
||||
|
||||
// Are we sending the email as HTML?
|
||||
if ($mode)
|
||||
{
|
||||
$mail->IsHTML(true);
|
||||
$mail->isHTML(true);
|
||||
$mail->AltBody = $textonly;
|
||||
}
|
||||
|
||||
//embed images
|
||||
if ($embeded)
|
||||
if ($embeded && !empty($embeds))
|
||||
{
|
||||
if(ArrayHelper::check($embeds))
|
||||
foreach ($embeds as $embed)
|
||||
{
|
||||
foreach($embeds as $embed)
|
||||
{
|
||||
$mail->AddEmbeddedImage($embed->Path,$embed->FileName);
|
||||
}
|
||||
$mail->addEmbeddedImage($embed->Path, $embed->FileName);
|
||||
}
|
||||
}
|
||||
|
||||
$mail->addRecipient($recipient);
|
||||
$mail->addCC($cc);
|
||||
$mail->addBCC($bcc);
|
||||
$mail->addAttachment($attachment);
|
||||
if (!empty($cc)) $mail->addCC($cc);
|
||||
if (!empty($bcc)) $mail->addBCC($bcc);
|
||||
if (!empty($attachment)) $mail->addAttachment($attachment);
|
||||
|
||||
// Take care of reply email addresses
|
||||
if (is_array($mailreply))
|
||||
if (!empty($mailreply))
|
||||
{
|
||||
$mail->ClearReplyTos();
|
||||
$numReplyTo = count((array)$mailreply);
|
||||
for ($i=0; $i < $numReplyTo; $i++)
|
||||
if (is_array($mailreply))
|
||||
{
|
||||
$mail->addReplyTo($mailreply[$i], $replyname[$i]);
|
||||
foreach ($mailreply as $i => $reply)
|
||||
{
|
||||
$mail->addReplyTo($reply, $replyname[$i] ?? '');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$mail->addReplyTo($mailreply, (string) $replyname);
|
||||
}
|
||||
}
|
||||
elseif (!empty($mailreply))
|
||||
{
|
||||
$mail->ClearReplyTos();
|
||||
$mail->addReplyTo($mailreply, $replyname);
|
||||
}
|
||||
|
||||
// check if we can add the DKIM to email
|
||||
if ($conf->get('enable_dkim'))
|
||||
{
|
||||
if (!empty($conf->get('dkim_domain')) && !empty($conf->get('dkim_selector')) && !empty($conf->get('dkim_private')) && !empty($conf->get('dkim_public')))
|
||||
{
|
||||
$mail->DKIM_domain = $conf->get('dkim_domain');
|
||||
$mail->DKIM_selector = $conf->get('dkim_selector');
|
||||
$mail->DKIM_identity = $conf->get('dkim_identity');
|
||||
$mail->DKIM_passphrase = $conf->get('dkim_passphrase');
|
||||
$sent = false;
|
||||
$tmp = null;
|
||||
|
||||
try {
|
||||
if (
|
||||
$conf->get('enable_dkim') &&
|
||||
($domain = $conf->get('dkim_domain')) &&
|
||||
($selector = $conf->get('dkim_selector')) &&
|
||||
($privateKey = $conf->get('dkim_private'))
|
||||
) {
|
||||
$mail->DKIM_domain = $domain;
|
||||
$mail->DKIM_selector = $selector;
|
||||
$mail->DKIM_identity = $conf->get('dkim_identity') ?: $domain;
|
||||
$mail->DKIM_passphrase = $conf->get('dkim_passphrase');
|
||||
|
||||
$tmp = tempnam(sys_get_temp_dir(), 'VDM');
|
||||
$h = fopen($tmp, 'w');
|
||||
fwrite($h, $conf->get('dkim_private'));
|
||||
fclose($h);
|
||||
$mail->DKIM_private = $tmp;
|
||||
if ($tmp === false || file_put_contents($tmp, $privateKey) === false)
|
||||
{
|
||||
throw new \RuntimeException('Failed to create temporary DKIM private key file.');
|
||||
}
|
||||
|
||||
$mail->DKIM_private = $tmp;
|
||||
}
|
||||
|
||||
$sent = $mail->Send();
|
||||
} finally {
|
||||
if ($tmp && file_exists($tmp))
|
||||
{
|
||||
@unlink($tmp);
|
||||
}
|
||||
}
|
||||
|
||||
$sendmail = $mail->Send();
|
||||
$sent = $mail->Send();
|
||||
|
||||
if ($conf->get('enable_dkim') && !empty($conf->get('dkim_domain')) && !empty($conf->get('dkim_selector')) && !empty($conf->get('dkim_private')) && !empty($conf->get('dkim_public')))
|
||||
if ($tmp)
|
||||
{
|
||||
@unlink($tmp);
|
||||
}
|
||||
|
||||
if (method_exists('ComponentbuilderHelper','storeMessage'))
|
||||
if (method_exists('ComponentbuilderHelper', 'storeMessage'))
|
||||
{
|
||||
// if we have active recipient details
|
||||
if (isset(self::$active[$recipient]))
|
||||
{
|
||||
// store the massage if the method is set
|
||||
ComponentbuilderHelper::storeMessage($sendmail, self::$active[$recipient], $subject, $body, $textonly, $mode, 'email');
|
||||
// clear memory
|
||||
unset(self::$active[$recipient]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// store the massage if the method is set
|
||||
ComponentbuilderHelper::storeMessage($sendmail, $recipient, $subject, $body, $textonly, $mode, 'email');
|
||||
}
|
||||
$data = self::$active[$recipient] ?? $recipient;
|
||||
ComponentbuilderHelper::storeMessage($sent, $data, $subject, $body, $textonly, $mode, 'email');
|
||||
unset(self::$active[$recipient]);
|
||||
}
|
||||
|
||||
return $sendmail;
|
||||
return $sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set html text (in a row) and subject (as title) to a email table.
|
||||
* do not use <p> instead use <br />
|
||||
* in your html that you pass to this method
|
||||
* since it is a table row it does not
|
||||
* work well with paragraphs
|
||||
* Build a complete minimal HTML email body with basic headers.
|
||||
* Use <br /> instead of <p> for layout consistency in emails.
|
||||
*
|
||||
* @return string on success
|
||||
* @param string $html Body HTML content.
|
||||
* @param string $subject Email subject/title used in the <title> tag.
|
||||
*
|
||||
* @return string Full HTML email body.
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function setBasicBody($html, $subject)
|
||||
public static function setBasicBody(string $html, string $subject): string
|
||||
{
|
||||
$body = [];
|
||||
$body[] = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
|
||||
$body[] = "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
|
||||
$body[] = "<head>";
|
||||
$body[] = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
|
||||
$body[] = "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>";
|
||||
$body[] = "<title>" . $subject . "</title>";
|
||||
$body[] = "<style type=\"text/css\">";
|
||||
$body[] = "#outlook a {padding:0;}";
|
||||
$body[] = ".ExternalClass {width:100%;}";
|
||||
$body[] = ".ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} ";
|
||||
$body[] = "p {margin: 0; padding: 0; font-size: 0px; line-height: 0px;} ";
|
||||
$body[] = "table td {border-collapse: collapse;}";
|
||||
$body[] = "table {border-collapse: collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; }";
|
||||
$body[] = "img {display: block; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;}";
|
||||
$body[] = "a img {border: none;}";
|
||||
$body[] = "a {text-decoration: none; color: #000001;}";
|
||||
$body[] = "a.phone {text-decoration: none; color: #000001 !important; pointer-events: auto; cursor: default;}";
|
||||
$body[] = "span {font-size: 13px; line-height: 17px; font-family: monospace; color: #000001;}";
|
||||
$body[] = "</style>";
|
||||
$body[] = "<!--[if gte mso 9]>";
|
||||
$body[] = "<style>";
|
||||
$body[] = "/* Target Outlook 2007 and 2010 */";
|
||||
$body[] = "</style>";
|
||||
$body[] = "<![endif]-->";
|
||||
$body[] = "</head>";
|
||||
$body[] = "<body style=\"width:100%; margin:0; padding:0; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;\">";
|
||||
$body[] = $html;
|
||||
$body[] = "</body>";
|
||||
$body[] = "</html>";
|
||||
|
||||
return implode("\n", $body);
|
||||
return implode("\n", [
|
||||
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||
'<html xmlns="http://www.w3.org/1999/xhtml">',
|
||||
'<head>',
|
||||
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
|
||||
'<meta name="viewport" content="width=device-width, initial-scale=1.0"/>',
|
||||
'<title>' . htmlspecialchars($subject) . '</title>',
|
||||
'<style type="text/css">',
|
||||
'#outlook a {padding:0;} .ExternalClass {width:100%;} .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height:100%;}',
|
||||
// 'p {margin: 0; padding: 0; font-size: 0px; line-height: 0px;}',
|
||||
'table, table td {border-collapse: collapse;}',
|
||||
'img {display:block; outline:none; text-decoration:none; -ms-interpolation-mode:bicubic;}',
|
||||
'a img {border:none;} a {text-decoration:none; color:#000001;} a.phone {pointer-events:auto; cursor:default; color:#000001 !important;}',
|
||||
'span {font-size:13px; line-height:17px; font-family:monospace; color:#000001;}',
|
||||
'</style>',
|
||||
'<!--[if gte mso 9]><style>/* Target Outlook 2007 and 2010 */</style><![endif]-->',
|
||||
'</head>',
|
||||
'<body style="width:100%; margin:0; padding:0; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;">',
|
||||
$html,
|
||||
'</body>',
|
||||
'</html>'
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set html text (in a row) and subject (as title) to a email table.
|
||||
* do not use <p> instead use <br />
|
||||
* in your html that you pass to this method
|
||||
* since it is a table row it does not
|
||||
* work well with paragraphs
|
||||
* Build a styled HTML email with outer table formatting for wide layout support.
|
||||
* Suitable for rich content emails that need outer table structure.
|
||||
*
|
||||
* @return string on success
|
||||
* @param string $html Inner body HTML content.
|
||||
* @param string $subject Email subject/title used in the <title> tag.
|
||||
*
|
||||
* @return string Complete HTML email content.
|
||||
* @since 3.0
|
||||
*/
|
||||
public static function setTableBody($html, $subject)
|
||||
public static function setTableBody(string $html, string $subject): string
|
||||
{
|
||||
$body = [];
|
||||
$body[] = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">";
|
||||
$body[] = "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
|
||||
$body[] = "<head>";
|
||||
$body[] = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />";
|
||||
$body[] = "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>";
|
||||
$body[] = "<title>" . $subject . "</title>";
|
||||
$body[] = "<style type=\"text/css\">";
|
||||
$body[] = "#outlook a {padding:0;}";
|
||||
$body[] = ".ExternalClass {width:100%;}";
|
||||
$body[] = ".ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height: 100%;} ";
|
||||
$body[] = "p {margin: 0; padding: 0; font-size: 0px; line-height: 0px;} ";
|
||||
$body[] = "table td {border-collapse: collapse;}";
|
||||
$body[] = "table {border-collapse: collapse; mso-table-lspace:0pt; mso-table-rspace:0pt; }";
|
||||
$body[] = "img {display: block; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic;}";
|
||||
$body[] = "a img {border: none;}";
|
||||
$body[] = "a {text-decoration: none; color: #000001;}";
|
||||
$body[] = "a.phone {text-decoration: none; color: #000001 !important; pointer-events: auto; cursor: default;}";
|
||||
$body[] = "span {font-size: 13px; line-height: 17px; font-family: monospace; color: #000001;}";
|
||||
$body[] = "</style>";
|
||||
$body[] = "<!--[if gte mso 9]>";
|
||||
$body[] = "<style>";
|
||||
$body[] = "/* Target Outlook 2007 and 2010 */";
|
||||
$body[] = "</style>";
|
||||
$body[] = "<![endif]-->";
|
||||
$body[] = "</head>";
|
||||
$body[] = "<body style=\"width:100%; margin:0; padding:0; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;\">";
|
||||
$body[] = "\n<!-- body wrapper -->";
|
||||
$body[] = "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" style=\"margin:0; padding:0; width:100%; line-height: 100% !important;\">";
|
||||
$body[] = "<tr>";
|
||||
$body[] = "<td valign=\"top\">";
|
||||
$body[] = "<!-- edge wrapper -->";
|
||||
$body[] = "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"center\" width=\"800\" >";
|
||||
$body[] = "<tr>";
|
||||
$body[] = "<td valign=\"top\">";
|
||||
$body[] = "<!-- content wrapper -->";
|
||||
$body[] = "<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\" align=\"center\" width=\"780\">";
|
||||
$body[] = "<tr>";
|
||||
$body[] = "<td valign=\"top\" style=\"vertical-align: top;\">";
|
||||
$body[] = $html;
|
||||
$body[] = "</td>";
|
||||
$body[] = "</tr>";
|
||||
$body[] = "</table>";
|
||||
$body[] = "<!-- / content wrapper -->";
|
||||
$body[] = "</td>";
|
||||
$body[] = "</tr>";
|
||||
$body[] = "</table>";
|
||||
$body[] = "<!-- / edge wrapper -->";
|
||||
$body[] = "</td>";
|
||||
$body[] = "</tr>";
|
||||
$body[] = "</table>";
|
||||
$body[] = "<!-- / page wrapper -->";
|
||||
$body[] = "</body>";
|
||||
$body[] = "</html>";
|
||||
|
||||
return implode("\n", $body);
|
||||
return implode("\n", [
|
||||
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
|
||||
'<html xmlns="http://www.w3.org/1999/xhtml">',
|
||||
'<head>',
|
||||
'<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
|
||||
'<meta name="viewport" content="width=device-width, initial-scale=1.0"/>',
|
||||
'<title>' . htmlspecialchars($subject) . '</title>',
|
||||
'<style type="text/css">',
|
||||
'#outlook a {padding:0;} .ExternalClass {width:100%;} .ExternalClass, .ExternalClass p, .ExternalClass span, .ExternalClass font, .ExternalClass td, .ExternalClass div {line-height:100%;}',
|
||||
// 'p {margin: 0; padding: 0; font-size: 0px; line-height: 0px;}',
|
||||
'table, table td {border-collapse: collapse;}',
|
||||
'img {display:block; outline:none; text-decoration:none; -ms-interpolation-mode:bicubic;}',
|
||||
'a img {border:none;} a {text-decoration:none; color:#000001;} a.phone {pointer-events:auto; cursor:default; color:#000001 !important;}',
|
||||
'span {font-size:13px; line-height:17px; font-family:monospace; color:#000001;}',
|
||||
'</style>',
|
||||
'<!--[if gte mso 9]><style>/* Target Outlook 2007 and 2010 */</style><![endif]-->',
|
||||
'</head>',
|
||||
'<body style="width:100%; margin:0; padding:0; -webkit-text-size-adjust:100%; -ms-text-size-adjust:100%;">',
|
||||
'<table cellpadding="0" cellspacing="0" border="0" width="100%" style="line-height:100% !important;">',
|
||||
'<tr><td valign="top">',
|
||||
'<table cellpadding="0" cellspacing="0" border="0" align="center" width="800">',
|
||||
'<tr><td valign="top">',
|
||||
'<table cellpadding="0" cellspacing="0" border="0" align="center" width="780">',
|
||||
'<tr><td valign="top" style="vertical-align:top;">',
|
||||
$html,
|
||||
'</td></tr></table>',
|
||||
'</td></tr></table>',
|
||||
'</td></tr></table>',
|
||||
'</body>',
|
||||
'</html>'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
@@ -38,14 +38,16 @@ use Joomla\Archive\Archive;
|
||||
use Joomla\CMS\Filesystem\Folder;
|
||||
use Joomla\CMS\Filesystem\Path;
|
||||
use VDM\Joomla\Openai\Factory as OpenaiFactory;
|
||||
use VDM\Joomla\Utilities\GuidHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper;
|
||||
use VDM\Joomla\Utilities\GetHelper;
|
||||
use VDM\Joomla\Data\Factory as DataFactory;
|
||||
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||
use VDM\Joomla\Utilities\FileHelper;
|
||||
use VDM\Joomla\Utilities\GuidHelper;
|
||||
use VDM\Joomla\Utilities\JsonHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper;
|
||||
use VDM\Joomla\Utilities\ObjectHelper;
|
||||
use VDM\Joomla\Utilities\FileHelper;
|
||||
use VDM\Joomla\Utilities\Component\Helper;
|
||||
use VDM\Joomla\Utilities\GetHelper;
|
||||
use VDM\Joomla\Utilities\SessionHelper;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Utilities\FieldHelper;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Factory as CompilerFactory;
|
||||
use VDM\Joomla\Utilities\Base64Helper;
|
||||
@@ -103,12 +105,12 @@ abstract class ComponentbuilderHelper
|
||||
/**
|
||||
* Locked Libraries (we can not have these change)
|
||||
**/
|
||||
public static $libraryNames = array(1 => 'No Library', 2 => 'Bootstrap v4', 3 => 'Uikit v3', 4 => 'Uikit v2', 5 => 'FooTable v2', 6 => 'FooTable v3');
|
||||
public static $libraryNames = [1 => 'No Library', 2 => 'Bootstrap v4', 3 => 'Uikit v3', 4 => 'Uikit v2', 5 => 'FooTable v2', 6 => 'FooTable v3'];
|
||||
|
||||
/**
|
||||
* Array of php fields Allowed (16)
|
||||
**/
|
||||
public static $phpFieldArray = array('', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'x', 'HEADER');
|
||||
public static $phpFieldArray = ['', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'x', 'HEADER'];
|
||||
|
||||
/**
|
||||
* The global params
|
||||
@@ -130,30 +132,6 @@ abstract class ComponentbuilderHelper
|
||||
**/
|
||||
protected static $exPowers= array();
|
||||
|
||||
/**
|
||||
* The snippet paths
|
||||
**/
|
||||
public static $snippetPath = 'https://raw.githubusercontent.com/vdm-io/Joomla-Component-Builder-Snippets/master/';
|
||||
public static $snippetsPath = 'https://api.github.com/repos/vdm-io/Joomla-Component-Builder-Snippets/git/trees/master';
|
||||
|
||||
/**
|
||||
* The VDM packages paths
|
||||
**/
|
||||
public static $vdmGithubPackageUrl = "https://github.com/vdm-io/JCB-Packages/raw/master/";
|
||||
public static $vdmGithubPackagesUrl = "https://api.github.com/repos/vdm-io/JCB-Packages/git/trees/master";
|
||||
|
||||
/**
|
||||
* The JCB packages paths
|
||||
**/
|
||||
public static $jcbGithubPackageUrl = "https://github.com/vdm-io/JCB-Community-Packages/raw/master/";
|
||||
public static $jcbGithubPackagesUrl = "https://api.github.com/repos/vdm-io/JCB-Community-Packages/git/trees/master";
|
||||
|
||||
/**
|
||||
* The bolerplate paths
|
||||
**/
|
||||
public static $bolerplatePath = 'https://raw.githubusercontent.com/vdm-io/boilerplate/jcb/';
|
||||
public static $bolerplateAPI = 'https://api.github.com/repos/vdm-io/boilerplate/git/trees/jcb';
|
||||
|
||||
/**
|
||||
* The array of constant paths
|
||||
*
|
||||
@@ -206,527 +184,37 @@ abstract class ComponentbuilderHelper
|
||||
);
|
||||
|
||||
/**
|
||||
* get the class method or property
|
||||
* Retrieves an associative array of published language tags as headers.
|
||||
*
|
||||
* @input mixed The method/property ID|GUID
|
||||
* @input string The target type
|
||||
* The returned array is used to build header labels for language translations.
|
||||
* Includes a default 'source' => 'source' entry.
|
||||
*
|
||||
* @returns string on success
|
||||
* @since 3.0.0
|
||||
* @return array<string, string> Associative array of language headers
|
||||
* @since 5.1.1
|
||||
*/
|
||||
public static function getClassCode($target, string $type): ?string
|
||||
public static function getLanguageTranslationsHeaders(): array
|
||||
{
|
||||
if ('property' === $type || 'method' === $type)
|
||||
{
|
||||
if (GuidHelper::valid($target))
|
||||
{
|
||||
$key = 'guid';
|
||||
}
|
||||
elseif (is_numeric($target))
|
||||
{
|
||||
$key = 'id';
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
$values = DataFactory::_('Load')->values(
|
||||
['langtag'], ['language'], ['published' => 1], ['name' => 'ASC']
|
||||
);
|
||||
|
||||
// Get a db connection.
|
||||
$db = Factory::getDbo();
|
||||
// Get user object
|
||||
$user = Factory::getUser();
|
||||
// Create a new query object.
|
||||
$query = $db->getQuery(true);
|
||||
// get method
|
||||
if ('method' === $type)
|
||||
{
|
||||
$query->select($db->quoteName(['a.comment','a.name','a.visibility','a.arguments','a.code']));
|
||||
}
|
||||
// get property
|
||||
elseif ('property' === $type)
|
||||
{
|
||||
$query->select($db->quoteName(['a.comment','a.name','a.visibility','a.default']));
|
||||
}
|
||||
$query->from($db->quoteName('#__componentbuilder_class_' . $type, 'a'));
|
||||
$query->where($db->quoteName('a.' . $key) . ' = ' . $db->quote($target));
|
||||
// Implement View Level Access
|
||||
if (!$user->authorise('core.options', 'com_componentbuilder'))
|
||||
{
|
||||
$columns = $db->getTableColumns('#__componentbuilder_class_' . $type);
|
||||
if(isset($columns['access']))
|
||||
{
|
||||
$groups = implode(',', $user->getAuthorisedViewLevels());
|
||||
$query->where('a.access IN (' . $groups . ')');
|
||||
}
|
||||
}
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
if ($db->getNumRows())
|
||||
{
|
||||
// get the code
|
||||
$code = $db->loadObject();
|
||||
// combine method values
|
||||
$combinded = [];
|
||||
// add comment if set
|
||||
if (UtilitiesStringHelper::check($code->comment))
|
||||
{
|
||||
$comment = array_map('trim', (array) explode(PHP_EOL, base64_decode($code->comment)));
|
||||
$combinded[] = "\t" . implode(PHP_EOL . "\t ", $comment);
|
||||
}
|
||||
// build method
|
||||
if ('method' === $type)
|
||||
{
|
||||
// set the method signature
|
||||
if (UtilitiesStringHelper::check($code->arguments))
|
||||
{
|
||||
$combinded[] = "\t" . $code->visibility . ' function ' . $code->name . '(' . base64_decode($code->arguments) . ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
$combinded[] = "\t" . $code->visibility . ' function ' . $code->name . '()';
|
||||
}
|
||||
// set the method code
|
||||
$combinded[] = "\t" . "{";
|
||||
// add code if set
|
||||
if (UtilitiesStringHelper::check(trim($code->code)))
|
||||
{
|
||||
$combinded[] = base64_decode($code->code);
|
||||
}
|
||||
else
|
||||
{
|
||||
$combinded[] = "\t\t// add your code here";
|
||||
}
|
||||
$combinded[] = "\t" . "}";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (UtilitiesStringHelper::check($code->default))
|
||||
{
|
||||
$code->default = base64_decode($code->default);
|
||||
if (is_int($code->default))
|
||||
{
|
||||
// set the class property
|
||||
$combinded[] = "\t" . $code->visibility . ' $' . $code->name . ' = ' . (int) $code->default . ';';
|
||||
}
|
||||
elseif (is_float($code->default))
|
||||
{
|
||||
// set the class property
|
||||
$combinded[] = "\t" . $code->visibility . ' $' . $code->name . ' = ' . (float) $code->default . ';';
|
||||
}
|
||||
elseif (('false' === $code->default || 'true' === $code->default)
|
||||
|| (UtilitiesStringHelper::check($code->default) && (strpos($code->default, 'array(') !== false || strpos($code->default, '"') !== false)))
|
||||
{
|
||||
// set the class property
|
||||
$combinded[] = "\t" . $code->visibility . ' $' . $code->name . ' = ' . $code->default . ';';
|
||||
}
|
||||
elseif (UtilitiesStringHelper::check($code->default) && strpos($code->default, '"') === false)
|
||||
{
|
||||
// set the class property
|
||||
$combinded[] = "\t" . $code->visibility . ' $' . $code->name . ' = "' . $code->default . '";';
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the class property
|
||||
$combinded[] = "\t" . $code->visibility . ' $' . $code->name . ';';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the class property
|
||||
$combinded[] = "\t" . $code->visibility . ' $' . $code->name . ';';
|
||||
}
|
||||
}
|
||||
// return the code
|
||||
return implode(PHP_EOL, $combinded);
|
||||
}
|
||||
if (empty($values))
|
||||
{
|
||||
// return default array
|
||||
return ['source' => 'source', 'af-ZA' => 'af-ZA', 'nl-NL' => 'nl-NL', 'fr-FR' => 'fr-FR', 'de-DE' => 'de-DE', 'pt-PT' => 'pt-PT', 'ru-RU' => 'ru-RU'];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract Boilerplate Class Extends
|
||||
*
|
||||
* @input string The class as a string
|
||||
* @input string The type of class/extension
|
||||
*
|
||||
* @returns string on success
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static function extractBoilerplateClassExtends(&$class, $type)
|
||||
{
|
||||
if (($strings = GetHelper::allBetween($class, 'class ', '}')) !== false && UtilitiesArrayHelper::check($strings))
|
||||
{
|
||||
foreach ($strings as $string)
|
||||
{
|
||||
if (($extends = GetHelper::between($string, 'extends ', '{')) !== false && UtilitiesStringHelper::check($extends))
|
||||
{
|
||||
return trim($extends);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
$headers = ['source' => 'source'];
|
||||
|
||||
/**
|
||||
* extract Boilerplate Class Header
|
||||
*
|
||||
* @input string The class as a string
|
||||
* @input string The class being extended
|
||||
* @input string The type of class/extension
|
||||
*
|
||||
* @returns string on success
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static function extractBoilerplateClassHeader(&$class, $extends, $type)
|
||||
{
|
||||
if (($string = GetHelper::between($class, "defined('_JEXEC')", 'extends ' . $extends)) !== false && UtilitiesStringHelper::check($string))
|
||||
foreach ($values as $value)
|
||||
{
|
||||
$headArray = explode(PHP_EOL, $string);
|
||||
if (UtilitiesArrayHelper::check($headArray) && count($headArray) > 3)
|
||||
if (is_string($value) && trim($value) !== '')
|
||||
{
|
||||
// remove first since it still has the [or die;] string in it
|
||||
array_shift($headArray);
|
||||
// remove the last since it has the class declaration
|
||||
array_pop($headArray);
|
||||
// at this point we have the class comment still in as part of the header, lets remove that
|
||||
$last = count($headArray);
|
||||
while ($last > 0)
|
||||
{
|
||||
$last--;
|
||||
if (isset($headArray[$last]) && strpos($headArray[$last], '*') !== false)
|
||||
{
|
||||
unset($headArray[$last]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// moment the comment stops, we break out
|
||||
$last = 0;
|
||||
}
|
||||
}
|
||||
// make sure we only return if we have values
|
||||
if (UtilitiesArrayHelper::check($headArray))
|
||||
{
|
||||
return implode(PHP_EOL, $headArray);
|
||||
}
|
||||
$headers[$value] = $value;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract Boilerplate Class Comment
|
||||
*
|
||||
* @input string The class as a string
|
||||
* @input string The class being extended
|
||||
* @input string The type of class/extension
|
||||
*
|
||||
* @returns string on success
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static function extractBoilerplateClassComment(&$class, $extends, $type)
|
||||
{
|
||||
if (($string = GetHelper::between($class, "defined('_JEXEC')", 'extends ' . $extends)) !== false && UtilitiesStringHelper::check($string))
|
||||
{
|
||||
$headArray = explode(PHP_EOL, $string);
|
||||
if (UtilitiesArrayHelper::check($headArray) && count($headArray) > 3)
|
||||
{
|
||||
$comment = array();
|
||||
// remove the last since it has the class declaration
|
||||
array_pop($headArray);
|
||||
// at this point we have the class comment still in as part of the header, lets remove that
|
||||
$last = count($headArray);
|
||||
while ($last > 0)
|
||||
{
|
||||
$last--;
|
||||
if (isset($headArray[$last]) && strpos($headArray[$last], '*') !== false)
|
||||
{
|
||||
$comment[$last] = $headArray[$last];
|
||||
}
|
||||
else
|
||||
{
|
||||
// moment the comment stops, we break out
|
||||
$last = 0;
|
||||
}
|
||||
}
|
||||
// make sure we only return if we have values
|
||||
if (UtilitiesArrayHelper::check($comment))
|
||||
{
|
||||
// set the correct order
|
||||
ksort($comment);
|
||||
$replace = array('Foo' => '[[[Plugin_name]]]', '[PACKAGE_NAME]' => '[[[Plugin]]]', '1.0.0' => '[[[plugin.version]]]', '1.0' => '[[[plugin.version]]]');
|
||||
// now update with JCB placeholders
|
||||
return str_replace(array_keys($replace), array_values($replace), implode(PHP_EOL, $comment));
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract Boilerplate Class Properties & Methods
|
||||
*
|
||||
* @input string The class as a string
|
||||
* @input string The class being extended
|
||||
* @input string The type of class/extension
|
||||
* @input int The plugin groups
|
||||
*
|
||||
* @returns string on success
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static function extractBoilerplateClassPropertiesMethods(&$class, $extends, $type, $plugin_group = null)
|
||||
{
|
||||
$bucket = array('property' => array(), 'method' => array());
|
||||
// get the class code, and remove the head
|
||||
$codeArrayTmp = explode('extends ' . $extends, $class);
|
||||
// make sure we have the correct result
|
||||
if (UtilitiesArrayHelper::check($codeArrayTmp) && count($codeArrayTmp) == 2)
|
||||
{
|
||||
// the triggers
|
||||
$triggers = array('public' => 1, 'protected' => 2, 'private' => 3);
|
||||
$codeArray = explode(PHP_EOL, $codeArrayTmp[1]);
|
||||
unset($codeArrayTmp);
|
||||
// clean the code
|
||||
self::cleanBoilerplateCode($codeArray);
|
||||
// temp bucket
|
||||
$name = null;
|
||||
$arg = null;
|
||||
$target = null;
|
||||
$visibility = null;
|
||||
$tmp = array();
|
||||
$comment = array();
|
||||
// load method
|
||||
$loadCode = function (&$bucket, &$target, &$name, &$arg, &$visibility, &$tmp, &$comment) use($type, $plugin_group){
|
||||
$_tmp = array(
|
||||
'name' => $name,
|
||||
'visibility' => $visibility,
|
||||
'extension_type' => $type
|
||||
);
|
||||
// build filter
|
||||
$filters = array('extension_type' => $type);
|
||||
// add more data based on target
|
||||
if ('method' === $target && UtilitiesArrayHelper::check($tmp))
|
||||
{
|
||||
// clean the code
|
||||
self::cleanBoilerplateCode($tmp);
|
||||
// only load if there are values
|
||||
if (UtilitiesArrayHelper::check($tmp, true))
|
||||
{
|
||||
$_tmp['code'] = implode(PHP_EOL, $tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
$_tmp['code'] = '';
|
||||
}
|
||||
// load arguments only if set
|
||||
if (UtilitiesStringHelper::check($arg))
|
||||
{
|
||||
$_tmp['arguments'] = $arg;
|
||||
}
|
||||
}
|
||||
elseif ('property' === $target)
|
||||
{
|
||||
// load default only if set
|
||||
if (UtilitiesStringHelper::check($arg))
|
||||
{
|
||||
$_tmp['default'] = $arg;
|
||||
}
|
||||
}
|
||||
// load comment only if set
|
||||
if (UtilitiesArrayHelper::check($comment, true))
|
||||
{
|
||||
$_tmp['comment'] = implode(PHP_EOL, $comment);
|
||||
}
|
||||
// load the group target
|
||||
if ($plugin_group)
|
||||
{
|
||||
$_tmp['joomla_plugin_group'] = $plugin_group;
|
||||
$filters['joomla_plugin_group'] = $plugin_group;
|
||||
}
|
||||
// load the local values
|
||||
if (($locals = self::getLocalBoilerplate($name, $target, $type, $filters)) !== false)
|
||||
{
|
||||
foreach ($locals as $key => $value)
|
||||
{
|
||||
$_tmp[$key] = $value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$_tmp['id'] = 0;
|
||||
$_tmp['published'] = 1;
|
||||
$_tmp['version'] = 1;
|
||||
}
|
||||
// store the data based on target
|
||||
$bucket[$target][] = $_tmp;
|
||||
};
|
||||
// now we start loading
|
||||
foreach($codeArray as $line)
|
||||
{
|
||||
if ($visibility && $target && $name && strpos($line, '/**') !== false)
|
||||
{
|
||||
$loadCode($bucket, $target, $name, $arg, $visibility, $tmp, $comment);
|
||||
// reset loop buckets
|
||||
$name = null;
|
||||
$arg = null;
|
||||
$target = null;
|
||||
$visibility = null;
|
||||
$tmp = array();
|
||||
$comment = array();
|
||||
}
|
||||
// load the comment before method/property
|
||||
if (!$visibility && !$target && !$name && strpos($line, '*') !== false)
|
||||
{
|
||||
$comment[] = rtrim($line);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!$visibility && !$target && !$name)
|
||||
{
|
||||
// get the line values
|
||||
$lineArray = array_values(array_map('trim', preg_split('/\s+/', trim($line))));
|
||||
// check if we are at the main line
|
||||
if (isset($lineArray[0]) && isset($triggers[$lineArray[0]]))
|
||||
{
|
||||
$visibility = $lineArray[0];
|
||||
if (strpos($line, 'function') !== false)
|
||||
{
|
||||
$target = 'method';
|
||||
// get the name
|
||||
$name = trim(GetHelper::between($line, 'function ', '('));
|
||||
// get the arguments
|
||||
$arg = trim(GetHelper::between($line, ' ' . $name . '(', ')'));
|
||||
}
|
||||
else
|
||||
{
|
||||
$target = 'property';
|
||||
if (strpos($line, '=') !== false)
|
||||
{
|
||||
// get the name
|
||||
$name = trim(GetHelper::between($line, '$', '='));
|
||||
// get the default
|
||||
$arg = trim(GetHelper::between($line, '=', ';'));
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the name
|
||||
$name = trim(GetHelper::between($line, '$', ';'));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmp[] = rtrim($line);
|
||||
}
|
||||
}
|
||||
}
|
||||
// check if a last method is still around
|
||||
if ($visibility && $target && $name)
|
||||
{
|
||||
$loadCode($bucket, $target, $name, $arg, $visibility, $tmp, $comment);
|
||||
// reset loop buckets
|
||||
$name = null;
|
||||
$arg = null;
|
||||
$target = null;
|
||||
$visibility = null;
|
||||
$tmp = array();
|
||||
$comment = array();
|
||||
}
|
||||
return $bucket;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static function getLocalBoilerplate($name, $table, $extension_type, $filters = array())
|
||||
{
|
||||
if ('property' === $table || 'method' === $table)
|
||||
{
|
||||
// Get a db connection.
|
||||
$db = Factory::getDbo();
|
||||
// Create a new query object.
|
||||
$query = $db->getQuery(true);
|
||||
// get method
|
||||
$query->select($db->quoteName(array('a.id','a.published','a.version')));
|
||||
$query->from($db->quoteName('#__componentbuilder_class_' . $table,'a'));
|
||||
$query->where($db->quoteName('a.name') . ' = ' . $db->quote($name));
|
||||
$query->where($db->quoteName('a.extension_type') . ' = ' . $db->quote($extension_type));
|
||||
// add more filters
|
||||
if (UtilitiesArrayHelper::check($filters))
|
||||
{
|
||||
foreach($filters as $where => $value)
|
||||
{
|
||||
if (is_numeric($value))
|
||||
{
|
||||
$query->where($db->quoteName('a.' . $where) . ' = ' . $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$query->where($db->quoteName('a.' . $where) . ' = ' . $db->quote($value));
|
||||
}
|
||||
}
|
||||
}
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
if ($db->getNumRows())
|
||||
{
|
||||
// get the code
|
||||
return $db->loadAssoc();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected static function cleanBoilerplateCode(&$code)
|
||||
{
|
||||
// remove the first lines until a { is found
|
||||
$key = 0;
|
||||
$found = false;
|
||||
while (!$found)
|
||||
{
|
||||
if (isset($code[$key]))
|
||||
{
|
||||
if (strpos($code[$key], '{') !== false)
|
||||
{
|
||||
unset($code[$key]);
|
||||
// only remove the first } found
|
||||
$found = true;
|
||||
}
|
||||
// remove empty lines
|
||||
elseif (!UtilitiesStringHelper::check(trim($code[$key])))
|
||||
{
|
||||
unset($code[$key]);
|
||||
}
|
||||
}
|
||||
// check next line
|
||||
$key++;
|
||||
// stop loop at line 30 (really this should never happen)
|
||||
if ($key > 30)
|
||||
{
|
||||
$found = true;
|
||||
}
|
||||
}
|
||||
// reset all keys
|
||||
$code = array_values($code);
|
||||
// remove last lines until }
|
||||
$last = count($code);
|
||||
while ($last > 0)
|
||||
{
|
||||
$last--;
|
||||
if (isset($code[$last]))
|
||||
{
|
||||
if (strpos($code[$last], '}') !== false)
|
||||
{
|
||||
unset($code[$last]);
|
||||
// only remove the first } found
|
||||
$last = 0;
|
||||
}
|
||||
// remove empty lines
|
||||
elseif (!UtilitiesStringHelper::check(trim($code[$last])))
|
||||
{
|
||||
unset($code[$last]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -797,81 +285,6 @@ abstract class ComponentbuilderHelper
|
||||
return is_array($items) ? $items : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the snippet contributor details
|
||||
*
|
||||
* @param string $filename The file name
|
||||
* @param string $type The type of file
|
||||
*
|
||||
* @return array On success the contributor details
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public static function getContributorDetails(string $filename, string $type = 'snippet'): ?array
|
||||
{
|
||||
// start loading the contributor details
|
||||
$contributor = [];
|
||||
|
||||
// get the path & content
|
||||
switch ($type)
|
||||
{
|
||||
case 'snippet':
|
||||
$path = self::$snippetPath.$filename;
|
||||
// get the file if available
|
||||
$content = FileHelper::getContent($path);
|
||||
if (JsonHelper::check($content))
|
||||
{
|
||||
$content = json_decode($content, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// only allow types that are being targeted
|
||||
return null;
|
||||
break;
|
||||
}
|
||||
|
||||
// see if we have content and all needed details
|
||||
if (isset($content) && UtilitiesArrayHelper::check($content)
|
||||
&& isset($content['contributor_company'])
|
||||
&& isset($content['contributor_name'])
|
||||
&& isset($content['contributor_email'])
|
||||
&& isset($content['contributor_website']))
|
||||
{
|
||||
// got the details from file
|
||||
return [
|
||||
'contributor_company' => $content['contributor_company'] ,
|
||||
'contributor_name' => $content['contributor_name'],
|
||||
'contributor_email' => $content['contributor_email'],
|
||||
'contributor_website' => $content['contributor_website'],
|
||||
'origin' => 'file'
|
||||
];
|
||||
}
|
||||
|
||||
// get the global settings
|
||||
if (!ObjectHelper::check(self::$params))
|
||||
{
|
||||
self::$params = ComponentHelper::getParams('com_componentbuilder');
|
||||
}
|
||||
|
||||
// get the global company details
|
||||
if (!UtilitiesArrayHelper::check(self::$localCompany))
|
||||
{
|
||||
// Set the person sharing information (default VDM ;)
|
||||
self::$localCompany['company'] = self::$params->get('export_company', 'Vast Development Method');
|
||||
self::$localCompany['owner'] = self::$params->get('export_owner', 'Llewellyn van der Merwe');
|
||||
self::$localCompany['email'] = self::$params->get('export_email', 'joomla@vdm.io');
|
||||
self::$localCompany['website'] = self::$params->get('export_website', 'https://www.vdm.io/');
|
||||
}
|
||||
|
||||
// default global
|
||||
return [
|
||||
'contributor_company' => self::$localCompany['company'],
|
||||
'contributor_name' => self::$localCompany['owner'],
|
||||
'contributor_email' => self::$localCompany['email'],
|
||||
'contributor_website' => self::$localCompany['website'],
|
||||
'origin' => 'global'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the library files
|
||||
*
|
||||
@@ -1470,15 +883,6 @@ abstract class ComponentbuilderHelper
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the session defaults if not set
|
||||
**/
|
||||
protected static function setSessionDefaults()
|
||||
{
|
||||
// noting for now
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if it is a new hash
|
||||
**/
|
||||
@@ -2295,61 +1699,70 @@ abstract class ComponentbuilderHelper
|
||||
|
||||
|
||||
/**
|
||||
* the Butler
|
||||
**/
|
||||
public static $session = array();
|
||||
* Local in-memory cache of session values for faster access.
|
||||
*
|
||||
* @var array<string, mixed>
|
||||
* @since 3.5.2
|
||||
*/
|
||||
protected static array $localSession = [];
|
||||
|
||||
/**
|
||||
* the Butler Assistant
|
||||
**/
|
||||
protected static $localSession = array();
|
||||
|
||||
/**
|
||||
* start a session if not already set, and load with data
|
||||
**/
|
||||
public static function loadSession()
|
||||
* Initialize the session and set default values.
|
||||
*
|
||||
* This ensures the session is ready and can be used safely.
|
||||
* Defaults can be loaded or checked here if needed.
|
||||
*
|
||||
* @return void
|
||||
* @throws \RuntimeException if the session cannot be initialized
|
||||
* @since 3.5.2
|
||||
*/
|
||||
public static function loadSession(): void
|
||||
{
|
||||
if (!isset(self::$session) || !ObjectHelper::check(self::$session))
|
||||
// Ensure the session is initialized (handled by the session() method).
|
||||
SessionHelper::session();
|
||||
|
||||
// Set default session values if needed
|
||||
if (method_exists(static::class, 'setSessionDefaults'))
|
||||
{
|
||||
self::$session = Factory::getApplication()->getSession();
|
||||
static::setSessionDefaults();
|
||||
}
|
||||
// set the defaults
|
||||
self::setSessionDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* give Session more to keep
|
||||
**/
|
||||
public static function set($key, $value)
|
||||
* Store a key-value pair in the session and local memory.
|
||||
*
|
||||
* @param string $key The session key name
|
||||
* @param mixed $value The value to store
|
||||
*
|
||||
* @return mixed The previous session value if it existed
|
||||
* @since 3.5.2
|
||||
*/
|
||||
public static function set(string $key, $value)
|
||||
{
|
||||
if (!isset(self::$session) || !ObjectHelper::check(self::$session))
|
||||
{
|
||||
self::$session = Factory::getApplication()->getSession();
|
||||
}
|
||||
// set to local memory to speed up program
|
||||
self::$localSession[$key] = $value;
|
||||
// load to session for later use
|
||||
return self::$session->set($key, self::$localSession[$key]);
|
||||
static::$localSession[$key] = $value;
|
||||
|
||||
return SessionHelper::set($key, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* get info from Session
|
||||
**/
|
||||
public static function get($key, $default = null)
|
||||
* Retrieve a value from the session.
|
||||
* Uses local cache if already fetched during this request.
|
||||
*
|
||||
* @param string $key The session key name
|
||||
* @param mixed $default Default value if the key is not found
|
||||
*
|
||||
* @return mixed The session value
|
||||
* @since 3.5.2
|
||||
*/
|
||||
public static function get(string $key, $default = null)
|
||||
{
|
||||
if (!isset(self::$session) || !ObjectHelper::check(self::$session))
|
||||
if (!array_key_exists($key, static::$localSession))
|
||||
{
|
||||
self::$session = Factory::getApplication()->getSession();
|
||||
static::$localSession[$key] = SessionHelper::get($key, $default);
|
||||
}
|
||||
// check if in local memory
|
||||
if (!isset(self::$localSession[$key]))
|
||||
{
|
||||
// set to local memory to speed up program
|
||||
self::$localSession[$key] = self::$session->get($key, $default);
|
||||
}
|
||||
return self::$localSession[$key];
|
||||
}
|
||||
|
||||
return static::$localSession[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* get field type properties
|
||||
|
@@ -970,7 +970,7 @@ class Admin_viewModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -28,6 +28,7 @@ use VDM\Joomla\Utilities\FormHelper as JCBFormHelper;
|
||||
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||
use VDM\Joomla\Utilities\ObjectHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use Joomla\CMS\Form\Form;
|
||||
|
||||
// No direct access to this file
|
||||
\defined('_JEXEC') or die;
|
||||
@@ -109,7 +110,7 @@ class Admin_viewsModel extends ListModel
|
||||
* @param array $data data
|
||||
* @param boolean $loadData load current data
|
||||
*
|
||||
* @return \JForm|boolean The \JForm object or false on error
|
||||
* @return Form|boolean The Form object or false on error
|
||||
*
|
||||
* @since JCB 2.12.5
|
||||
*/
|
||||
|
@@ -42,6 +42,8 @@ use VDM\Joomla\Utilities\Base64Helper;
|
||||
use VDM\Joomla\Componentbuilder\Table\Search;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Utilities\FieldHelper;
|
||||
use VDM\Joomla\Utilities\FormHelper;
|
||||
use VDM\Joomla\Componentbuilder\Utilities\FilterHelper;
|
||||
use VDM\Joomla\Data\Factory as DataFactory;
|
||||
use VDM\Joomla\Componentbuilder\Package\Factory as PackageFactory;
|
||||
use VDM\Joomla\Componentbuilder\Fieldtype\Factory as FieldtypeFactory;
|
||||
use VDM\Joomla\Componentbuilder\JoomlaPower\Factory as JoomlaPowerFactory;
|
||||
@@ -4111,332 +4113,6 @@ class AjaxModel extends ListModel
|
||||
return '&ref=placeholder&refid=' . $id;
|
||||
}
|
||||
|
||||
// Used in snippet
|
||||
public function setSnippetGithub($path, $status)
|
||||
{
|
||||
// get user
|
||||
$user = Factory::getUser();
|
||||
$access = $user->authorise('snippet.access', 'com_componentbuilder');
|
||||
if ($access)
|
||||
{
|
||||
// secure path
|
||||
$path = StringHelper::safe(str_replace('.json','',$path), 'filename', '', false).'.json';
|
||||
// base path
|
||||
$base_path = basename($path);
|
||||
// set url
|
||||
$url = ComponentbuilderHelper::$snippetPath.rawurlencode($base_path);
|
||||
// get the snippets
|
||||
if (($snippet = ComponentbuilderHelper::getGithubRepoData('lib_snippet_' . $base_path, $url, null, 'array')) !== false)
|
||||
{
|
||||
return $this->saveSnippet($snippet, $status, $user);
|
||||
}
|
||||
// see if we have any errors from github
|
||||
if (UtilitiesArrayHelper::check(ComponentbuilderHelper::$githubRepoDataErrors))
|
||||
{
|
||||
return array('message' => Text::sprintf('COM_COMPONENTBUILDER_ERROR_BR_S', implode('<br />', ComponentbuilderHelper::$githubRepoDataErrors)), 'status' => 'danger');
|
||||
}
|
||||
return array('message' => Text::_('COM_COMPONENTBUILDER_ERROR_THE_PATH_HAS_A_MISMATCH_AND_COULD_THEREFORE_NOT_RETRIEVE_THE_SNIPPET_FROM_GITHUB'), 'status' => 'danger');
|
||||
}
|
||||
return array('message' => Text::_('COM_COMPONENTBUILDER_ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THE_SNIPPETS'), 'status' => 'danger');
|
||||
}
|
||||
|
||||
protected function saveSnippet($item, $status, $user)
|
||||
{
|
||||
// set some defaults
|
||||
$todayDate = Factory::getDate()->toSql();
|
||||
// get the type id
|
||||
$item['type'] = ($id = GetHelper::var('snippet_type', $item['type'], 'name', 'id')) ? $id : $this->createNew($item['type'], 'snippet_type', $user, $todayDate);
|
||||
// get the library id
|
||||
$item['library'] = ($id = GetHelper::var('library', $item['library'], 'name', 'id')) ? $id : $this->createNew($item['library'], 'library', $user, $todayDate);
|
||||
// remove type if zero
|
||||
if ($item['type'] == 0)
|
||||
{
|
||||
unset($item['type']);
|
||||
}
|
||||
// remove library if zero
|
||||
if ($item['library'] == 0)
|
||||
{
|
||||
unset($item['library']);
|
||||
}
|
||||
// get the snippet ID
|
||||
$item['id'] = $this->getSnippetId($item);
|
||||
if ($item['id'] == 0)
|
||||
{
|
||||
$canCreate = $user->authorise('snippet.create', 'com_componentbuilder');
|
||||
if ('new' === $status && !$canCreate)
|
||||
{
|
||||
return array('message' => Text::_('COM_COMPONENTBUILDER_ERROR_YOU_DO_NOT_HAVE_PERMISSION_TO_CREATE_THE_SNIPPET'), 'status' => 'danger');
|
||||
}
|
||||
}
|
||||
// get the snippet model
|
||||
$model = ComponentbuilderHelper::getModel('snippet', JPATH_ADMINISTRATOR . '/components/com_componentbuilder');
|
||||
// save the snippet
|
||||
if ($model->save($item))
|
||||
{
|
||||
if ($item['id'] == 0)
|
||||
{
|
||||
// get the saved item
|
||||
$updatedItem = $model->getItem();
|
||||
$item['id']= $updatedItem->get('id');
|
||||
}
|
||||
// we have to force modified date since the model does not allow you
|
||||
if ($this->forchDateFix($item))
|
||||
{
|
||||
return array('message' => Text::_('COM_COMPONENTBUILDER_SUCCESS_THE_SNIPPET_WAS_SAVED'), 'status' => 'success');
|
||||
}
|
||||
// return error
|
||||
return array('message' => Text::_('COM_COMPONENTBUILDER_SUCCESS_THE_SNIPPET_WAS_SAVED_BUT_THE_MODIFIED_DATE_COULD_NOT_BE_ADJUSTED_BR_BR_BTHIS_MEANS_THE_SNIPPETS_WILL_CONTINUE_TO_APPEAR_OUT_OF_DATEB'), 'status' => 'warning');
|
||||
}
|
||||
// return error
|
||||
return array('message' => Text::_('COM_COMPONENTBUILDER_ERROR_THE_SNIPPET_IS_FAULTY_AND_COULD_NOT_BE_SAVED'), 'status' => 'danger');
|
||||
}
|
||||
|
||||
protected function forchDateFix($item)
|
||||
{
|
||||
$object = new \stdClass();
|
||||
$object->id = (int) $item['id'];
|
||||
$object->created = $item['created'];
|
||||
$object->modified = $item['modified'];
|
||||
// force update
|
||||
return Factory::getDbo()->updateObject('#__componentbuilder_snippet', $object, 'id');
|
||||
}
|
||||
|
||||
protected function getSnippetId($item)
|
||||
{
|
||||
// Get a db connection.
|
||||
$db = Factory::getDbo();
|
||||
|
||||
// Create a new query object.
|
||||
$query = $db->getQuery(true);
|
||||
$query->select($db->quoteName(array('a.id')));
|
||||
$query->from($db->quoteName('#__componentbuilder_snippet', 'a'));
|
||||
$query->where($db->quoteName('a.name') . ' = ' . (string) $db->quote($item['name']));
|
||||
if (is_numeric($item['type']))
|
||||
{
|
||||
$query->where($db->quoteName('a.type') . ' = ' . (int) $item['type']);
|
||||
}
|
||||
if (is_numeric($item['library']))
|
||||
{
|
||||
$query->where($db->quoteName('a.library') . ' = ' . (int) $item['library']);
|
||||
}
|
||||
// Reset the query using our newly populated query object.
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
if ($db->getNumRows())
|
||||
{
|
||||
return $db->loadResult();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
protected function createNew($name, $type, $user, $todayDate)
|
||||
{
|
||||
// verify that we can continue
|
||||
if (ComponentbuilderHelper::getActions($type)->get('core.create'))
|
||||
{
|
||||
// get the snippet model
|
||||
$model = ComponentbuilderHelper::getModel($type, JPATH_ADMINISTRATOR . '/components/com_componentbuilder');
|
||||
// build array to save
|
||||
$item['id'] = 0;
|
||||
$item['name'] = $name;
|
||||
$item['published'] = 1;
|
||||
$item['version'] = 1;
|
||||
$item['created'] = $todayDate;
|
||||
$item['created_by'] = $user->id;
|
||||
// save the new
|
||||
$model->save($item);
|
||||
// get the saved item
|
||||
$item = $model->getItem();
|
||||
return $item->get('id');
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves published snippet GUIDs for valid libraries.
|
||||
*
|
||||
* @param mixed $libraries JSON string or array of library GUIDs.
|
||||
*
|
||||
* @return array|false List of snippet IDs or false on failure.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
public function getSnippets($libraries)
|
||||
{
|
||||
// Decode JSON if required
|
||||
if (JsonHelper::check($libraries))
|
||||
{
|
||||
$libraries = json_decode($libraries, true);
|
||||
}
|
||||
|
||||
// Ensure we have a valid array of libraries
|
||||
if (!UtilitiesArrayHelper::check($libraries))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate and expand libraries
|
||||
$validatedLibraries = $this->expandAndValidateLibraries($libraries);
|
||||
|
||||
if (!$validatedLibraries)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true)
|
||||
->select($db->quoteName('a.id'))
|
||||
->from($db->quoteName('#__componentbuilder_snippet', 'a'))
|
||||
->where($db->quoteName('a.published') . ' = 1')
|
||||
->where($db->quoteName('a.library') . ' IN ("' . implode('","', $validatedLibraries) . '")');
|
||||
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
return $db->getNumRows() ? $db->loadColumn() : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and expands library GUIDs to ensure only integers and valid references remain.
|
||||
*
|
||||
* @param array $libraries The original list of library GUIDs.
|
||||
*
|
||||
* @return array|false Sanitized and validated list of libraries, or false.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
protected function expandAndValidateLibraries(array $libraries)
|
||||
{
|
||||
$expanded = [];
|
||||
|
||||
foreach ($libraries as $guid)
|
||||
{
|
||||
$guid = (string) $guid;
|
||||
$type = GetHelper::var('library', $guid, 'guid', 'type');
|
||||
|
||||
if ((int) $type === 2)
|
||||
{
|
||||
$bundled = GetHelper::var('library', $guid, 'guid', 'libraries');
|
||||
|
||||
if (JsonHelper::check($bundled))
|
||||
{
|
||||
$bundled = json_decode($bundled, true);
|
||||
}
|
||||
|
||||
if (UtilitiesArrayHelper::check($bundled))
|
||||
{
|
||||
foreach ($bundled as $lib)
|
||||
{
|
||||
$expanded[$lib] = $lib;
|
||||
}
|
||||
}
|
||||
elseif (is_numeric($bundled))
|
||||
{
|
||||
$expanded[$bundled] = $bundled;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$expanded[$guid] = $guid;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove invalid entries and duplicates
|
||||
$valid = array_filter(array_unique($expanded), function ($guid) {
|
||||
return GuidHelper::valid($guid);
|
||||
});
|
||||
|
||||
return UtilitiesArrayHelper::check($valid) ? array_values($valid) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves snippet details by GUID or ID.
|
||||
*
|
||||
* @param string|int $key The snippet GUID (string) or ID (int).
|
||||
*
|
||||
* @return object|false The snippet data object or false on failure.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
public function getSnippetDetails($key)
|
||||
{
|
||||
$target = $this->resolveSnippetKeyField($key);
|
||||
|
||||
if ($target === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query
|
||||
->select($db->quoteName(
|
||||
[
|
||||
'a.name',
|
||||
'a.heading',
|
||||
'a.usage',
|
||||
'a.description',
|
||||
'b.name',
|
||||
'a.snippet',
|
||||
'a.url',
|
||||
'c.name'
|
||||
],
|
||||
[
|
||||
'name',
|
||||
'heading',
|
||||
'usage',
|
||||
'description',
|
||||
'type',
|
||||
'snippet',
|
||||
'url',
|
||||
'library'
|
||||
]
|
||||
))
|
||||
->from($db->quoteName('#__componentbuilder_snippet', 'a'))
|
||||
->join('LEFT', $db->quoteName('#__componentbuilder_snippet_type', 'b') . ' ON ' . $db->quoteName('a.type') . ' = ' . $db->quoteName('b.guid'))
|
||||
->join('LEFT', $db->quoteName('#__componentbuilder_library', 'c') . ' ON ' . $db->quoteName('a.library') . ' = ' . $db->quoteName('c.guid'))
|
||||
->where($db->quoteName('a.published') . ' >= 1')
|
||||
->where($db->quoteName("a.$target") . ' = ' . $db->quote($key));
|
||||
|
||||
$db->setQuery($query);
|
||||
$db->execute();
|
||||
|
||||
if ($db->getNumRows() > 0)
|
||||
{
|
||||
$snippet = $db->loadObject();
|
||||
|
||||
if (isset($snippet->snippet))
|
||||
{
|
||||
$snippet->snippet = base64_decode($snippet->snippet);
|
||||
}
|
||||
|
||||
return $snippet;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves whether the given key is a GUID or numeric ID and returns the appropriate field.
|
||||
*
|
||||
* @param mixed $key The value used to identify the snippet.
|
||||
*
|
||||
* @return string|false 'guid', 'id', or false if invalid.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
protected function resolveSnippetKeyField($key)
|
||||
{
|
||||
if (GuidHelper::valid($key))
|
||||
{
|
||||
return 'guid';
|
||||
}
|
||||
|
||||
if (is_numeric($key))
|
||||
{
|
||||
return 'id';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Used in validation_rule
|
||||
public function getExistingValidationRuleCode($name)
|
||||
{
|
||||
@@ -5011,6 +4687,237 @@ class AjaxModel extends ListModel
|
||||
return $xml;
|
||||
}
|
||||
|
||||
// Used in language_translation
|
||||
/**
|
||||
* Export language translation data by filtering records based on extension, translated, and untranslated tags.
|
||||
*
|
||||
* This method loads translation records from the database and structures them into an array
|
||||
* with language-tagged headers (e.g., `en-GB`, `de-DE`). It supports filtering for a specific
|
||||
* extension, already translated languages, and missing translations. All matching records are
|
||||
* padded with empty values for missing languages, and returned with a size count or errors.
|
||||
*
|
||||
* @param string $extension The extension identifier in format "type__name" (e.g., "com_example__field").
|
||||
* @param string $translated Comma-separated list of language tags that must have translations.
|
||||
* @param string $notTranslated Comma-separated list of language tags that must not yet have translations.
|
||||
*
|
||||
* @return array<string, mixed> Returns an array with:
|
||||
* - 'data' (array<int, array<string, string>>): The exportable translation rows.
|
||||
* - 'size' (int): Number of rows (if successful).
|
||||
* - 'errors' (string): Error message (if an error occurred).
|
||||
*
|
||||
* @throws \Throwable If any unexpected exception occurs during data fetching or parsing.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
public function exportLanguageTranslations(string $extension, string $translated, string $notTranslated): array
|
||||
{
|
||||
try {
|
||||
$ids = $this->resolveLanguageTranslationFilterIds($extension, $translated, $notTranslated);
|
||||
$where = $this->buildLanguageTranslationWhereClause($ids);
|
||||
$records = $this->loadLanguageTranslationRows($where);
|
||||
$headers = $this->getLanguageTranslationHeaders();
|
||||
|
||||
if (empty($records))
|
||||
{
|
||||
return $this->errorLanguageTranslationResponse(Text::_('COM_COMPONENTBUILDER_NO_LANGUAGE_STRINGS_FOUND'));
|
||||
}
|
||||
|
||||
$data = $this->normalizeLanguageTranslationData($records, $headers);
|
||||
|
||||
return [
|
||||
'data' => $data,
|
||||
'size' => count($data),
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
return $this->errorLanguageTranslationResponse($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve all relevant record IDs from the given filters.
|
||||
*
|
||||
* @param string $extension Extension string in format "type__name".
|
||||
* @param string $translated Comma-separated list of translated language tags.
|
||||
* @param string $notTranslated Comma-separated list of untranslated language tags.
|
||||
*
|
||||
* @return array<int>|null Array of record IDs, or empty array to load all or null to force a skip all.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
protected function resolveLanguageTranslationFilterIds(string $extension, string $translated, string $notTranslated): ?array
|
||||
{
|
||||
$ids = [];
|
||||
$forceEmpty = false;
|
||||
|
||||
// Extension IDs
|
||||
if (!empty($extension) && strpos($extension, '__') !== false)
|
||||
{
|
||||
[$type, $name] = explode('__', $extension, 2);
|
||||
$extIds = FilterHelper::translation($name, $type);
|
||||
if (!empty($extIds))
|
||||
{
|
||||
$ids = array_merge($ids, $extIds);
|
||||
}
|
||||
else
|
||||
{
|
||||
$forceEmpty = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Translated IDs
|
||||
if (!empty($translated))
|
||||
{
|
||||
$trIds = FilterHelper::translations($translated);
|
||||
if (!empty($trIds))
|
||||
{
|
||||
$ids = array_merge($ids, $trIds);
|
||||
}
|
||||
else
|
||||
{
|
||||
$forceEmpty = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Not translated IDs
|
||||
if (!empty($notTranslated))
|
||||
{
|
||||
$untrIds = FilterHelper::translations($notTranslated, false);
|
||||
if (!empty($untrIds))
|
||||
{
|
||||
$ids = array_merge($ids, $untrIds);
|
||||
}
|
||||
else
|
||||
{
|
||||
$forceEmpty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($ids === [] && !$forceEmpty)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return $forceEmpty ? null : array_unique($ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a SQL WHERE clause using resolved IDs.
|
||||
*
|
||||
* @param array<int>|null $ids The record IDs to include in the query.
|
||||
*
|
||||
* @return array<string, array<string, mixed>> A structured WHERE clause.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
protected function buildLanguageTranslationWhereClause(?array $ids): array
|
||||
{
|
||||
if ($ids === [])
|
||||
{
|
||||
// return all published
|
||||
return ['published' => ['value' => 1, 'operator' => '=', 'quote' => false]];
|
||||
}
|
||||
elseif ($ids === null)
|
||||
{
|
||||
// return none
|
||||
return ['id' => ['value' => 0, 'operator' => '=', 'quote' => false]];
|
||||
}
|
||||
|
||||
// return selected and published
|
||||
return [
|
||||
'id' => ['value' => $ids, 'operator' => 'IN', 'quote' => false],
|
||||
'published' => ['value' => 1, 'operator' => '=', 'quote' => false]
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load translation rows from the database based on the given WHERE clause.
|
||||
*
|
||||
* @param array<string, array<string, mixed>>|null $where Optional WHERE clause.
|
||||
*
|
||||
* @return array<int, array<string, mixed>> Loaded records with 'source' and 'translation' keys.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
protected function loadLanguageTranslationRows(?array $where): array
|
||||
{
|
||||
return DataFactory::_('Load')->rows(
|
||||
['source', 'translation'],
|
||||
['language_translation'],
|
||||
$where,
|
||||
['source' => 'ASC']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the list of available language headers (e.g., ['en-GB' => 'en-GB']).
|
||||
*
|
||||
* This includes a default 'source' => 'source' entry.
|
||||
*
|
||||
* @return array<string, string> Associative list of language tags.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
protected function getLanguageTranslationHeaders(): array
|
||||
{
|
||||
return ComponentbuilderHelper::getLanguageTranslationsHeaders() ?? ['source' => 'source'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize translation records by mapping language keys and padding missing headers.
|
||||
*
|
||||
* @param array<int, array<string, mixed>> $rows Raw translation rows from the database.
|
||||
* @param array<string, string> $headers Valid language header list.
|
||||
*
|
||||
* @return array<int, array<string, string>> Structured translation data ready for export.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
protected function normalizeLanguageTranslationData(array $rows, array $headers): array
|
||||
{
|
||||
$normalized = [];
|
||||
|
||||
foreach ($rows as $row)
|
||||
{
|
||||
$translations = json_decode($row['translation'] ?? '[]', true) ?: [];
|
||||
unset($row['translation']);
|
||||
|
||||
// Pad all expected language headers
|
||||
foreach ($headers as $lang => $_)
|
||||
{
|
||||
if ($lang === 'source')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$row[$lang] = '';
|
||||
}
|
||||
|
||||
foreach ($translations as $entry)
|
||||
{
|
||||
$lang = $entry['language'] ?? '';
|
||||
$text = trim(($entry['translation'] ?? ''));
|
||||
|
||||
if (isset($headers[$lang]) && trim($text) !== '')
|
||||
{
|
||||
$row[$lang] = $text;
|
||||
}
|
||||
}
|
||||
|
||||
$normalized[] = $row;
|
||||
}
|
||||
|
||||
return $normalized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a standardized error response with message.
|
||||
*
|
||||
* @param string $message Error message to return.
|
||||
*
|
||||
* @return array<string, mixed> Error response with 'data' as empty array and 'errors' as message.
|
||||
* @since 5.1.1
|
||||
*/
|
||||
protected function errorLanguageTranslationResponse(string $message): array
|
||||
{
|
||||
return [
|
||||
'data' => [],
|
||||
'errors' => $message,
|
||||
];
|
||||
}
|
||||
|
||||
// Used in admin_fields_relations
|
||||
public function getCodeGlueOptions($listfield, $joinfields, $type, $area)
|
||||
{
|
||||
|
@@ -599,7 +599,7 @@ class Class_methodModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -590,7 +590,7 @@ class Class_propertyModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -28,6 +28,7 @@ use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper;
|
||||
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||
use VDM\Joomla\Utilities\ObjectHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use Joomla\CMS\Form\Form;
|
||||
|
||||
// No direct access to this file
|
||||
\defined('_JEXEC') or die;
|
||||
@@ -108,7 +109,7 @@ class Custom_admin_viewsModel extends ListModel
|
||||
* @param array $data data
|
||||
* @param boolean $loadData load current data
|
||||
*
|
||||
* @return \JForm|boolean The \JForm object or false on error
|
||||
* @return Form|boolean The Form object or false on error
|
||||
*
|
||||
* @since JCB 2.12.5
|
||||
*/
|
||||
|
@@ -592,7 +592,7 @@ class Custom_codeModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -747,7 +747,7 @@ class Dynamic_getModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -678,7 +678,7 @@ class FieldModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -28,6 +28,7 @@ use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper;
|
||||
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||
use VDM\Joomla\Utilities\ObjectHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use Joomla\CMS\Form\Form;
|
||||
|
||||
// No direct access to this file
|
||||
\defined('_JEXEC') or die;
|
||||
@@ -111,7 +112,7 @@ class FieldsModel extends ListModel
|
||||
* @param array $data data
|
||||
* @param boolean $loadData load current data
|
||||
*
|
||||
* @return \JForm|boolean The \JForm object or false on error
|
||||
* @return Form|boolean The Form object or false on error
|
||||
*
|
||||
* @since JCB 2.12.5
|
||||
*/
|
||||
|
@@ -611,7 +611,7 @@ class FieldtypeModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -477,7 +477,7 @@ class Help_documentModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -904,7 +904,7 @@ class Joomla_componentModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -29,10 +29,7 @@ use Joomla\Utilities\ArrayHelper;
|
||||
use Joomla\Input\Input;
|
||||
use VDM\Component\Componentbuilder\Administrator\Helper\ComponentbuilderHelper;
|
||||
use Joomla\CMS\Helper\TagsHelper;
|
||||
use VDM\Joomla\Utilities\SessionHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper as UtilitiesStringHelper;
|
||||
use VDM\Joomla\Utilities\ObjectHelper;
|
||||
use VDM\Joomla\Utilities\GuidHelper;
|
||||
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||
|
||||
// No direct access to this file
|
||||
@@ -118,62 +115,6 @@ class Language_translationModel extends AdminModel
|
||||
return parent::getTable($type, $prefix, $config);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves or generates a Vast Development Method (VDM) key for the current item.
|
||||
*
|
||||
* This function performs the following operations:
|
||||
* 1. Checks if the VDM key is already set. If not, it proceeds to generate or retrieve one.
|
||||
* 2. Determines the item ID based on the presence of a specific argument.
|
||||
* 3. Attempts to retrieve an existing VDM key from a helper method using the item ID.
|
||||
* 4. If a VDM key is not found, it generates a new random VDM key.
|
||||
* 5. Stores the VDM key and associates it with the item ID in a helper method.
|
||||
* 6. Optionally, stores return and GUID values if available.
|
||||
* 7. Returns the VDM key.
|
||||
*
|
||||
* @return string The VDM key for the current item.
|
||||
*/
|
||||
public function getVDM()
|
||||
{
|
||||
if (!isset($this->vastDevMod))
|
||||
{
|
||||
$_id = 0; // new item probably (since it was not set in the getItem method)
|
||||
|
||||
if (empty($_id))
|
||||
{
|
||||
$id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$id = $_id;
|
||||
}
|
||||
// set the id and view name to session
|
||||
if (($vdm = SessionHelper::get('language_translation__'.$id)) !== null)
|
||||
{
|
||||
$this->vastDevMod = $vdm;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the vast development method key
|
||||
$this->vastDevMod = UtilitiesStringHelper::random(50);
|
||||
SessionHelper::set($this->vastDevMod, 'language_translation__'.$id);
|
||||
SessionHelper::set('language_translation__'.$id, $this->vastDevMod);
|
||||
// set a return value if found
|
||||
$jinput = Factory::getApplication()->input;
|
||||
$return = $jinput->get('return', null, 'base64');
|
||||
SessionHelper::set($this->vastDevMod . '__return', $return);
|
||||
// set a GUID value if found
|
||||
if (isset($item) && ObjectHelper::check($item) && isset($item->guid)
|
||||
&& GuidHelper::valid($item->guid))
|
||||
{
|
||||
SessionHelper::set($this->vastDevMod . '__guid', $item->guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $this->vastDevMod;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to get a single record.
|
||||
*
|
||||
@@ -202,6 +143,30 @@ class Language_translationModel extends AdminModel
|
||||
$item->metadata = $registry->toArray();
|
||||
}
|
||||
|
||||
if (!empty($item->plugins))
|
||||
{
|
||||
// Convert the plugins field to an array.
|
||||
$plugins = new Registry;
|
||||
$plugins->loadString($item->plugins);
|
||||
$item->plugins = $plugins->toArray();
|
||||
}
|
||||
|
||||
if (!empty($item->modules))
|
||||
{
|
||||
// Convert the modules field to an array.
|
||||
$modules = new Registry;
|
||||
$modules->loadString($item->modules);
|
||||
$item->modules = $modules->toArray();
|
||||
}
|
||||
|
||||
if (!empty($item->components))
|
||||
{
|
||||
// Convert the components field to an array.
|
||||
$components = new Registry;
|
||||
$components->loadString($item->components);
|
||||
$item->components = $components->toArray();
|
||||
}
|
||||
|
||||
if (!empty($item->translation))
|
||||
{
|
||||
// Convert the translation field to an array.
|
||||
@@ -209,56 +174,6 @@ class Language_translationModel extends AdminModel
|
||||
$translation->loadString($item->translation);
|
||||
$item->translation = $translation->toArray();
|
||||
}
|
||||
|
||||
if (!empty($item->plugins))
|
||||
{
|
||||
// JSON Decode plugins.
|
||||
$item->plugins = json_decode($item->plugins);
|
||||
}
|
||||
|
||||
if (!empty($item->modules))
|
||||
{
|
||||
// JSON Decode modules.
|
||||
$item->modules = json_decode($item->modules);
|
||||
}
|
||||
|
||||
if (!empty($item->components))
|
||||
{
|
||||
// JSON Decode components.
|
||||
$item->components = json_decode($item->components);
|
||||
}
|
||||
|
||||
|
||||
if (empty($item->id))
|
||||
{
|
||||
$id = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
$id = $item->id;
|
||||
}
|
||||
// set the id and view name to session
|
||||
if (($vdm = SessionHelper::get('language_translation__'.$id)) !== null)
|
||||
{
|
||||
$this->vastDevMod = $vdm;
|
||||
}
|
||||
else
|
||||
{
|
||||
// set the vast development method key
|
||||
$this->vastDevMod = UtilitiesStringHelper::random(50);
|
||||
SessionHelper::set($this->vastDevMod, 'language_translation__'.$id);
|
||||
SessionHelper::set('language_translation__'.$id, $this->vastDevMod);
|
||||
// set a return value if found
|
||||
$jinput = Factory::getApplication()->input;
|
||||
$return = $jinput->get('return', null, 'base64');
|
||||
SessionHelper::set($this->vastDevMod . '__return', $return);
|
||||
// set a GUID value if found
|
||||
if (isset($item) && ObjectHelper::check($item) && isset($item->guid)
|
||||
&& GuidHelper::valid($item->guid))
|
||||
{
|
||||
SessionHelper::set($this->vastDevMod . '__guid', $item->guid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $item;
|
||||
@@ -987,6 +902,45 @@ class Language_translationModel extends AdminModel
|
||||
$data['metadata'] = (string) $metadata;
|
||||
}
|
||||
|
||||
// Set the plugins items to data.
|
||||
if (isset($data['plugins']) && is_array($data['plugins']))
|
||||
{
|
||||
$plugins = new Registry;
|
||||
$plugins->loadArray($data['plugins']);
|
||||
$data['plugins'] = (string) $plugins;
|
||||
}
|
||||
elseif (!isset($data['plugins']))
|
||||
{
|
||||
// Set the empty plugins to data
|
||||
$data['plugins'] = '';
|
||||
}
|
||||
|
||||
// Set the modules items to data.
|
||||
if (isset($data['modules']) && is_array($data['modules']))
|
||||
{
|
||||
$modules = new Registry;
|
||||
$modules->loadArray($data['modules']);
|
||||
$data['modules'] = (string) $modules;
|
||||
}
|
||||
elseif (!isset($data['modules']))
|
||||
{
|
||||
// Set the empty modules to data
|
||||
$data['modules'] = '';
|
||||
}
|
||||
|
||||
// Set the components items to data.
|
||||
if (isset($data['components']) && is_array($data['components']))
|
||||
{
|
||||
$components = new Registry;
|
||||
$components->loadArray($data['components']);
|
||||
$data['components'] = (string) $components;
|
||||
}
|
||||
elseif (!isset($data['components']))
|
||||
{
|
||||
// Set the empty components to data
|
||||
$data['components'] = '';
|
||||
}
|
||||
|
||||
// Set the translation items to data.
|
||||
if (isset($data['translation']) && is_array($data['translation']))
|
||||
{
|
||||
@@ -1000,24 +954,6 @@ class Language_translationModel extends AdminModel
|
||||
$data['translation'] = '';
|
||||
}
|
||||
|
||||
// Set the plugins string to JSON string.
|
||||
if (isset($data['plugins']))
|
||||
{
|
||||
$data['plugins'] = (string) json_encode($data['plugins']);
|
||||
}
|
||||
|
||||
// Set the modules string to JSON string.
|
||||
if (isset($data['modules']))
|
||||
{
|
||||
$data['modules'] = (string) json_encode($data['modules']);
|
||||
}
|
||||
|
||||
// Set the components string to JSON string.
|
||||
if (isset($data['components']))
|
||||
{
|
||||
$data['components'] = (string) json_encode($data['components']);
|
||||
}
|
||||
|
||||
// Set the Params Items to data
|
||||
if (isset($data['params']) && is_array($data['params']))
|
||||
{
|
||||
|
@@ -28,7 +28,7 @@ use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper;
|
||||
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||
use VDM\Joomla\Utilities\ObjectHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use VDM\Joomla\Utilities\JsonHelper;
|
||||
use Joomla\CMS\Form\Form;
|
||||
|
||||
// No direct access to this file
|
||||
\defined('_JEXEC') or die;
|
||||
@@ -104,7 +104,7 @@ class Language_translationsModel extends ListModel
|
||||
* @param array $data data
|
||||
* @param boolean $loadData load current data
|
||||
*
|
||||
* @return \JForm|boolean The \JForm object or false on error
|
||||
* @return Form|boolean The Form object or false on error
|
||||
*
|
||||
* @since JCB 2.12.5
|
||||
*/
|
||||
@@ -281,55 +281,6 @@ class Language_translationsModel extends ListModel
|
||||
}
|
||||
}
|
||||
}
|
||||
// prep the lang strings for export
|
||||
if (isset($_export) && $_export && UtilitiesArrayHelper::check($items))
|
||||
{
|
||||
// insure we have the same order in the languages
|
||||
$languages = ComponentbuilderHelper::getVars('language', 1, 'published', 'langtag');
|
||||
foreach ($items as $nr => &$item)
|
||||
{
|
||||
// remove some values completely
|
||||
unset($item->components);
|
||||
unset($item->modules);
|
||||
unset($item->plugins);
|
||||
unset($item->params);
|
||||
unset($item->published);
|
||||
unset($item->created_by);
|
||||
unset($item->modified_by);
|
||||
unset($item->created);
|
||||
unset($item->modified);
|
||||
unset($item->version);
|
||||
unset($item->hits);
|
||||
unset($item->access);
|
||||
unset($item->ordering);
|
||||
// set the lang order
|
||||
if ($nr != 0)
|
||||
{
|
||||
foreach ($languages as $lanTag)
|
||||
{
|
||||
$item->{$lanTag} = '';
|
||||
}
|
||||
// now adapt the source
|
||||
if (isset($item->translation) && JsonHelper::check($item->translation))
|
||||
{
|
||||
$translations = json_decode($item->translation, true);
|
||||
if (UtilitiesArrayHelper::check($translations))
|
||||
{
|
||||
foreach ($translations as $language)
|
||||
{
|
||||
if (isset($language['translation']) && StringHelper::check($language['translation'])
|
||||
&& isset($language['language']) && StringHelper::check($language['language']))
|
||||
{
|
||||
$item->{$language['language']} = $language['translation'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove translation
|
||||
unset($item->translation);
|
||||
}
|
||||
}
|
||||
|
||||
// return items
|
||||
return $items;
|
||||
@@ -355,54 +306,50 @@ class Language_translationsModel extends ListModel
|
||||
// From the componentbuilder_item table
|
||||
$query->from($db->quoteName('#__componentbuilder_language_translation', 'a'));
|
||||
|
||||
// do not use these filters in the export method
|
||||
if (!isset($_export) || !$_export)
|
||||
// Filtering "translated in"
|
||||
$filter_translated = $this->state->get("filter.translated");
|
||||
if ($filter_translated !== null && !empty($filter_translated))
|
||||
{
|
||||
// Filtering "translated in"
|
||||
$filter_translated = $this->state->get("filter.translated");
|
||||
if ($filter_translated !== null && !empty($filter_translated))
|
||||
if (($ids = JCBFilterHelper::translations($filter_translated)) !== null)
|
||||
{
|
||||
if (($ids = JCBFilterHelper::translations($filter_translated)) !== null)
|
||||
{
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')');
|
||||
}
|
||||
|
||||
// Filtering "not translated in"
|
||||
$filter_not_translated = $this->state->get("filter.not_translated");
|
||||
if ($filter_not_translated !== null && !empty($filter_not_translated))
|
||||
else
|
||||
{
|
||||
if (($ids = JCBFilterHelper::translations($filter_not_translated, false)) !== null)
|
||||
{
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',',$ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Filtering "extension"
|
||||
$filter_extension = $this->state->get("filter.extension");
|
||||
if ($filter_extension !== null && !empty($filter_extension))
|
||||
// Filtering "not translated in"
|
||||
$filter_not_translated = $this->state->get("filter.not_translated");
|
||||
if ($filter_not_translated !== null && !empty($filter_not_translated))
|
||||
{
|
||||
if (($ids = JCBFilterHelper::translations($filter_not_translated, false)) !== null)
|
||||
{
|
||||
// column name, and id
|
||||
$type_extension = explode('__', $filter_extension);
|
||||
if (($ids = JCBFilterHelper::translation((int) $type_extension[1], $type_extension[0])) !== null)
|
||||
{
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',',$ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Filtering "extension"
|
||||
$filter_extension = $this->state->get("filter.extension");
|
||||
if ($filter_extension !== null && !empty($filter_extension))
|
||||
{
|
||||
// column name, and id
|
||||
$type_extension = explode('__', $filter_extension);
|
||||
if (($ids = JCBFilterHelper::translation((string) $type_extension[1], (string) $type_extension[0])) !== null)
|
||||
{
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,54 +463,50 @@ class Language_translationsModel extends ListModel
|
||||
$query->where('a.id IN (' . implode(',',$pks) . ')');
|
||||
}
|
||||
|
||||
// do not use these filters in the export method
|
||||
if (!isset($_export) || !$_export)
|
||||
{
|
||||
// Filtering "translated in"
|
||||
$filter_translated = $this->state->get("filter.translated");
|
||||
if ($filter_translated !== null && !empty($filter_translated))
|
||||
$filter_translated = $this->state->get("filter.translated");
|
||||
if ($filter_translated !== null && !empty($filter_translated))
|
||||
{
|
||||
if (($ids = JCBFilterHelper::translations($filter_translated)) !== null)
|
||||
{
|
||||
if (($ids = JCBFilterHelper::translations($filter_translated)) !== null)
|
||||
{
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')');
|
||||
}
|
||||
|
||||
// Filtering "not translated in"
|
||||
$filter_not_translated = $this->state->get("filter.not_translated");
|
||||
if ($filter_not_translated !== null && !empty($filter_not_translated))
|
||||
else
|
||||
{
|
||||
if (($ids = JCBFilterHelper::translations($filter_not_translated, false)) !== null)
|
||||
{
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',',$ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Filtering "extension"
|
||||
$filter_extension = $this->state->get("filter.extension");
|
||||
if ($filter_extension !== null && !empty($filter_extension))
|
||||
// Filtering "not translated in"
|
||||
$filter_not_translated = $this->state->get("filter.not_translated");
|
||||
if ($filter_not_translated !== null && !empty($filter_not_translated))
|
||||
{
|
||||
if (($ids = JCBFilterHelper::translations($filter_not_translated, false)) !== null)
|
||||
{
|
||||
// column name, and id
|
||||
$type_extension = explode('__', $filter_extension);
|
||||
if (($ids = JCBFilterHelper::translation((int) $type_extension[1], $type_extension[0])) !== null)
|
||||
{
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',',$ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Filtering "extension"
|
||||
$filter_extension = $this->state->get("filter.extension");
|
||||
if ($filter_extension !== null && !empty($filter_extension))
|
||||
{
|
||||
// column name, and id
|
||||
$type_extension = explode('__', $filter_extension);
|
||||
if (($ids = JCBFilterHelper::translation((string) $type_extension[1], (string) $type_extension[0])) !== null)
|
||||
{
|
||||
$query->where($db->quoteName('a.id') . ' IN (' . implode(',', $ids) . ')');
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is none
|
||||
$query->where($db->quoteName('a.id') . ' = ' . 0);
|
||||
}
|
||||
}
|
||||
// Implement View Level Access
|
||||
@@ -613,56 +556,6 @@ class Language_translationsModel extends ListModel
|
||||
{
|
||||
array_unshift($items,$headers);
|
||||
}
|
||||
|
||||
// prep the lang strings for export
|
||||
if (isset($_export) && $_export && UtilitiesArrayHelper::check($items))
|
||||
{
|
||||
// insure we have the same order in the languages
|
||||
$languages = ComponentbuilderHelper::getVars('language', 1, 'published', 'langtag');
|
||||
foreach ($items as $nr => &$item)
|
||||
{
|
||||
// remove some values completely
|
||||
unset($item->components);
|
||||
unset($item->modules);
|
||||
unset($item->plugins);
|
||||
unset($item->params);
|
||||
unset($item->published);
|
||||
unset($item->created_by);
|
||||
unset($item->modified_by);
|
||||
unset($item->created);
|
||||
unset($item->modified);
|
||||
unset($item->version);
|
||||
unset($item->hits);
|
||||
unset($item->access);
|
||||
unset($item->ordering);
|
||||
// set the lang order
|
||||
if ($nr != 0)
|
||||
{
|
||||
foreach ($languages as $lanTag)
|
||||
{
|
||||
$item->{$lanTag} = '';
|
||||
}
|
||||
// now adapt the source
|
||||
if (isset($item->translation) && JsonHelper::check($item->translation))
|
||||
{
|
||||
$translations = json_decode($item->translation, true);
|
||||
if (UtilitiesArrayHelper::check($translations))
|
||||
{
|
||||
foreach ($translations as $language)
|
||||
{
|
||||
if (isset($language['translation']) && StringHelper::check($language['translation'])
|
||||
&& isset($language['language']) && StringHelper::check($language['language']))
|
||||
{
|
||||
$item->{$language['language']} = $language['translation'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// remove translation
|
||||
unset($item->translation);
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
}
|
||||
|
@@ -615,7 +615,7 @@ class LibraryModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -28,6 +28,7 @@ use VDM\Joomla\Utilities\FormHelper as JCBFormHelper;
|
||||
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||
use VDM\Joomla\Utilities\ObjectHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use Joomla\CMS\Form\Form;
|
||||
|
||||
// No direct access to this file
|
||||
\defined('_JEXEC') or die;
|
||||
@@ -107,7 +108,7 @@ class PowersModel extends ListModel
|
||||
* @param array $data data
|
||||
* @param boolean $loadData load current data
|
||||
*
|
||||
* @return \JForm|boolean The \JForm object or false on error
|
||||
* @return Form|boolean The Form object or false on error
|
||||
*
|
||||
* @since JCB 2.12.5
|
||||
*/
|
||||
|
@@ -23,9 +23,11 @@ use Joomla\Utilities\ArrayHelper;
|
||||
use Joomla\Input\Input;
|
||||
use VDM\Component\Componentbuilder\Administrator\Helper\ComponentbuilderHelper;
|
||||
use Joomla\CMS\Helper\TagsHelper;
|
||||
use VDM\Joomla\Utilities\FormHelper;
|
||||
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||
use VDM\Joomla\Utilities\ObjectHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use Joomla\CMS\Form\Form;
|
||||
|
||||
// No direct access to this file
|
||||
\defined('_JEXEC') or die;
|
||||
@@ -89,8 +91,8 @@ class RepositoriesModel extends ListModel
|
||||
'a.organisation','organisation',
|
||||
'a.repository','repository',
|
||||
'a.target','target',
|
||||
'a.base','base',
|
||||
'a.type','type'
|
||||
'a.type','type',
|
||||
'a.base','base'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -99,6 +101,48 @@ class RepositoriesModel extends ListModel
|
||||
$this->app ??= Factory::getApplication();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filter form - Override the parent method
|
||||
*
|
||||
* @param array $data data
|
||||
* @param boolean $loadData load current data
|
||||
*
|
||||
* @return Form|boolean The Form object or false on error
|
||||
*
|
||||
* @since JCB 2.12.5
|
||||
*/
|
||||
public function getFilterForm($data = array(), $loadData = true)
|
||||
{
|
||||
// load form from the parent class
|
||||
$form = parent::getFilterForm($data, $loadData);
|
||||
|
||||
// Create the "read write branch" filter
|
||||
$attributes = array(
|
||||
'name' => 'branch',
|
||||
'type' => 'list',
|
||||
'onchange' => 'this.form.submit();',
|
||||
);
|
||||
$options = [
|
||||
'' => '- ' . Text::_('COM_COMPONENTBUILDER_SELECT_BRANCH_STATE') . ' -',
|
||||
'write' => Text::_('COM_COMPONENTBUILDER_WRITE_BRANCH_SET'),
|
||||
'no_write' => Text::_('COM_COMPONENTBUILDER_NO_WRITE_BRANCH_SET'),
|
||||
'read' => Text::_('COM_COMPONENTBUILDER_READ_BRANCH_SET'),
|
||||
'no_read' => Text::_('COM_COMPONENTBUILDER_NO_READ_BRANCH_SET'),
|
||||
'both' => Text::_('COM_COMPONENTBUILDER_BOTH_BRANCHES_SET'),
|
||||
'none' => Text::_('COM_COMPONENTBUILDER_NO_BRANCHES_SET')
|
||||
];
|
||||
|
||||
$form->setField(FormHelper::xml($attributes, $options),'filter');
|
||||
$form->setValue(
|
||||
'branch',
|
||||
'filter',
|
||||
$this->state->get("filter.branch")
|
||||
);
|
||||
array_push($this->filter_fields, 'branch');
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to auto-populate the model state.
|
||||
*
|
||||
@@ -166,13 +210,6 @@ class RepositoriesModel extends ListModel
|
||||
$this->setState('filter.target', $target);
|
||||
}
|
||||
|
||||
$base = $this->getUserStateFromRequest($this->context . '.filter.base', 'filter_base');
|
||||
if ($formSubmited)
|
||||
{
|
||||
$base = $app->input->post->get('base');
|
||||
$this->setState('filter.base', $base);
|
||||
}
|
||||
|
||||
$type = $this->getUserStateFromRequest($this->context . '.filter.type', 'filter_type');
|
||||
if ($formSubmited)
|
||||
{
|
||||
@@ -180,6 +217,13 @@ class RepositoriesModel extends ListModel
|
||||
$this->setState('filter.type', $type);
|
||||
}
|
||||
|
||||
$base = $this->getUserStateFromRequest($this->context . '.filter.base', 'filter_base');
|
||||
if ($formSubmited)
|
||||
{
|
||||
$base = $app->input->post->get('base');
|
||||
$this->setState('filter.base', $base);
|
||||
}
|
||||
|
||||
// List state information.
|
||||
parent::populateState($ordering, $direction);
|
||||
}
|
||||
@@ -298,6 +342,51 @@ class RepositoriesModel extends ListModel
|
||||
// From the componentbuilder_item table
|
||||
$query->from($db->quoteName('#__componentbuilder_repository', 'a'));
|
||||
|
||||
// Filtering by "branch"
|
||||
$filterBranch = $this->state->get('filter.branch');
|
||||
|
||||
// Ensure the filter value is a string and not empty
|
||||
if (is_string($filterBranch) && $filterBranch !== '')
|
||||
{
|
||||
$readBranch = 'CHAR_LENGTH(TRIM(' . $db->quoteName('a.read_branch') . '))';
|
||||
$writeBranch = 'CHAR_LENGTH(TRIM(' . $db->quoteName('a.write_branch') . '))';
|
||||
|
||||
switch ($filterBranch)
|
||||
{
|
||||
case 'both':
|
||||
// Both read_branch and write_branch must be set
|
||||
$query->where("{$readBranch} > 1");
|
||||
$query->where("{$writeBranch} > 1");
|
||||
break;
|
||||
|
||||
case 'none':
|
||||
// Neither read_branch nor write_branch must be set
|
||||
$query->where("{$readBranch} = 0");
|
||||
$query->where("{$writeBranch} = 0");
|
||||
break;
|
||||
|
||||
case 'read':
|
||||
// Only read_branch must be set
|
||||
$query->where("{$readBranch} > 1");
|
||||
break;
|
||||
|
||||
case 'write':
|
||||
// Only write_branch must be set
|
||||
$query->where("{$writeBranch} > 1");
|
||||
break;
|
||||
|
||||
case 'no_read':
|
||||
// Only read_branch must NOT be set
|
||||
$query->where("{$readBranch} = 0");
|
||||
break;
|
||||
|
||||
case 'no_write':
|
||||
// Only write_branch must NOT be set
|
||||
$query->where("{$writeBranch} = 0");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter by published state
|
||||
$published = $this->getState('filter.published');
|
||||
if (is_numeric($published))
|
||||
@@ -397,6 +486,23 @@ class RepositoriesModel extends ListModel
|
||||
{
|
||||
$query->where('a.target = ' . $db->quote($db->escape($_target)));
|
||||
}
|
||||
// Filter by Type.
|
||||
$_type = $this->getState('filter.type');
|
||||
if (is_numeric($_type))
|
||||
{
|
||||
if (is_float($_type))
|
||||
{
|
||||
$query->where('a.type = ' . (float) $_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
$query->where('a.type = ' . (int) $_type);
|
||||
}
|
||||
}
|
||||
elseif (StringHelper::check($_type))
|
||||
{
|
||||
$query->where('a.type = ' . $db->quote($db->escape($_type)));
|
||||
}
|
||||
// Filter by Base.
|
||||
$_base = $this->getState('filter.base');
|
||||
if (is_numeric($_base))
|
||||
@@ -458,8 +564,8 @@ class RepositoriesModel extends ListModel
|
||||
$id .= ':' . $this->getState('filter.organisation');
|
||||
$id .= ':' . $this->getState('filter.repository');
|
||||
$id .= ':' . $this->getState('filter.target');
|
||||
$id .= ':' . $this->getState('filter.base');
|
||||
$id .= ':' . $this->getState('filter.type');
|
||||
$id .= ':' . $this->getState('filter.base');
|
||||
|
||||
return parent::getStoreId($id);
|
||||
}
|
||||
|
@@ -534,7 +534,7 @@ class ServerModel extends AdminModel
|
||||
/**
|
||||
* Method to validate the form data.
|
||||
*
|
||||
* @param JForm $form The form to validate against.
|
||||
* @param Form $form The form to validate against.
|
||||
* @param array $data The data to validate.
|
||||
* @param string $group The name of the field group to validate.
|
||||
*
|
||||
|
@@ -28,6 +28,7 @@ use VDM\Joomla\Componentbuilder\Utilities\FilterHelper as JCBFilterHelper;
|
||||
use VDM\Joomla\Utilities\ArrayHelper as UtilitiesArrayHelper;
|
||||
use VDM\Joomla\Utilities\ObjectHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use Joomla\CMS\Form\Form;
|
||||
|
||||
// No direct access to this file
|
||||
\defined('_JEXEC') or die;
|
||||
@@ -109,7 +110,7 @@ class Site_viewsModel extends ListModel
|
||||
* @param array $data data
|
||||
* @param boolean $loadData load current data
|
||||
*
|
||||
* @return \JForm|boolean The \JForm object or false on error
|
||||
* @return Form|boolean The Form object or false on error
|
||||
*
|
||||
* @since JCB 2.12.5
|
||||
*/
|
||||
|
@@ -403,14 +403,6 @@ class HtmlView extends BaseHtmlView
|
||||
{
|
||||
Html::_('script', $script, ['version' => 'auto']);
|
||||
}
|
||||
// add JavaScripts
|
||||
Html::_('script', 'media/com_componentbuilder/uikit-v2/js/uikit.min.js', ['version' => 'auto']);
|
||||
Html::_('script', 'media/com_componentbuilder/uikit-v2/js/components/lightbox.min.js', ['version' => 'auto']);
|
||||
Html::_('script', 'media/com_componentbuilder/uikit-v2/js/components/notify.min.js', ['version' => 'auto']);
|
||||
// add the style sheets
|
||||
Html::_('stylesheet', 'media/com_componentbuilder/uikit-v2/css/uikit.gradient.min.css', ['version' => 'auto']);
|
||||
Html::_('stylesheet', 'media/com_componentbuilder/uikit-v2/css/components/notify.gradient.min.css', ['version' => 'auto']);
|
||||
// add var key
|
||||
$this->getDocument()->addScriptDeclaration("var vastDevMod = '".$this->get('VDM')."';");
|
||||
// LayoutHelper::render('exportlanguagetranslations', []); // to ensure that the layout gets loaded
|
||||
}
|
||||
}
|
||||
|
@@ -416,8 +416,6 @@ class HtmlView extends BaseHtmlView
|
||||
{
|
||||
Html::_('stylesheet', $style, ['version' => 'auto']);
|
||||
}
|
||||
// Add Ajax Token
|
||||
$this->getDocument()->addScriptDeclaration("var token = '" . Session::getFormToken() . "';");
|
||||
// add scripts
|
||||
foreach ($this->scripts as $script)
|
||||
{
|
||||
|
@@ -15,7 +15,6 @@ use Joomla\CMS\HTML\HTMLHelper as Html;
|
||||
use Joomla\CMS\Layout\LayoutHelper;
|
||||
use Joomla\CMS\Router\Route;
|
||||
use VDM\Component\Componentbuilder\Administrator\Helper\ComponentbuilderHelper;
|
||||
use Joomla\CMS\Uri\Uri;
|
||||
|
||||
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
|
||||
$wa = $this->getDocument()->getWebAssetManager();
|
||||
@@ -102,26 +101,3 @@ $tmpl = $tmpl ? '&tmpl=' . $tmpl : '';
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
|
||||
|
||||
|
||||
<?php
|
||||
$app = Factory::getApplication();
|
||||
?>
|
||||
function JRouter(link) {
|
||||
<?php
|
||||
if ($app->isClient('site'))
|
||||
{
|
||||
echo 'var url = "'. Uri::root() . '";';
|
||||
}
|
||||
else
|
||||
{
|
||||
echo 'var url = "";';
|
||||
}
|
||||
?>
|
||||
return url+link;
|
||||
}
|
||||
</script>
|
||||
|
@@ -49,3 +49,30 @@ if ($this->saveOrder)
|
||||
<input type="hidden" name="task" value="" />
|
||||
<?php echo Html::_('form.token'); ?>
|
||||
</form>
|
||||
<script type="text/javascript">
|
||||
// language_translations footer script
|
||||
|
||||
// get page body
|
||||
var outerBodyDiv = document.querySelector('body');
|
||||
|
||||
// start loading spinner
|
||||
var loadingDiv = document.createElement('div');
|
||||
loadingDiv.id = 'loading';
|
||||
|
||||
// Set CSS properties individually
|
||||
loadingDiv.style.background = "rgba(255, 255, 255, .8) url('components/com_componentbuilder/assets/images/ajax.gif') 50% 35% no-repeat";
|
||||
loadingDiv.style.top = (outerBodyDiv.getBoundingClientRect().top + window.pageYOffset) + "px";
|
||||
loadingDiv.style.left = (outerBodyDiv.getBoundingClientRect().left + window.pageXOffset) + "px";
|
||||
loadingDiv.style.width = outerBodyDiv.offsetWidth + "px";
|
||||
loadingDiv.style.height = outerBodyDiv.offsetHeight + "px";
|
||||
loadingDiv.style.position = 'fixed';
|
||||
loadingDiv.style.opacity = '0.80';
|
||||
loadingDiv.style.msFilter = "progid:DXImageTransform.Microsoft.Alpha(Opacity=80)";
|
||||
loadingDiv.style.filter = "alpha(opacity=80)";
|
||||
loadingDiv.style.display = 'none';
|
||||
|
||||
// add to page body
|
||||
outerBodyDiv.appendChild(loadingDiv);
|
||||
</script>
|
||||
<?php echo LayoutHelper::render('exportlanguagetranslations', []); ?>
|
||||
</script>
|
||||
|
@@ -97,7 +97,15 @@ $edit = "index.php?option=com_componentbuilder&view=repositories&task=repository
|
||||
<?php echo $this->escape($item->organisation); ?>
|
||||
</td>
|
||||
<td class="hidden-phone">
|
||||
<?php echo $this->escape($item->repository); ?>
|
||||
<div>
|
||||
<?php echo $this->escape($item->repository); ?>
|
||||
<?php if (!empty($item->read_branch)): ?>
|
||||
<br><small><?php echo Text::_('COM_COMPONENTBUILDER_READ_BRANCH'); ?>: <?php echo $item->read_branch; ?></small>
|
||||
<?php endif; ?>
|
||||
<?php if (!empty($item->write_branch)): ?>
|
||||
<br><small><?php echo Text::_('COM_COMPONENTBUILDER_WRITE_BRANCH'); ?>: <?php echo $item->write_branch; ?></small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="hidden-phone">
|
||||
<?php echo Text::_($item->target); ?>
|
||||
|
@@ -1,15 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<extension type="component" version="4.0" method="upgrade">
|
||||
<name>COM_COMPONENTBUILDER</name>
|
||||
<creationDate>27th June, 2025</creationDate>
|
||||
<creationDate>2nd July, 2025</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.1.1-beta2</version>
|
||||
<version>4.1.1-rc1</version>
|
||||
<description>< is highly advanced tool that is truly able to build extremely complex components in a fraction of the time.
|
||||
|
||||
|
@@ -113,49 +113,13 @@
|
||||
<element>pkg_component_builder</element>
|
||||
<type>package</type>
|
||||
<client>site</client>
|
||||
<version>4.1.1-alpha</version>
|
||||
<version>4.1.1-rc1</version>
|
||||
<infourl title="Component Builder!">https://dev.vdm.io</infourl>
|
||||
<downloads>
|
||||
<downloadurl type="full" format="zip">https://github.com/joomengine/pkg-component-builder/archive/refs/tags/v4.1.1-alpha4.zip</downloadurl>
|
||||
<downloadurl type="full" format="zip">https://github.com/joomengine/pkg-component-builder/archive/refs/tags/v4.1.1-rc1.zip</downloadurl>
|
||||
</downloads>
|
||||
<tags>
|
||||
<tag>alpha</tag>
|
||||
</tags>
|
||||
<maintainer>Llewellyn van der Merwe</maintainer>
|
||||
<maintainerurl>https://dev.vdm.io</maintainerurl>
|
||||
<targetplatform name="joomla" version="4\.[01234]"/>
|
||||
</update>
|
||||
<update>
|
||||
<name>Component Builder</name>
|
||||
<description>Builds Complex Joomla Components</description>
|
||||
<element>pkg_component_builder</element>
|
||||
<type>package</type>
|
||||
<client>site</client>
|
||||
<version>4.1.1-beta</version>
|
||||
<infourl title="Component Builder!">https://dev.vdm.io</infourl>
|
||||
<downloads>
|
||||
<downloadurl type="full" format="zip">https://github.com/joomengine/pkg-component-builder/archive/refs/tags/v4.1.1-beta2.zip</downloadurl>
|
||||
</downloads>
|
||||
<tags>
|
||||
<tag>beta</tag>
|
||||
</tags>
|
||||
<maintainer>Llewellyn van der Merwe</maintainer>
|
||||
<maintainerurl>https://dev.vdm.io</maintainerurl>
|
||||
<targetplatform name="joomla" version="4\.[01234]"/>
|
||||
</update>
|
||||
<update>
|
||||
<name>Component Builder</name>
|
||||
<description>Builds Complex Joomla Components</description>
|
||||
<element>pkg_component_builder</element>
|
||||
<type>component</type>
|
||||
<client>site</client>
|
||||
<version>4.1.1-beta2</version>
|
||||
<infourl title="Component Builder!">https://dev.vdm.io</infourl>
|
||||
<downloads>
|
||||
<downloadurl type="full" format="zip">https://github.com/joomengine/pkg-component-builder/archive/refs/tags/v4.1.1-beta2.zip</downloadurl>
|
||||
</downloads>
|
||||
<tags>
|
||||
<tag>beta</tag>
|
||||
<tag>release_candidate</tag>
|
||||
</tags>
|
||||
<maintainer>Llewellyn van der Merwe</maintainer>
|
||||
<maintainerurl>https://dev.vdm.io</maintainerurl>
|
||||
|
@@ -29,6 +29,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Line;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Minify;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Helper\Fields;
|
||||
use Joomla\CMS\Form\Form;
|
||||
|
||||
|
||||
/**
|
||||
@@ -17415,7 +17416,7 @@ class Interpretation extends Fields
|
||||
. " * Method to validate the form data.";
|
||||
$fix .= PHP_EOL . Indent::_(1) . " *";
|
||||
$fix .= PHP_EOL . Indent::_(1)
|
||||
. " * @param JForm \$form The form to validate against.";
|
||||
. " * @param Form \$form The form to validate against.";
|
||||
$fix .= PHP_EOL . Indent::_(1)
|
||||
. " * @param array \$data The data to validate.";
|
||||
$fix .= PHP_EOL . Indent::_(1)
|
||||
|
@@ -25,6 +25,7 @@ use VDM\Joomla\Componentbuilder\Compiler\Builder\Tags;
|
||||
use VDM\Joomla\Utilities\ArrayHelper;
|
||||
use VDM\Joomla\Utilities\StringHelper;
|
||||
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\HeaderInterface;
|
||||
use Joomla\CMS\Form\FormHelper;
|
||||
|
||||
|
||||
/**
|
||||
@@ -422,7 +423,7 @@ final class Header implements HeaderInterface
|
||||
case 'form.custom.field':
|
||||
$headers[] = 'use Joomla\CMS\HTML\HTMLHelper as Html;';
|
||||
$headers[] = "jimport('joomla.form.helper');";
|
||||
$headers[] = "\JFormHelper::loadFieldClass('###JFORM_extends###');";
|
||||
$headers[] = "FormHelper::loadFieldClass('###JFORM_extends###');";
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@@ -78,7 +78,7 @@ You write clean, readable logic — and JCB ensures compatibility under the hood
|
||||
MD;
|
||||
|
||||
// What can be found here
|
||||
$readme[] = '### What's in This Repository?';
|
||||
$readme[] = '### What\'s in This Repository?';
|
||||
$readme[] = <<<MD
|
||||
This repository contains a **index of Joomla Powers** to be used in a JCB instance.
|
||||
|
||||
|
@@ -10863,7 +10863,7 @@ class Table extends BaseTable implements TableInterface
|
||||
'store' => 'json',
|
||||
'tab_name' => 'Details',
|
||||
'db' => [
|
||||
'type' => 'TEXT',
|
||||
'type' => 'MEDIUMTEXT',
|
||||
'default' => 'EMPTY',
|
||||
'GUID' => '36edbdce-b9b7-4b89-b2d9-03f91bb56019',
|
||||
'null_switch' => 'NULL',
|
||||
|
@@ -42,7 +42,7 @@ final class Delete extends Database implements DeleteInterface
|
||||
}
|
||||
|
||||
// get a query object
|
||||
$query = $this->db->getQuery(true);
|
||||
$query = $this->db->createQuery();
|
||||
|
||||
// start the conditions bucket
|
||||
$_conditions = [];
|
||||
|
@@ -219,7 +219,7 @@ final class Insert extends Versioning implements InsertInterface
|
||||
$this->historyGuid = [];
|
||||
|
||||
// get a query object
|
||||
$query = $this->db->getQuery(true);
|
||||
$query = $this->db->createQuery();
|
||||
$table = $this->getTable($table);
|
||||
|
||||
// set the query targets
|
||||
@@ -242,7 +242,7 @@ final class Insert extends Versioning implements InsertInterface
|
||||
$limit = 300;
|
||||
|
||||
// get a query object
|
||||
$query = $this->db->getQuery(true);
|
||||
$query = $this->db->createQuery();
|
||||
|
||||
// set the query targets
|
||||
$query->insert($this->db->quoteName($table))->columns($this->db->quoteName(array_keys($columns)));
|
||||
@@ -334,7 +334,7 @@ final class Insert extends Versioning implements InsertInterface
|
||||
{
|
||||
try
|
||||
{
|
||||
$query = $this->db->getQuery(true)
|
||||
$query = $this->db->createQuery()
|
||||
->select($this->db->quoteName('id'))
|
||||
->from($this->db->quoteName($table))
|
||||
->where(
|
||||
|
@@ -330,7 +330,7 @@ final class Load extends Database implements LoadInterface
|
||||
protected function query(array $select, array $tables, ?array $where = null,
|
||||
?array $order = null, ?int $limit = null): ?object
|
||||
{
|
||||
$query = $this->db->getQuery(true);
|
||||
$query = $this->db->createQuery();
|
||||
|
||||
$this->applySelect($query, $select);
|
||||
$this->applyFromAndJoins($query, $tables);
|
||||
|
@@ -167,7 +167,7 @@ final class Update extends Versioning implements UpdateInterface
|
||||
$table = $this->getTable($table);
|
||||
|
||||
// get a query object
|
||||
$query = $this->db->getQuery(true);
|
||||
$query = $this->db->createQuery();
|
||||
|
||||
// set the query targets
|
||||
$query->update($this->db->quoteName($table));
|
||||
@@ -270,7 +270,7 @@ final class Update extends Versioning implements UpdateInterface
|
||||
}
|
||||
|
||||
// Get a query object
|
||||
$query = $this->db->getQuery(true);
|
||||
$query = $this->db->createQuery();
|
||||
|
||||
// Prepare the update statement
|
||||
$query->update($this->db->quoteName($this->getTable($table)))
|
||||
@@ -317,7 +317,7 @@ final class Update extends Versioning implements UpdateInterface
|
||||
|
||||
try
|
||||
{
|
||||
$query = $this->db->getQuery(true)
|
||||
$query = $this->db->createQuery()
|
||||
->select($this->db->quoteName('id'))
|
||||
->from($this->db->quoteName($table))
|
||||
->where($this->db->quoteName('guid') . ' = ' . $this->quote($guid));
|
||||
|
@@ -87,12 +87,12 @@ abstract class StringHelper
|
||||
{
|
||||
// Safely escape output for HTML
|
||||
$title = self::shorten($string, 400 , false);
|
||||
$escapedTitle = htmlspecialchars($title, ENT_QUOTES, 'UTF-8');
|
||||
$escapedShort = htmlspecialchars($shortened, ENT_QUOTES, 'UTF-8');
|
||||
|
||||
return '<span class="hasTip" title="' . $escapedTitle . '" style="cursor:help">'
|
||||
. $escapedShort
|
||||
. '</span>';
|
||||
return sprintf(
|
||||
'<span class="hasTip" title="%s" style="cursor:help">%s</span>',
|
||||
htmlspecialchars($title, ENT_QUOTES, 'UTF-8'),
|
||||
htmlspecialchars($shortened, ENT_QUOTES, 'UTF-8')
|
||||
);
|
||||
}
|
||||
|
||||
// Return shortened version without tooltip
|
||||
|
@@ -9,40 +9,3 @@
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
jQuery(document).ready(function($)
|
||||
{
|
||||
// set button to add more languages
|
||||
addButton('language','entranslation');
|
||||
});
|
||||
function addData(result,where){
|
||||
jQuery(result).insertAfter(jQuery(where).closest('.control-group'));
|
||||
}
|
||||
|
||||
function addButton_server(type, size){
|
||||
var getUrl = JRouter("index.php?option=com_componentbuilder&task=ajax.getButton&format=json&raw=true&vdm="+vastDevMod);
|
||||
if(token.length > 0 && type.length > 0){
|
||||
var request = token+'=1&type='+type+'&size='+size;
|
||||
}
|
||||
return jQuery.ajax({
|
||||
type: 'GET',
|
||||
url: getUrl,
|
||||
dataType: 'json',
|
||||
data: request,
|
||||
jsonp: false
|
||||
});
|
||||
}
|
||||
function addButton(type, where, size){
|
||||
// just to insure that default behaviour still works
|
||||
size = typeof size !== 'undefined' ? size : 1;
|
||||
addButton_server(type, size).done(function(result) {
|
||||
if(result){
|
||||
if (2 == size) {
|
||||
jQuery('#'+where).html(result);
|
||||
} else {
|
||||
addData(result, '#jform_'+where);
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user