* @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\Extractor; use Joomla\CMS\Factory; use Joomla\CMS\Filesystem\Folder; use VDM\Joomla\Utilities\ArrayHelper; use VDM\Joomla\Utilities\JsonHelper; use VDM\Joomla\Utilities\GetHelper; use VDM\Joomla\Utilities\String\ClassfunctionHelper; use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; use VDM\Joomla\Componentbuilder\Compiler\Config; use VDM\Joomla\Componentbuilder\Compiler\Placeholder; use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder as ComponentPlaceholder; use VDM\Joomla\Componentbuilder\Compiler\Customcode; use VDM\Joomla\Componentbuilder\Compiler\Language\Extractor; /** * Compiler Custom Code Paths * * @since 3.2.0 */ class Paths { /** * The local paths * * @var array * @since 3.2.0 **/ public array $active = []; /** * Compiler Component Placeholder * * @var array * @since 3.2.0 **/ protected array $componentPlaceholder; /** * Compiler Config * * @var Config * @since 3.2.0 **/ protected Config $config; /** * Compiler Placeholder * * @var Placeholder * @since 3.2.0 **/ protected Placeholder $placeholder; /** * Compiler Customcode * * @var Customcode * @since 3.2.0 **/ protected Customcode $customcode; /** * Compiler Language Extractor * * @var Extractor * @since 3.2.0 **/ protected Extractor $extractor; /** * Database object to query local DB * * @since 3.2.0 **/ protected $db; /** * Constructor. * * @param Config|null $config The compiler config object. * @param Placeholder|null $placeholder The compiler placeholder object. * @param ComponentPlaceholder|null $componentPlaceholder The compiler component placeholder object. * @param Customcode|null $customcode The compiler customcode object. * @param Extractor|null $extractor The compiler language extractor object. * * @throws \Exception * @since 3.2.0 */ public function __construct(?Config $config = null, ?Placeholder $placeholder = null, ?ComponentPlaceholder $componentPlaceholder = null, ?Customcode $customcode = null, ?Extractor $extractor = null) { $this->config = $config ?: Compiler::_('Config'); $this->placeholder = $placeholder ?: Compiler::_('Placeholder'); /** @var ComponentPlaceholder $componentPlaceholder */ $componentPlaceholder = $componentPlaceholder ?: Compiler::_('Component.Placeholder'); $this->customcode = $customcode ?: Compiler::_('Customcode'); $this->extractor = $extractor ?: Compiler::_('Language.Extractor'); $this->db = Factory::getDbo(); // load the placeholders to local array $this->componentPlaceholder = $componentPlaceholder->get(); // load the paths on initialization $this->load(); } /** * get the local installed path of this component * * @return void * @since 3.2.0 */ protected function load() { // set the local paths to search $local_paths = []; // admin path $local_paths['admin'] = JPATH_ADMINISTRATOR . '/components/com_' . $this->config->component_code_name; // site path $local_paths['site'] = JPATH_ROOT . '/components/com_' . $this->config->component_code_name; // media path $local_paths['media'] = JPATH_ROOT . '/media/com_' . $this->config->component_code_name; // power path $local_paths['power'] = JPATH_ROOT . '/' . $this->config->get('jcb_powers_path', 'libraries/jcb_powers'); // lets also go over the REPOS - TODO // Painful but we need to folder paths for the linked modules if (($module_ids = $this->getModuleIDs()) !== false) { foreach ($module_ids as $module_id) { // get the module folder path if (($path = $this->getModulePath($module_id)) !== false) { // set the path $local_paths['module_' . str_replace('/', '_', (string) $path)] = $path; } } } // Painful but we need to folder paths for the linked plugins if (($plugin_ids = $this->getPluginIDs()) !== false) { foreach ($plugin_ids as $plugin_id) { // get the plugin group and folder name if (($path = $this->getPluginPath($plugin_id)) !== false) { // set the path $local_paths['plugin_' . str_replace('/', '_', (string) $path)] = JPATH_ROOT . '/plugins/' . $path; } } } // check if the local install is found foreach ($local_paths as $key => $localPath) { if (!Folder::exists($localPath)) { unset($local_paths[$key]); } } if (ArrayHelper::check($local_paths)) { $this->active = $local_paths; } } /** * get the Joomla Modules IDs * * @return mixed of IDs on success * @since 3.2.0 */ protected function getModuleIDs() { if (($addjoomla_modules = GetHelper::var( 'component_modules', $this->config->component_id, 'joomla_component', 'addjoomla_modules' )) !== false) { $addjoomla_modules = (JsonHelper::check( $addjoomla_modules )) ? json_decode((string) $addjoomla_modules, true) : null; if (ArrayHelper::check($addjoomla_modules)) { $joomla_modules = array_filter( array_values($addjoomla_modules), // only load the modules whose target association call for it fn($array): bool => !isset($array['target']) || $array['target'] != 2 ); // if we have values we return IDs if (ArrayHelper::check($joomla_modules)) { return array_map( fn($array) => (int) $array['module'], $joomla_modules ); } } } return false; } /** * get the Joomla module path * * @return mixed of module path and target site area on success * @since 3.2.0 */ protected function getModulePath($id) { if (is_numeric($id) && $id > 0) { // Create a new query object. $query = $this->db->getQuery(true); $query->select('a.*'); $query->select( $this->db->quoteName( array( 'a.name', 'a.target' ), array( 'name', 'target' ) ) ); // from these tables $query->from('#__componentbuilder_joomla_module AS a'); $query->where($this->db->quoteName('a.id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); if ($this->db->getNumRows()) { // get the module data $module = $this->db->loadObject(); // update the name if it has dynamic values $module->name = $this->placeholder->update( $this->customcode->update($module->name), $this->componentPlaceholder ); // set safe class function name $module->code_name = ClassfunctionHelper::safe( $module->name ); // set module folder name $module->folder_name = 'mod_' . strtolower((string) $module->code_name); // set the lang key $this->extractor->langKeys[strtoupper($module->folder_name)] = $module->id . '_M0dUl3'; // return the path if ($module->target == 2) { // administrator client area return JPATH_ADMINISTRATOR . '/modules/' . $module->folder_name; } else { // default is the site client area return JPATH_ROOT . '/modules/' . $module->folder_name; } } } return false; } /** * get the Joomla plugins IDs * * @return mixed of IDs on success * @since 3.2.0 */ protected function getPluginIDs() { if (($addjoomla_plugins = GetHelper::var( 'component_plugins', $this->config->component_id, 'joomla_component', 'addjoomla_plugins' )) !== false) { $addjoomla_plugins = (JsonHelper::check( $addjoomla_plugins )) ? json_decode((string) $addjoomla_plugins, true) : null; if (ArrayHelper::check($addjoomla_plugins)) { $joomla_plugins = array_filter( array_values($addjoomla_plugins), function ($array) { // only load the plugins whose target association call for it if (!isset($array['target']) || $array['target'] != 2) { return true; } return false; } ); // if we have values we return IDs if (ArrayHelper::check($joomla_plugins)) { return array_map( fn($array) => (int) $array['plugin'], $joomla_plugins ); } } } return false; } /** * get the Joomla plugin path * * @return mixed of plugin path on success * @deprecated 3.3 */ protected function getPluginPath($id) { if (is_numeric($id) && $id > 0) { // Create a new query object. $query = $this->db->getQuery(true); $query->select('a.*'); $query->select( $this->db->quoteName( array( 'a.name', 'g.name' ), array( 'name', 'group' ) ) ); // from these tables $query->from('#__componentbuilder_joomla_plugin AS a'); $query->join( 'LEFT', $this->db->quoteName( '#__componentbuilder_joomla_plugin_group', 'g' ) . ' ON (' . $this->db->quoteName('a.joomla_plugin_group') . ' = ' . $this->db->quoteName('g.id') . ')' ); $query->where($this->db->quoteName('a.id') . ' = ' . (int) $id); $this->db->setQuery($query); $this->db->execute(); if ($this->db->getNumRows()) { // get the plugin data $plugin = $this->db->loadObject(); // update the name if it has dynamic values $plugin->name = $this->placeholder->update( $this->customcode->update($plugin->name), $this->componentPlaceholder ); // update the name if it has dynamic values $plugin->code_name = ClassfunctionHelper::safe( $plugin->name ); // set plugin folder name $plugin->group = strtolower((string) $plugin->group); // set plugin file name $plugin->file_name = strtolower((string) $plugin->code_name); // set the lang key $this->extractor->langKeys['PLG_' . strtoupper( $plugin->group . '_' . $plugin->file_name )] = $plugin->id . '_pLuG!n'; // return the path return $plugin->group . '/' . $plugin->file_name; } } return false; } }