* @git Joomla Component Builder * @copyright Copyright (C) 2015 Vast Development Method. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ namespace VDM\Joomla\Componentbuilder\Compiler\Customcode; use Joomla\CMS\Factory; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Language\Text; use VDM\Joomla\Utilities\ArrayHelper; use VDM\Joomla\Utilities\StringHelper; use VDM\Joomla\Utilities\GetHelper; use VDM\Joomla\Utilities\FileHelper; use VDM\Joomla\Utilities\String\FieldHelper; use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; use VDM\Joomla\Componentbuilder\Compiler\Config; use VDM\Joomla\Componentbuilder\Compiler\Placeholder\Reverse; use VDM\Joomla\Componentbuilder\Compiler\Power\Parser; use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Customcode\GuiInterface; /** * Compiler Gui Custom Code * * @since 3.2.0 */ class Gui implements GuiInterface { /** * Compiler Config * * @var Config * @since 3.2.0 **/ protected Config $config; /** * Compiler Placeholder Reverse * * @var Reverse * @since 3.2.0 **/ protected Reverse $reverse; /** * Compiler Powers Parser * * @var Parser * @since 3.2.0 **/ protected Parser $parser; /** * Database object to query local DB * * @since 3.2.0 **/ protected $db; /** * Database object to query local DB * * @since 3.2.0 **/ protected $app; /** * Constructor. * * @param Config|null $config The compiler config object. * @param Reverse|null $reverse The compiler placeholder reverse object. * @param Parser|null $parser The powers parser object. * * @throws \Exception * @since 3.2.0 */ public function __construct(?Config $config = null, ?Reverse $reverse = null, ?Parser $parser = null) { $this->config = $config ?: Compiler::_('Config'); $this->reverse = $reverse ?: Compiler::_('Placeholder.Reverse'); $this->parser = $parser ?: Compiler::_('Power.Parser'); $this->db = Factory::getDbo(); $this->app = Factory::getApplication(); } /** * Set the JCB GUI code placeholder * * @param string $string The code string * @param array $config The placeholder config values * * @return string * @since 3.2.0 */ public function set(string $string, array $config): string { if (StringHelper::check($string)) { if ($this->config->get('add_placeholders', false) && $this->check($string) && ArrayHelper::check($config) && isset($config['table']) && StringHelper::check($config['table']) && isset($config['field']) && StringHelper::check($config['field']) && isset($config['type']) && StringHelper::check($config['type']) && isset($config['id']) && is_numeric($config['id'])) { // if we have a key we must get the ID if (isset($config['key']) && StringHelper::check($config['key']) && $config['key'] !== 'id') { if (($id = GetHelper::var($config['table'], $config['id'], $config['key'], 'id')) !== false && is_numeric($id)) { $config['id'] = $id; } else { // we must give a error message to inform the user of this issue. (should never happen) $this->app->enqueueMessage( Text::sprintf('COM_COMPONENTBUILDER_ID_MISMATCH_WAS_DETECTED_WITH_THE_SSSS_GUI_CODE_FIELD_SO_THE_PLACEHOLDER_WAS_NOT_SET', $config['table'], $config['field'], $config['key'], $config['id'] ), 'Error' ); // check some config if (!isset($config['prefix'])) { $config['prefix'] = ''; } return $config['prefix'] . $string; } } // check some config if (!isset($config['prefix'])) { $config['prefix'] = PHP_EOL; } // add placeholder based on type of code switch (strtolower((string) $config['type'])) { // adding with html commenting case 'html': $front = $config['prefix'] . '' . PHP_EOL; $back = '' ); if (($guiCode = ArrayHelper::merge($guiCode)) !== false && ArrayHelper::check($guiCode, true)) { foreach ($guiCode as $code) { $first_line = strtok($code, PHP_EOL); // get the GUI target details $query = explode('.', trim($first_line, '.')); // only continue if we have 3 values in the query if (is_array($query) && count($query) >= 3) { // cleanup the newlines around the code $code = trim(str_replace($first_line, '', (string) $code), PHP_EOL) . PHP_EOL; // set the ID $id = (int) $query[2]; // make the field name save $field = FieldHelper::safe($query[1]); // make the table name save $table = StringHelper::safe($query[0]); // reverse placeholder as much as we can $code = $this->reverse->engine( $code, $placeholders, $target, $id, $field, $table, $use_statements ); // update the GUI/Tables/Database $object = new \stdClass(); $object->id = $id; $object->{$field} = base64_encode( (string) $code ); // (TODO) this may not always work... // update the value in GUI $this->db->updateObject( '#__componentbuilder_' . (string) $table, $object, 'id' ); } } } } /** * search a code to see if there is already any custom * code or other reasons not to add the GUI code placeholders * * @param string $code The code to check * * @return bool true if GUI code placeholders can be added * @since 3.2.0 */ protected function check(string &$code): bool { // check for customcode placeholders // we do not add GUI wrapper placeholder to code // that already has any customcode placeholders return strpos($code, '$$$$') === false; } }