jcb-compiler/src/324566de-0f7d-4b6e-9caf-842.../code.php

487 lines
13 KiB
PHP

<?php
/**
* @package Joomla.Component.Builder
*
* @created 4th September, 2022
* @author Llewellyn van der Merwe <https://dev.vdm.io>
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace VDM\Joomla\Componentbuilder\Compiler\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 = '<?php' . PHP_EOL . '// A POWER FILE' .
PHP_EOL . Placefix::_h('BOM') . PHP_EOL;
// add custom override if found
if ($power->add_licensing_template == 2)
{
$bom = '<?php' . PHP_EOL . $power->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 .
'<IfModule mod_authz_core.c>' . PHP_EOL .
' Require all denied' . PHP_EOL .
'</IfModule>' . PHP_EOL . PHP_EOL .
'# Apache 2.0-2.2' . PHP_EOL .
'<IfModule !mod_authz_core.c>' . PHP_EOL .
' Deny from all' . PHP_EOL .
'</IfModule>' . 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'],
'<?xml version="1.0"?>' . PHP_EOL .
' <system.web>' . PHP_EOL .
' <authorization>' . PHP_EOL .
' <deny users="*" />' . PHP_EOL .
' </authorization>' . PHP_EOL .
' </system.web>' . PHP_EOL .
'</configuration>' . 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);
}
}
}