* @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\Power; use Joomla\CMS\Factory; use Joomla\CMS\Application\CMSApplication; use Joomla\CMS\Language\Text; use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler; use VDM\Joomla\Componentbuilder\Compiler\Power; use VDM\Joomla\Componentbuilder\Compiler\Config; use VDM\Joomla\Componentbuilder\Compiler\Registry; use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface; use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter; use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths; use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder; use VDM\Joomla\Componentbuilder\Compiler\Utilities\File; use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files; use VDM\Joomla\Utilities\ObjectHelper; use VDM\Joomla\Utilities\ArrayHelper; use VDM\Joomla\Utilities\StringHelper; use VDM\Joomla\Utilities\JsonHelper; use VDM\Joomla\Utilities\FileHelper; use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix; /** * Power Structure Builder Class * * @since 3.2.0 */ class Structure { /** * we track the creation of htaccess files * * @var array * @since 3.2.0 **/ protected array $htaccess = []; /** * Power Build Tracker * * @var array * @since 3.2.0 **/ protected array $done = []; /** * Path Build Tracker * * @var array * @since 3.2.0 **/ protected array $path_done = []; /** * Power Objects * * @var Power * @since 3.2.0 **/ protected Power $power; /** * Compiler Config * * @var Config * @since 3.2.0 */ protected Config $config; /** * The compiler registry * * @var Registry * @since 3.2.0 */ protected Registry $registry; /** * Compiler Event * * @var EventInterface * @since 3.2.0 */ protected EventInterface $event; /** * Compiler Counter * * @var Counter * @since 3.2.0 */ protected Counter $counter; /** * Compiler Utilities Paths * * @var Paths * @since 3.2.0 */ protected Paths $paths; /** * Compiler Utilities Folder * * @var Folder * @since 3.2.0 */ protected Folder $folder; /** * Compiler Utilities File * * @var File * @since 3.2.0 */ protected File $file; /** * Compiler Utilities Files * * @var Files * @since 3.2.0 */ protected Files $files; /** * Database object to query local DB * * @var CMSApplication * @since 3.2.0 **/ protected CMSApplication $app; /** * Constructor * * @param Power|null $power The power object. * @param Config|null $config The compiler config object. * @param Registry|null $registry The compiler registry object. * @param EventInterface|null $event The compiler event api object. * @param Counter|null $counter The compiler counter object. * @param Paths|null $paths The compiler paths object. * @param Folder|null $folder The compiler folder object. * @param File|null $file The compiler file object. * @param Files|null $files The compiler files object. * @param CMSApplication|null $app The CMS Application object. * * @throws \Exception * @since 3.2.0 */ public function __construct(?Power $power = null, ?Config $config = null, ?Registry $registry = null, ?EventInterface $event = null, ?Counter $counter = null, ?Paths $paths = null, ?Folder $folder = null, ?File $file = null, ?Files $files = null, ?CMSApplication $app = null) { $this->power = $power ?: Compiler::_('Power'); $this->config = $config ?: Compiler::_('Config'); $this->registry = $registry ?: Compiler::_('Registry'); $this->event = $event ?: Compiler::_('Event'); $this->counter = $counter ?: Compiler::_('Utilities.Counter'); $this->paths = $paths ?: Compiler::_('Utilities.Paths'); $this->folder = $folder ?: Compiler::_('Utilities.Folder'); $this->file = $file ?: Compiler::_('Utilities.File'); $this->files = $files ?: Compiler::_('Utilities.Files'); $this->app = $app ?: Factory::getApplication(); } /** * Build the Powers files, folders * * @return void * @since 3.2.0 */ public function build() { if (ArrayHelper::check($this->power->active)) { // Trigger Event: jcb_ce_onBeforeSetModules $this->event->trigger( 'jcb_ce_onBeforeBuildPowers' ); // set super power details $this->setSuperPowerDetails(); foreach ($this->power->active as $guid => $power) { if (isset($this->done[$guid])) { continue; } if (ObjectHelper::check($power) && isset($power->path) && StringHelper::check( $power->path )) { // activate dynamic folders $this->setDynamicFolders(); // power path $power->full_path = $this->paths->component_path . '/' . $power->path; $power->full_path_jcb = $this->paths->component_path . '/' . $power->path_jcb; $power->full_path_parent = $this->paths->component_path . '/' . $power->path_parent; // set the power paths $this->registry->set('dynamic_paths.' . $power->key, $power->full_path_parent); // create the power folder if it does not exist // we do it like this to add html files to each part $this->folder->create($power->full_path_jcb); $this->folder->create($power->full_path_parent); $this->folder->create($power->full_path); $bom = 'add_licensing_template == 2) { $bom = 'licensing_template; } // set the main power php file $this->createFile($bom . PHP_EOL . Placefix::_h('POWERCODE') . PHP_EOL, $power->full_path, $power->file_name . '.php', $power->key); // set super power files $this->setSuperPowerFiles($power, $bom); // set htaccess once per path $this->setHtaccess($power); // do each power just once $this->done[$guid] = true; } } } } /** * Create a file with optional custom content and save it to the given path. * * @param string $content The content. * @param string $fullPath The full path to the destination folder. * @param string $fileName The file name without the extension. * @param string $key The key to append the file details. * * @return void * @since 3.2.0 */ private function createFile(string $content, string $fullPath, string $fileName, string $key) { $file_details = [ 'path' => $fullPath . '/' . $fileName, 'name' => $fileName, 'zip' => $fileName ]; // Write the content to the file $this->file->write($file_details['path'], $content); // Append the file details to the files array $this->files->appendArray($key, $file_details); // Increment the file counter $this->counter->file++; } /** * Set the .htaccess for this power path * * @param object $power The power object * * @return void * @since 3.2.0 */ private function setHtaccess(object &$power) { if (!isset($this->htaccess[$power->path_jcb])) { // set the htaccess data $data = '# Apache 2.4+' . PHP_EOL . '' . PHP_EOL . ' Require all denied' . PHP_EOL . '' . PHP_EOL . PHP_EOL . '# Apache 2.0-2.2' . PHP_EOL . '' . PHP_EOL . ' Deny from all' . PHP_EOL . '' . PHP_EOL; // now we must add the .htaccess file $fileDetails = array('path' => $power->full_path_jcb . '/.htaccess', 'name' => '.htaccess', 'zip' => '.htaccess'); $this->file->write( $fileDetails['path'], $data ); $this->files->appendArray($power->key, $fileDetails); // count the file created $this->counter->file++; // now we must add the htaccess.txt file where the zip package my not get the [.] files $fileDetails = array('path' => $power->full_path_jcb . '/htaccess.txt', 'name' => 'htaccess.txt', 'zip' => 'htaccess.txt'); $this->file->write( $fileDetails['path'], $data ); $this->files->appendArray($power->key, $fileDetails); // count the file created $this->counter->file++; // now we must add the web.config file $fileDetails = array('path' => $power->full_path_jcb . '/web.config', 'name' => 'web.config', 'zip' => 'web.config'); $this->file->write( $fileDetails['path'], '' . PHP_EOL . ' ' . PHP_EOL . ' ' . PHP_EOL . ' ' . PHP_EOL . ' ' . PHP_EOL . ' ' . PHP_EOL . '' . PHP_EOL ); $this->files->appendArray($power->key, $fileDetails); // count the file created $this->counter->file++; // we set these files only once $this->htaccess[$power->path_jcb] = true; } } /** * Add the dynamic folders * * @return void * @since 3.2.0 */ private function setDynamicFolders() { // check if we should add the dynamic folder moving script to the installer script if (!$this->registry->get('set_move_folders_install_script')) { $function = 'setDynamicF0ld3rs'; $script = 'script.php'; if ($this->config->get('joomla_version', 3) != 3) { $function = 'moveFolders'; $script = 'ComponentnameInstallerScript.php'; } // add the setDynamicF0ld3rs() method to the install script.php file $this->registry->set('set_move_folders_install_script', true); // set message that this was done (will still add a tutorial link later) $this->app->enqueueMessage( Text::_('COM_COMPONENTBUILDER_HR_HTHREEDYNAMIC_FOLDERS_WERE_DETECTEDHTHREE'), 'Notice' ); $this->app->enqueueMessage( Text::sprintf('COM_COMPONENTBUILDER_A_METHOD_S_WAS_ADDED_TO_THE_INSTALL_BSB_OF_THIS_PACKAGE_TO_INSURE_THAT_THE_FOLDERS_ARE_COPIED_INTO_THE_CORRECT_PLACE_WHEN_THIS_COMPONENT_IS_INSTALLED', $function, $script ), 'Notice' ); } } /** * Set the super powers details structure * * @return void * @since 3.2.0 */ private function setSuperPowerDetails() { if ($this->config->add_super_powers && ArrayHelper::check($this->power->superpowers)) { foreach ($this->power->superpowers as $path => $powers) { if (isset($this->path_done[$path])) { continue; } // get existing files $this->loadExistingSuperPower($path); // create the path if it does not exist $this->folder->create($path, false); $key = StringHelper::safe($path); // set the super powers readme file $this->createFile(Placefix::_h('POWERREADME'), $path, 'README.md', $key); // set the super power index file $this->createFile(Placefix::_h('POWERINDEX'), $path, 'super-powers.json', $key); // do each path just once $this->path_done[$path] = true; } } } /** * Set the super power file paths * * @param object $power The power object * @param string $bom The bom for the top of the PHP files * * @return void * @since 3.2.0 */ private function setSuperPowerFiles(object &$power, string $bom) { if ($this->config->add_super_powers && is_array($power->super_power_paths) && $power->super_power_paths !== []) { foreach ($power->super_power_paths as $path) { // create the path if it does not exist $this->folder->create($path, false); // set the super power php file $this->createFile($bom . PHP_EOL . Placefix::_h('POWERCODE') . PHP_EOL, $path, 'code.php', $power->key); // set the super power php RAW file $this->createFile(Placefix::_h('CODEPOWER'), $path, 'code.power', $power->key); // set the super power json file $this->createFile(Placefix::_h('POWERLINKER'), $path, 'settings.json', $power->key); // set the super power readme file $this->createFile(Placefix::_h('POWERREADME'), $path, 'README.md', $power->key); } } } /** * Set the super power file paths * * @param string $repository The super power repository * * @return void * @since 3.2.0 */ private function loadExistingSuperPower(string $repository) { if (!isset($this->power->old_superpowers[$repository]) && ($content = FileHelper::getContent($repository . '/super-powers.json', null)) !== null && JsonHelper::check($content)) { $this->power->old_superpowers[$repository] = json_decode($content, true); } } }