Release of v5.0.0-alpha8

Add power path override option on component level. Fix the sql build feature. #1032.
This commit is contained in:
2024-04-06 23:41:34 +02:00
parent 2f64eec95b
commit 2b7b8f90e1
762 changed files with 1900 additions and 1246 deletions

View File

@@ -0,0 +1,212 @@
<?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\Component;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Application\CMSApplication;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\ArrayHelper;
/**
* Compiler Component Dynamic Dashboard
*
* @since 3.2.0
*/
final class Dashboard
{
/**
* The compiler registry
*
* @var Registry
* @since 3.2.0
*/
protected Registry $registry;
/**
* Compiler Component
*
* @var Component
* @since 3.2.0
**/
protected Component $component;
/**
* Application object.
*
* @var CMSApplication
* @since 3.2.0
**/
protected CMSApplication $app;
/**
* Constructor
*
* @param Registry|null $registry The compiler registry object.
* @param Component|null $component The component class.
* @param CMSApplication|null $app The app object.
*
* @since 3.2.0
*/
public function __construct(?Registry $registry = null, ?Component $component = null,
?CMSApplication $app = null)
{
$this->registry = $registry ?: Compiler::_('Registry');
$this->component = $component ?: Compiler::_('Component');
$this->app = $app ?: Factory::getApplication();
}
/**
* Set the Dynamic Dashboard
*
* @return void
* @since 3.2.0
*/
public function set()
{
// only add the dynamic dashboard if all checks out
if ($this->component->get('dashboard_type', 0) == 2
&& ($dashboard_ = $this->component->get('dashboard')) !== null
&& StringHelper::check($dashboard_)
&& strpos((string) $dashboard_, '_') !== false)
{
// set the default view
$getter = explode('_', (string) $dashboard_);
if (count((array) $getter) == 2 && is_numeric($getter[1]))
{
// the pointers
$t = StringHelper::safe($getter[0], 'U');
$id = (int) $getter[1];
// the dynamic stuff
$targets = array('A' => 'admin_views',
'C' => 'custom_admin_views');
$names = array('A' => 'admin view',
'C' => 'custom admin view');
$types = array('A' => 'adminview', 'C' => 'customadminview');
$keys = array('A' => 'name_list', 'C' => 'code');
// check the target values
if (isset($targets[$t]) && $id > 0)
{
// set the type name
$type_names = StringHelper::safe(
$targets[$t], 'w'
);
// set the dynamic dash
if (($target_ = $this->component->get($targets[$t])) !== null
&& ArrayHelper::check($target_))
{
// search the target views
$dashboard = (array) array_filter(
$target_,
function ($view) use ($id, $t, $types) {
if (isset($view[$types[$t]])
&& $id == $view[$types[$t]])
{
return true;
}
return false;
}
);
// set dashboard
if (ArrayHelper::check($dashboard))
{
$dashboard = array_values($dashboard)[0];
}
// check if view was found (this should be true)
if (isset($dashboard['settings'])
&& isset($dashboard['settings']->{$keys[$t]}))
{
$this->registry->set('build.dashboard',
StringHelper::safe(
$dashboard['settings']->{$keys[$t]}
)
);
$this->registry->set('build.dashboard.type',
$targets[$t]
);
}
else
{
// set massage that something is wrong
$this->app->enqueueMessage(
Text::_('COM_COMPONENTBUILDER_HR_HTHREEDASHBOARD_ERRORHTHREE'),
'Error'
);
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_BSB_IS_NOT_AVAILABLE_IN_YOUR_COMPONENT_PLEASE_INSURE_TO_ONLY_USED_S_FOR_A_DYNAMIC_DASHBOARD_THAT_ARE_STILL_LINKED_TO_YOUR_COMPONENT',
$names[$t], $dashboard_,
$type_names
), 'Error'
);
}
}
else
{
// set massage that something is wrong
$this->app->enqueueMessage(
Text::_('COM_COMPONENTBUILDER_HR_HTHREEDASHBOARD_ERRORHTHREE'), 'Error'
);
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_BSB_IS_NOT_AVAILABLE_IN_YOUR_COMPONENT_PLEASE_INSURE_TO_ONLY_USED_S_FOR_A_DYNAMIC_DASHBOARD_THAT_ARE_STILL_LINKED_TO_YOUR_COMPONENT',
$names[$t], $dashboard_,
$type_names
), 'Error'
);
}
}
else
{
// the target value is wrong
$this->app->enqueueMessage(
Text::_('COM_COMPONENTBUILDER_HR_HTHREEDASHBOARD_ERRORHTHREE'), 'Error'
);
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_VALUE_FOR_THE_DYNAMIC_DASHBOARD_IS_INVALID',
$dashboard_
), 'Error'
);
}
}
else
{
// the target value is wrong
$this->app->enqueueMessage(
Text::_('COM_COMPONENTBUILDER_HR_HTHREEDASHBOARD_ERRORHTHREE'), 'Error'
);
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_THE_BSB_VALUE_FOR_THE_DYNAMIC_DASHBOARD_IS_INVALID',
$dashboard_
), 'Error'
);
}
// if default was changed to dynamic dashboard the remove default tab and methods
if ($this->registry->get('build.dashboard'))
{
// dynamic dashboard is used
$this->component->remove('dashboard_tab');
$this->component->remove('php_dashboard_methods');
}
}
}
}

View File

@@ -0,0 +1,889 @@
<?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\Component;
use Joomla\CMS\Factory;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Component\Placeholder as ComponentPlaceholder;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser;
use VDM\Joomla\Componentbuilder\Compiler\Customcode;
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Gui;
use VDM\Joomla\Componentbuilder\Compiler\Field as Field;
use VDM\Joomla\Componentbuilder\Compiler\Field\Name as FieldName;
use VDM\Joomla\Componentbuilder\Compiler\Field\UniqueName;
use VDM\Joomla\Componentbuilder\Compiler\Model\Filesfolders;
use VDM\Joomla\Componentbuilder\Compiler\Model\Historycomponent;
use VDM\Joomla\Componentbuilder\Compiler\Model\Whmcs;
use VDM\Joomla\Componentbuilder\Compiler\Model\Sqltweaking;
use VDM\Joomla\Componentbuilder\Compiler\Model\Adminviews;
use VDM\Joomla\Componentbuilder\Compiler\Model\Siteviews;
use VDM\Joomla\Componentbuilder\Compiler\Model\Customadminviews;
use VDM\Joomla\Componentbuilder\Compiler\Model\Updateserver;
use VDM\Joomla\Componentbuilder\Compiler\Model\Joomlamodules;
use VDM\Joomla\Componentbuilder\Compiler\Model\Joomlaplugins;
use VDM\Joomla\Componentbuilder\Compiler\Model\Router;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\GetHelper;
/**
* Compiler Component Data
*
* @since 3.2.0
*/
final class Data
{
/**
* Compiler Config
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* Compiler Event
*
* @var EventInterface
* @since 3.2.0
*/
protected EventInterface $event;
/**
* Compiler Placeholder
*
* @var Placeholder
* @since 3.2.0
*/
protected Placeholder $placeholder;
/**
* Compiler Component Placeholder
*
* @var ComponentPlaceholder
* @since 3.2.0
**/
protected ComponentPlaceholder $componentPlaceholder;
/**
* Compiler Customcode Dispenser
*
* @var Dispenser
* @since 3.2.0
*/
protected Dispenser $dispenser;
/**
* Compiler Customcode
*
* @var Customcode
* @since 3.2.0
*/
protected Customcode $customcode;
/**
* Compiler Customcode in Gui
*
* @var Gui
* @since 3.2.0
**/
protected Gui $gui;
/**
* Compiler Field
*
* @var Field
* @since 3.2.0
*/
protected Field $field;
/**
* Compiler field name
*
* @var FieldName
* @since 3.2.0
*/
protected FieldName $fieldName;
/**
* Compiler Field Unique Name
*
* @var UniqueName
* @since 3.2.0
**/
protected UniqueName $uniqueName;
/**
* Compiler Files Folders
*
* @var Filesfolders
* @since 3.2.0
*/
protected Filesfolders $filesFolders;
/**
* The modelling component history
*
* @var Historycomponent
* @since 3.2.0
*/
protected Historycomponent $history;
/**
* The modelling whmcs
*
* @var Whmcs
* @since 3.2.0
*/
protected Whmcs $whmcs;
/**
* The modelling Sql Tweaking
*
* @var Sqltweaking
* @since 3.2.0
*/
protected Sqltweaking $sqltweaking;
/**
* The modelling Admin Views
*
* @var Adminviews
* @since 3.2.0
*/
protected Adminviews $adminviews;
/**
* The modelling Site Views
*
* @var Siteviews
* @since 3.2.0
*/
protected Siteviews $siteviews;
/**
* The modelling Custom Admin Views
*
* @var Customadminviews
* @since 3.2.0
*/
protected Customadminviews $customadminviews;
/**
* The modelling Update Server
*
* @var Updateserver
* @since 3.2.0
*/
protected Updateserver $updateserver;
/**
* The modelling Joomla Modules
*
* @var Joomlamodules
* @since 3.2.0
*/
protected Joomlamodules $modules;
/**
* The modelling Joomla Plugins
*
* @var Joomlaplugins
* @since 3.2.0
*/
protected Joomlaplugins $plugins;
/**
* The modelling Joomla Site Router
*
* @var Router
* @since 3.2.0
*/
protected Router $router;
/**
* Database object to query local DB
*
* @since 3.2.0
**/
protected $db;
/**
* Constructor
*
* @param Config|null $config The compiler config object.
* @param EventInterface|null $event The compiler event api object.
* @param Placeholder|null $placeholder The compiler placeholder object.
* @param ComponentPlaceholder|null $componentPlaceholder The compiler component placeholder object.
* @param Dispenser|null $dispenser The compiler customcode dispenser object.
* @param Customcode|null $customcode The compiler customcode object.
* @param Gui|null $gui The compiler customcode gui.
* @param Field|null $field The compiler field object.
* @param FieldName|null $fieldName The compiler field name object.
* @param UniqueName|null $uniqueName The compiler field unique name object.
* @param Filesfolders|null $filesFolders The compiler files folders object.
* @param Historycomponent|null $history The modelling component history object.
* @param Whmcs|null $whmcs The modelling whmcs object.
* @param Sqltweaking|null $sqltweaking The modelling sql tweaking object.
* @param Adminviews|null $adminviews The modelling adminviews object.
* @param Siteviews|null $siteviews The modelling siteviews object.
* @param Customadminviews|null $customadminviews The modelling customadminviews object.
* @param Updateserver|null $updateserver The modelling update server object.
* @param Joomlamodules|null $modules The modelling modules object.
* @param Joomlaplugins|null $plugins The modelling plugins object.
* @param Router|null $router The modelling router object.
*
* @since 3.2.0
*/
public function __construct(?Config $config = null, ?EventInterface $event = null,
?Placeholder $placeholder = null, ?ComponentPlaceholder $componentPlaceholder = null,
?Dispenser $dispenser = null, ?Customcode $customcode = null, ?Gui $gui = null,
?Field $field = null, ?FieldName $fieldName = null, ?UniqueName $uniqueName = null,
?Filesfolders $filesFolders = null, ?Historycomponent $history = null, ?Whmcs $whmcs = null,
?Sqltweaking $sqltweaking = null, ?Adminviews $adminviews = null, ?Siteviews $siteviews = null,
?Customadminviews $customadminviews = null, ?Updateserver $updateserver = null,
?Joomlamodules $modules = null, ?Joomlaplugins $plugins = null, ?Router $router = null)
{
$this->config = $config ?: Compiler::_('Config');
$this->event = $event ?: Compiler::_('Event');
$this->placeholder = $placeholder ?: Compiler::_('Placeholder');
$this->componentPlaceholder = $componentPlaceholder ?: Compiler::_('Component.Placeholder');
$this->dispenser = $dispenser ?: Compiler::_('Customcode.Dispenser');
$this->customcode = $customcode ?: Compiler::_('Customcode');
$this->gui = $gui ?: Compiler::_('Customcode.Gui');
$this->field = $field ?: Compiler::_('Field');
$this->fieldName = $fieldName ?: Compiler::_('Field.Name');
$this->uniqueName = $uniqueName ?: Compiler::_('Field.Unique.Name');
$this->filesFolders = $filesFolders ?: Compiler::_('Model.Filesfolders');
$this->history = $history ?: Compiler::_('Model.Historycomponent');
$this->whmcs = $whmcs ?: Compiler::_('Model.Whmcs');
$this->sqltweaking = $sqltweaking ?: Compiler::_('Model.Sqltweaking');
$this->adminviews = $adminviews ?: Compiler::_('Model.Adminviews');
$this->siteviews = $siteviews ?: Compiler::_('Model.Siteviews');
$this->customadminviews = $customadminviews ?: Compiler::_('Model.Customadminviews');
$this->updateserver = $updateserver ?: Compiler::_('Model.Updateserver');
$this->modules = $modules ?: Compiler::_('Model.Joomlamodules');
$this->plugins = $plugins ?: Compiler::_('Model.Joomlaplugins');
$this->router = $router ?: Compiler::_('Model.Router');
$this->db = Factory::getDbo();
}
/**
* get current component data
*
* @return object|null The component data
* @since 3.2.0
*/
public function get(): ?object
{
// Create a new query object.
$query = $this->db->getQuery(true);
// selection
$selection = [
'b.addadmin_views' => 'addadmin_views',
'b.id' => 'addadmin_views_id',
'h.addconfig' => 'addconfig',
'd.addcustom_admin_views' => 'addcustom_admin_views',
'g.addcustommenus' => 'addcustommenus',
'j.addfiles' => 'addfiles',
'j.addfolders' => 'addfolders',
'j.addfilesfullpath' => 'addfilesfullpath',
'j.addfoldersfullpath' => 'addfoldersfullpath',
'c.addsite_views' => 'addsite_views',
'l.addjoomla_plugins' => 'addjoomla_plugins',
'k.addjoomla_modules' => 'addjoomla_modules',
'i.dashboard_tab' => 'dashboard_tab',
'i.php_dashboard_methods' => 'php_dashboard_methods',
'i.params' => 'dashboard_params',
'i.id' => 'component_dashboard_id',
'f.sql_tweak' => 'sql_tweak',
'e.version_update' => 'version_update',
'e.id' => 'version_update_id',
'm.mode_constructor_before_parent' => 'router_mode_constructor_before_parent',
'm.mode_constructor_after_parent' => 'router_mode_constructor_after_parent',
'm.mode_methods' => 'router_mode_methods',
'm.constructor_before_parent_code' => 'router_constructor_before_parent_code',
'm.constructor_before_parent_manual' => 'router_constructor_before_parent_manual',
'm.constructor_after_parent_code' => 'router_constructor_after_parent_code',
'm.methods_code' => 'router_methods_code'
];
$query->select('a.*');
$query->select(
$this->db->quoteName(
array_keys($selection), array_values($selection)
)
);
// from this table
$query->from('#__componentbuilder_joomla_component AS a');
// jointer-map
$joiners = [
'b' => 'component_admin_views',
'c' => 'component_site_views',
'd' => 'component_custom_admin_views',
'e' => 'component_updates',
'f' => 'component_mysql_tweaks',
'g' => 'component_custom_admin_menus',
'h' => 'component_config',
'i' => 'component_dashboard',
'j' => 'component_files_folders',
'k' => 'component_modules',
'l' => 'component_plugins',
'm' => 'component_router'
];
// load the joins
foreach ($joiners as $as => $join)
{
$query->join(
'LEFT',
$this->db->quoteName('#__componentbuilder_' . $join, $as)
. ' ON (' . $this->db->quoteName('a.id') . ' = '
. $this->db->quoteName($as . '.joomla_component') . ')'
);
}
$query->where(
$this->db->quoteName('a.id') . ' = ' . (int) $this->config->component_id
);
// Trigger Event: jcb_ce_onBeforeQueryComponentData
$this->event->trigger(
'jcb_ce_onBeforeQueryComponentData', [&$query, &$this->db]
);
// Reset the query using our newly populated query object.
$this->db->setQuery($query);
// Load the results as a list of stdClass objects
$component = $this->db->loadObject();
// make sure we got a component loaded
if (!is_object($component) || !isset($component->system_name))
{
return null;
}
// Trigger Event: jcb_ce_onBeforeModelComponentData
$this->event->trigger(
'jcb_ce_onBeforeModelComponentData', [&$component]
);
// load the global placeholders
$this->placeholder->active = $this->componentPlaceholder->get();
// set component sales name
$component->sales_name = StringHelper::safe(
$component->system_name
);
// set the component name_code
$component->name_code = StringHelper::safe(
$component->name_code
);
// ensure version naming is correct
$this->config->set('component_version', preg_replace(
'/^v/i', '', (string) $component->component_version
)
);
// set the website and autor for global use (default to VDM if not found)
$this->config->set('project_website', $component->website ?? 'https://dev.vdm.io');
$this->config->set('project_author', $component->author ?? 'VDM');
// set the files and folders
$this->filesFolders->set($component);
// set the uikit switch
$this->config->set('uikit', $component->adduikit);
// set whmcs links if needed
$this->whmcs->set($component);
// set the footable switch
if ($component->addfootable > 0)
{
// force add footable
$this->config->set('footable', true);
// add the version
$this->config->set('footable_version', (3 == $component->addfootable) ? 3 : 2);
}
// set the addcustommenus data
$component->addcustommenus = (isset($component->addcustommenus)
&& JsonHelper::check($component->addcustommenus))
? json_decode((string) $component->addcustommenus, true) : null;
if (ArrayHelper::check($component->addcustommenus))
{
$component->custommenus = array_values($component->addcustommenus);
}
unset($component->addcustommenus);
// set the sql tweak data
$this->sqltweaking->set($component);
// set the admin view data
$this->adminviews->set($component);
// set the site view data
$this->siteviews->set($component);
// set the custom_admin_views data
$this->customadminviews->set($component);
// set the config data
$component->addconfig = (isset($component->addconfig)
&& JsonHelper::check($component->addconfig))
? json_decode((string) $component->addconfig, true) : null;
if (ArrayHelper::check($component->addconfig))
{
$component->config = array_map(
function ($field) {
// make sure the alias and title is 0
$field['alias'] = 0;
$field['title'] = 0;
// set the field details
$this->field->set($field);
// set unique name counter
$this->uniqueName->set($field['base_name'], 'configs');
// return field
return $field;
}, array_values($component->addconfig)
);
// do some house cleaning (for fields)
foreach ($component->config as $field)
{
// so first we lock the field name in
$this->fieldName->get($field, 'configs');
}
// unset original value
unset($component->addconfig);
}
// set the add contributors
$component->addcontributors = (isset($component->addcontributors)
&& JsonHelper::check($component->addcontributors))
? json_decode((string) $component->addcontributors, true) : null;
if (ArrayHelper::check($component->addcontributors))
{
$this->config->set('add_contributors', true);
$component->contributors = array_values(
$component->addcontributors
);
}
unset($component->addcontributors);
// set the version updates
$this->updateserver->set($component);
// build the build date
if ($this->config->get('add_build_date', 1) == 3)
{
if (empty($this->component->modified) ||
$this->component->modified == '0000-00-00' ||
$this->component->modified == '0000-00-00 00:00:00')
{
$this->config->set('build_date', $this->component->created);
}
else
{
$this->config->set('build_date', $this->component->modified);
}
}
// build update SQL
$this->history->set($component);
// set GUI mapper
$guiMapper = [
'table' => 'joomla_component',
'id' => (int) $this->config->component_id,
'field' => 'javascript',
'type' => 'js'
];
// add_javascript
if ($component->add_javascript == 1)
{
$this->dispenser->set(
$component->javascript,
'component_js',
null,
null,
$guiMapper
);
}
else
{
$this->dispenser->hub['component_js'] = '';
}
unset($component->javascript);
// add global CSS
$addGlobalCss = ['admin', 'site'];
foreach ($addGlobalCss as $area)
{
// add_css if found
if (isset($component->{'add_css_' . $area})
&& $component->{'add_css_' . $area} == 1
&& isset($component->{'css_' . $area})
&& StringHelper::check(
$component->{'css_' . $area}
))
{
$this->dispenser->set(
$component->{'css_' . $area},
'component_css_' . $area
);
}
else
{
$this->dispenser->hub['component_css_' . $area] = '';
}
unset($component->{'css_' . $area});
}
// set the lang target
$this->config->lang_target = 'admin';
// add PHP in ADMIN
$addScriptMethods = [
'php_preflight',
'php_postflight',
'php_method'
];
$addScriptTypes = [
'install',
'update',
'uninstall'
];
// update GUI mapper
$guiMapper['type'] = 'php';
foreach ($addScriptMethods as $scriptMethod)
{
foreach ($addScriptTypes as $scriptType)
{
if (isset($component->{'add_' . $scriptMethod . '_' . $scriptType})
&& $component->{'add_' . $scriptMethod . '_' . $scriptType} == 1
&& StringHelper::check(
$component->{$scriptMethod . '_' . $scriptType}
))
{
// set GUI mapper field
$guiMapper['field'] = $scriptMethod . '_' . $scriptType;
$this->dispenser->set(
$component->{$scriptMethod . '_' . $scriptType},
$scriptMethod,
$scriptType,
null,
$guiMapper
);
}
else
{
$this->dispenser->hub[$scriptMethod][$scriptType] = '';
}
unset($component->{$scriptMethod . '_' . $scriptType});
}
}
// add_php_helper
if ($component->add_php_helper_admin == 1
&& StringHelper::check(
$component->php_helper_admin
))
{
$this->config->lang_target = 'admin';
// update GUI mapper
$guiMapper['field'] = 'php_helper_admin';
$guiMapper['prefix'] = PHP_EOL . PHP_EOL;
$this->dispenser->set(
$component->php_helper_admin,
'component_php_helper_admin',
null,
null,
$guiMapper
);
unset($guiMapper['prefix']);
}
else
{
$this->dispenser->hub['component_php_helper_admin'] = '';
}
unset($component->php_helper);
// add_admin_event
if ($component->add_admin_event == 1
&& StringHelper::check($component->php_admin_event))
{
$this->config->lang_target = 'admin';
// update GUI mapper field
$guiMapper['field'] = 'php_admin_event';
$this->dispenser->set(
$component->php_admin_event,
'component_php_admin_event',
null,
null,
$guiMapper
);
}
else
{
$this->dispenser->hub['component_php_admin_event'] = '';
}
unset($component->php_admin_event);
// add_php_helper_both
if ($component->add_php_helper_both == 1
&& StringHelper::check($component->php_helper_both))
{
$this->config->lang_target = 'both';
// update GUI mapper field
$guiMapper['field'] = 'php_helper_both';
$guiMapper['prefix'] = PHP_EOL . PHP_EOL;
$this->dispenser->set(
$component->php_helper_both,
'component_php_helper_both',
null,
null,
$guiMapper
);
unset($guiMapper['prefix']);
}
else
{
$this->dispenser->hub['component_php_helper_both'] = '';
}
// add_php_helper_site
if ($component->add_php_helper_site == 1
&& StringHelper::check($component->php_helper_site))
{
$this->config->lang_target = 'site';
// update GUI mapper field
$guiMapper['field'] = 'php_helper_site';
$guiMapper['prefix'] = PHP_EOL . PHP_EOL;
$this->dispenser->set(
$component->php_helper_site,
'component_php_helper_site',
null,
null,
$guiMapper
);
unset($guiMapper['prefix']);
}
else
{
$this->dispenser->hub['component_php_helper_site'] = '';
}
unset($component->php_helper);
// add_site_event
if ($component->add_site_event == 1
&& StringHelper::check($component->php_site_event))
{
$this->config->lang_target = 'site';
// update GUI mapper field
$guiMapper['field'] = 'php_site_event';
$this->dispenser->set(
$component->php_site_event,
'component_php_site_event',
null,
null,
$guiMapper
);
}
else
{
$this->dispenser->hub['component_php_site_event'] = '';
}
unset($component->php_site_event);
// add_sql
if ($component->add_sql == 1)
{
$this->dispenser->set(
$component->sql,
'sql',
'component_sql'
);
}
unset($component->sql);
// add_sql_uninstall
if ($component->add_sql_uninstall == 1)
{
$this->dispenser->set(
$component->sql_uninstall,
'sql_uninstall'
);
}
unset($component->sql_uninstall);
// bom
if (StringHelper::check($component->bom))
{
$this->config->set('bom_path',
$this->config->get('compiler_path', JPATH_COMPONENT_ADMINISTRATOR . '/compiler') . '/' . $component->bom
);
}
unset($component->bom);
// README
$component->readme =
$component->addreadme ?
$this->customcode->update(
base64_decode((string) $component->readme)
) : '';
// set lang now
$nowLang = $this->config->lang_target;
$this->config->lang_target = 'admin';
// dashboard methods
$component->dashboard_tab = (isset($component->dashboard_tab)
&& JsonHelper::check($component->dashboard_tab))
? json_decode((string) $component->dashboard_tab, true) : null;
if (ArrayHelper::check($component->dashboard_tab))
{
$component->dashboard_tab = array_map(
function ($array) {
$array['html'] = $this->customcode->update($array['html']);
return $array;
}, array_values($component->dashboard_tab)
);
}
else
{
$component->dashboard_tab = '';
}
// add the php of the dashboard if set
if (isset($component->php_dashboard_methods)
&& StringHelper::check(
$component->php_dashboard_methods
))
{
// load the php for the dashboard model
$component->php_dashboard_methods = $this->gui->set(
$this->customcode->update(
base64_decode((string) $component->php_dashboard_methods)
),
[
'table' => 'component_dashboard',
'field' => 'php_dashboard_methods',
'id' => (int) $component->component_dashboard_id,
'type' => 'php'
]
);
}
else
{
$component->php_dashboard_methods = '';
}
// reset back to now lang
$this->config->lang_target = $nowLang;
// catch empty URL to update server TODO: we need to fix this in better way later
if (empty($component->add_update_server) || ($component->add_update_server == 1 && $component->update_server_target != 3
&& (
!StringHelper::check($component->update_server_url)
|| strpos($component->update_server_url, 'http') === false
)))
{
// we fall back to other, since we can't work with an empty update server URL
$component->add_update_server = 0;
$component->update_server_target = 3;
$component->update_server_url = '';
}
// add the update/sales server FTP details if that is the expected protocol
$serverArray = array('update_server', 'sales_server');
foreach ($serverArray as $server)
{
if ($component->{'add_' . $server} == 1
&& is_numeric($component->{$server})
&& $component->{$server} > 0)
{
// get the server protocol
$component->{$server . '_protocol'}
= GetHelper::var(
'server', (int) $component->{$server}, 'id', 'protocol'
);
}
else
{
$component->{$server} = 0;
// only change this for sales server (update server can be added loacaly to the zip file)
if ('sales_server' === $server)
{
$component->{'add_' . $server} = 0;
}
$component->{$server . '_protocol'} = 0;
}
}
// set the ignore folders for repo if found
if (isset($component->toignore)
&& StringHelper::check(
$component->toignore
))
{
if (strpos((string) $component->toignore, ',') !== false)
{
$component->toignore = array_map(
'trim', (array) explode(',', (string) $component->toignore)
);
}
else
{
$component->toignore = array(trim((string) $component->toignore));
}
}
else
{
// the default is to ignore the repo folder
$component->toignore = array('.git');
}
// set all modules
$this->modules->set($component);
// set all plugins
$this->plugins->set($component);
// set the site router
$this->router->set($component);
// Trigger Event: jcb_ce_onAfterModelComponentData
$this->event->trigger(
'jcb_ce_onAfterModelComponentData',
[&$component]
);
// return found component data
return $component;
}
}

View File

@@ -0,0 +1,748 @@
<?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\Component\JoomlaFive;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Dynamicpath;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Pathfix;
use VDM\Joomla\Utilities\FileHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component\SettingsInterface;
/**
* Compiler Component (Joomla Version) Settings
*
* @since 3.2.0
*/
final class Settings implements SettingsInterface
{
/**
* The standard folders
*
* @var array
* @since 3.2.0
*/
protected array $standardFolders = [
'site',
'admin',
'media'
];
/**
* The standard root files
*
* @var array
* @since 3.2.0
*/
protected array $standardRootFiles = [
'access.xml',
'config.xml',
'controller.php',
'index.html',
'README.txt'
];
/**
* Compiler Joomla Version Data
*
* @var object|null
* @since 3.2.0
*/
protected ?object $data = null;
/**
* 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 Placeholder
*
* @var Placeholder
* @since 3.2.0
*/
protected Placeholder $placeholder;
/**
* Compiler Component
*
* @var Component
* @since 3.2.0
**/
protected Component $component;
/**
* Compiler Utilities Paths
*
* @var Paths
* @since 3.2.0
*/
protected Paths $paths;
/**
* Compiler Component Dynamic Path
*
* @var Dynamicpath
* @since 3.2.0
**/
protected Dynamicpath $dynamicpath;
/**
* Compiler Component Pathfix
*
* @var Pathfix
* @since 3.2.0
**/
protected Pathfix $pathfix;
/**
* Constructor
*
* @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 Placeholder|null $placeholder The compiler placeholder object.
* @param Component|null $component The component class.
* @param Paths|null $paths The compiler paths object.
* @param Dynamicpath|null $dynamicpath The compiler dynamic path object.
* @param Pathfix|null $pathfix The compiler path fixing object.
*
* @since 3.2.0
*/
public function __construct(?Config $config = null, ?Registry $registry = null,
?EventInterface $event = null, ?Placeholder $placeholder = null,
?Component $component = null, ?Paths $paths = null,
?Dynamicpath $dynamicpath = null, ?Pathfix $pathfix = null)
{
$this->config = $config ?: Compiler::_('Config');
$this->registry = $registry ?: Compiler::_('Registry');
$this->event = $event ?: Compiler::_('Event');
$this->placeholder = $placeholder ?: Compiler::_('Placeholder');
$this->component = $component ?: Compiler::_('Component');
$this->paths = $paths ?: Compiler::_('Utilities.Paths');
$this->dynamicpath = $dynamicpath ?: Compiler::_('Utilities.Dynamicpath');
$this->pathfix = $pathfix ?: Compiler::_('Utilities.Pathfix');
// add component endpoint file to stander list of root files
$this->standardRootFiles[] = $this->component->get('name_code') . '.php';
}
/**
* Check if data set is loaded
*
* @return bool
* @since 3.2.0
*/
public function exists(): bool
{
if (!$this->isSet())
{
// load the data
$this->data = $this->get();
if (!$this->isSet())
{
return false;
}
}
return true;
}
/**
* Get Joomla - Folder Structure to Create
*
* @return object The version related structure
* @since 3.2.0
*/
public function structure(): object
{
return $this->data->create;
}
/**
* Get Joomla - Move Multiple Structure
*
* @return object The version related multiple structure
* @since 3.2.0
*/
public function multiple(): object
{
return $this->data->move->dynamic;
}
/**
* Get Joomla - Move Single Structure
*
* @return object The version related single structure
* @since 3.2.0
*/
public function single(): object
{
return $this->data->move->static;
}
/**
* Check if Folder is a Standard Folder
*
* @param string $folder The folder name
*
* @return bool true if the folder exists
* @since 3.2.0
*/
public function standardFolder(string $folder): bool
{
return in_array($folder, $this->standardFolders);
}
/**
* Check if File is a Standard Root File
*
* @param string $file The file name
*
* @return bool true if the file exists
* @since 3.2.0
*/
public function standardRootFile(string $file): bool
{
return in_array($file, $this->standardRootFiles);
}
/**
* Check if Data is Set
*
* @return bool
* @since 3.2.0
*/
private function isSet(): bool
{
return is_object($this->data) &&
isset($this->data->create) &&
isset($this->data->move) &&
isset($this->data->move->static) &&
isset($this->data->move->dynamic);
}
/**
* get the Joomla Version Data
*
* @return object|null The version data
* @since 3.2.0
*/
private function get(): ?object
{
// override option
$customSettings = $this->paths->template_path . '/settings_' .
$this->config->component_code_name . '.json';
// get the data
$version_data = $this->readJsonFile($customSettings);
if (is_null($version_data) || !$this->isValidData($version_data))
{
return null;
}
$this->loadExtraFolders();
$this->loadExtraFiles();
$this->addFolders($version_data);
$this->addFiles($version_data);
// Trigger Event: jcb_ce_onAfterSetJoomlaVersionData
$this->event->trigger(
'jcb_ce_onAfterSetJoomlaVersionData', [&$version_data]
);
return $version_data;
}
/**
* Read the Json file data
*
* @param string $filePath
*
* @return object|null The version data
* @since 3.2.0
*/
private function readJsonFile(string $filePath): ?object
{
if (FileHelper::exists($filePath))
{
$jsonContent = FileHelper::getContent($filePath);
}
else
{
$jsonContent = FileHelper::getContent($this->paths->template_path . '/settings.json');
}
if (JsonHelper::check($jsonContent))
{
return json_decode((string) $jsonContent);
}
return null;
}
/**
* Check if this is valid data
*
* @param object $versionData
*
* @return bool
* @since 3.2.0
*/
private function isValidData(object $versionData): bool
{
return isset($versionData->create) &&
isset($versionData->move) &&
isset($versionData->move->static) &&
isset($versionData->move->dynamic);
}
/**
* Add Extra/Dynamic folders
*
* @return void
* @since 3.2.0
*/
private function loadExtraFolders()
{
if ($this->component->isArray('folders') ||
$this->config->get('add_eximport', false) ||
$this->config->get('uikit', 0) ||
$this->config->get('footable', false))
{
$this->addImportViewFolder();
$this->addPhpSpreadsheetFolder();
$this->addUikitFolder();
$this->addFooTableFolder();
}
}
/**
* Add Import and Export Folder
*
* @return void
* @since 3.2.0
*/
private function addImportViewFolder()
{
if ($this->config->get('add_eximport', false))
{
// soon
}
}
/**
* Add Php Spreadsheet Folder
*
* @return void
* @since 3.2.0
*/
private function addPhpSpreadsheetFolder()
{
// move the phpspreadsheet Folder (TODO we must move this to a library package)
if ($this->config->get('add_eximport', false))
{
$this->component->appendArray('folders', [
'folderpath' => 'JPATH_LIBRARIES/phpspreadsheet/vendor',
'path' => '/libraries/phpspreadsheet/',
'rename' => 0
]);
}
}
/**
* Add Uikit Folders
*
* @return void
* @since 3.2.0
*/
private function addUikitFolder()
{
$uikit = $this->config->get('uikit', 0);
if (2 == $uikit || 1 == $uikit)
{
// move the UIKIT Folder into place
$this->component->appendArray('folders', [
'folder' => 'uikit-v2',
'path' => 'media',
'rename' => 0
]);
}
if (2 == $uikit || 3 == $uikit)
{
// move the UIKIT-3 Folder into place
$this->component->appendArray('folders', [
'folder' => 'uikit-v3',
'path' => 'media',
'rename' => 0
]);
}
}
/**
* Add Foo Table Folder
*
* @return void
* @since 3.2.0
*/
private function addFooTableFolder()
{
if (!$this->config->get('footable', false))
{
return;
}
$footable_version = $this->config->get('footable_version', 2);
if (2 == $footable_version)
{
// move the footable folder into place
$this->component->appendArray('folders', [
'folder' => 'footable-v2',
'path' => 'media',
'rename' => 0
]);
}
elseif (3 == $footable_version)
{
// move the footable folder into place
$this->component->appendArray('folders', [
'folder' => 'footable-v3',
'path' => 'media',
'rename' => 0
]);
}
}
/**
* Add Extra/Dynamic files
*
* @return void
* @since 3.2.0
*/
private function loadExtraFiles()
{
if ($this->component->isArray('files') ||
$this->config->get('google_chart', false))
{
$this->addGoogleChartFiles();
}
}
/**
* Add Google Chart Files
*
* @return void
* @since 3.2.0
*/
private function addGoogleChartFiles()
{
if ($this->config->get('google_chart', false))
{
// move the google chart files
$this->component->appendArray('files', [
'file' => 'google.jsapi.js',
'path' => 'media/js',
'rename' => 0
]);
$this->component->appendArray('files', [
'file' => 'chartbuilder.php',
'path' => 'admin/helpers',
'rename' => 0
]);
}
}
/**
* Add Folders
*
* @param object $versionData
*
* @return void
* @since 3.2.0
*/
private function addFolders(object &$versionData)
{
if (!$this->component->isArray('folders'))
{
return;
}
// pointer tracker
$pointer_tracker = 'h';
foreach ($this->component->get('folders') as $custom)
{
// check type of target type
$_target_type = 'c0mp0n3nt';
if (isset($custom['target_type']))
{
$_target_type = $custom['target_type'];
}
// for good practice
$this->pathfix->set(
$custom, ['path', 'folder', 'folderpath']
);
// fix custom path
if (isset($custom['path'])
&& StringHelper::check($custom['path']))
{
$custom['path'] = trim((string) $custom['path'], '/');
}
// by default custom path is true
$customPath = 'custom';
// set full path if this is a full path folder
if (!isset($custom['folder']) && isset($custom['folderpath']))
{
// update the dynamic path
$custom['folderpath'] = $this->dynamicpath->update(
$custom['folderpath']
);
// set the folder path with / if does not have a drive/windows full path
$custom['folder'] = (preg_match(
'/^[a-z]:/i', $custom['folderpath']
)) ? trim($custom['folderpath'], '/')
: '/' . trim($custom['folderpath'], '/');
// remove the file path
unset($custom['folderpath']);
// triget fullpath
$customPath = 'full';
}
// make sure we use the correct name
$pathArray = (array) explode('/', (string) $custom['path']);
$lastFolder = end($pathArray);
// only rename folder if last has folder name
if (isset($custom['rename']) && $custom['rename'] == 1)
{
$custom['path'] = str_replace(
'/' . $lastFolder, '', (string) $custom['path']
);
$rename = 'new';
$newname = $lastFolder;
}
elseif ('full' === $customPath)
{
// make sure we use the correct name
$folderArray = (array) explode('/', (string) $custom['folder']);
$lastFolder = end($folderArray);
$rename = 'new';
$newname = $lastFolder;
}
else
{
$rename = false;
$newname = '';
}
// insure we have no duplicates
$key_pointer = StringHelper::safe(
$custom['folder']
) . '_f' . $pointer_tracker;
$pointer_tracker++;
// fix custom path
$custom['path'] = ltrim((string) $custom['path'], '/');
// set new folder to object
$versionData->move->static->{$key_pointer} = new \stdClass();
$versionData->move->static->{$key_pointer}->naam = str_replace('//', '/', (string) $custom['folder']);
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = $rename;
$versionData->move->static->{$key_pointer}->newName = $newname;
$versionData->move->static->{$key_pointer}->type = 'folder';
$versionData->move->static->{$key_pointer}->custom = $customPath;
// set the target if type and id is found
if (isset($custom['target_id']) && isset($custom['target_type']))
{
$versionData->move->static->{$key_pointer}->_target = [
'key' => $custom['target_id'] . '_' . $custom['target_type'],
'type' => $custom['target_type']
];
}
}
$this->component->remove('folders');
}
/**
* Add Files
*
* @param object $versionData
*
* @return void
* @since 3.2.0
*/
private function addFiles(object &$versionData)
{
if (!$this->component->isArray('files')) {
return;
}
// pointer tracker
$pointer_tracker = 'h';
foreach ($this->component->get('files') as $custom)
{
// check type of target type
$_target_type = 'c0mp0n3nt';
if (isset($custom['target_type']))
{
$_target_type = $custom['target_type'];
}
// for good practice
$this->pathfix->set(
$custom, ['path', 'file', 'filepath']
);
// by default custom path is true
$customPath = 'custom';
// set full path if this is a full path file
if (!isset($custom['file']) && isset($custom['filepath']))
{
// update the dynamic path
$custom['filepath'] = $this->dynamicpath->update(
$custom['filepath']
);
// set the file path with / if does not have a drive/windows full path
$custom['file'] = (preg_match('/^[a-z]:/i', $custom['filepath']))
? trim($custom['filepath'], '/') : '/' . trim($custom['filepath'], '/');
// remove the file path
unset($custom['filepath']);
// triget fullpath
$customPath = 'full';
}
// make sure we have not duplicates
$key_pointer = StringHelper::safe(
$custom['file']
) . '_g' . $pointer_tracker;
$pointer_tracker++;
// set new file to object
$versionData->move->static->{$key_pointer} = new \stdClass();
$versionData->move->static->{$key_pointer}->naam = str_replace('//', '/', (string) $custom['file']);
// update the dynamic component name placholders in file names
$custom['path'] = $this->placeholder->update_(
$custom['path']
);
// get the path info
$pathInfo = pathinfo((string) $custom['path']);
if (isset($pathInfo['extension']) && $pathInfo['extension'])
{
$pathInfo['dirname'] = trim($pathInfo['dirname'], '/');
// set the info
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $pathInfo['dirname'];
$versionData->move->static->{$key_pointer}->rename = 'new';
$versionData->move->static->{$key_pointer}->newName = $pathInfo['basename'];
}
elseif ('full' === $customPath)
{
// fix custom path
$custom['path'] = ltrim((string) $custom['path'], '/');
// get file array
$fileArray = (array) explode('/', (string) $custom['file']);
// set the info
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = 'new';
$versionData->move->static->{$key_pointer}->newName = end($fileArray);
}
else
{
// fix custom path
$custom['path'] = ltrim((string) $custom['path'], '/');
// set the info
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = false;
}
$versionData->move->static->{$key_pointer}->type = 'file';
$versionData->move->static->{$key_pointer}->custom = $customPath;
// set the target if type and id is found
if (isset($custom['target_id'])
&& isset($custom['target_type']))
{
$versionData->move->static->{$key_pointer}->_target = [
'key' => $custom['target_id'] . '_' . $custom['target_type'],
'type' => $custom['target_type']
];
}
// check if file should be updated
if (!isset($custom['notnew']) || $custom['notnew'] == 0
|| $custom['notnew'] != 1)
{
$this->registry->appendArray('files.not.new', $key_pointer);
}
else
{
// update the file content
$this->registry->set('update.file.content.' . $key_pointer, true);
}
}
$this->component->remove('files');
}
}

View File

@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@@ -0,0 +1,748 @@
<?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\Component\JoomlaFour;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Dynamicpath;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Pathfix;
use VDM\Joomla\Utilities\FileHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component\SettingsInterface;
/**
* Compiler Component (Joomla Version) Settings
*
* @since 3.2.0
*/
final class Settings implements SettingsInterface
{
/**
* The standard folders
*
* @var array
* @since 3.2.0
*/
protected array $standardFolders = [
'site',
'admin',
'media'
];
/**
* The standard root files
*
* @var array
* @since 3.2.0
*/
protected array $standardRootFiles = [
'access.xml',
'config.xml',
'controller.php',
'index.html',
'README.txt'
];
/**
* Compiler Joomla Version Data
*
* @var object|null
* @since 3.2.0
*/
protected ?object $data = null;
/**
* 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 Placeholder
*
* @var Placeholder
* @since 3.2.0
*/
protected Placeholder $placeholder;
/**
* Compiler Component
*
* @var Component
* @since 3.2.0
**/
protected Component $component;
/**
* Compiler Utilities Paths
*
* @var Paths
* @since 3.2.0
*/
protected Paths $paths;
/**
* Compiler Component Dynamic Path
*
* @var Dynamicpath
* @since 3.2.0
**/
protected Dynamicpath $dynamicpath;
/**
* Compiler Component Pathfix
*
* @var Pathfix
* @since 3.2.0
**/
protected Pathfix $pathfix;
/**
* Constructor
*
* @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 Placeholder|null $placeholder The compiler placeholder object.
* @param Component|null $component The component class.
* @param Paths|null $paths The compiler paths object.
* @param Dynamicpath|null $dynamicpath The compiler dynamic path object.
* @param Pathfix|null $pathfix The compiler path fixing object.
*
* @since 3.2.0
*/
public function __construct(?Config $config = null, ?Registry $registry = null,
?EventInterface $event = null, ?Placeholder $placeholder = null,
?Component $component = null, ?Paths $paths = null,
?Dynamicpath $dynamicpath = null, ?Pathfix $pathfix = null)
{
$this->config = $config ?: Compiler::_('Config');
$this->registry = $registry ?: Compiler::_('Registry');
$this->event = $event ?: Compiler::_('Event');
$this->placeholder = $placeholder ?: Compiler::_('Placeholder');
$this->component = $component ?: Compiler::_('Component');
$this->paths = $paths ?: Compiler::_('Utilities.Paths');
$this->dynamicpath = $dynamicpath ?: Compiler::_('Utilities.Dynamicpath');
$this->pathfix = $pathfix ?: Compiler::_('Utilities.Pathfix');
// add component endpoint file to stander list of root files
$this->standardRootFiles[] = $this->component->get('name_code') . '.php';
}
/**
* Check if data set is loaded
*
* @return bool
* @since 3.2.0
*/
public function exists(): bool
{
if (!$this->isSet())
{
// load the data
$this->data = $this->get();
if (!$this->isSet())
{
return false;
}
}
return true;
}
/**
* Get Joomla - Folder Structure to Create
*
* @return object The version related structure
* @since 3.2.0
*/
public function structure(): object
{
return $this->data->create;
}
/**
* Get Joomla - Move Multiple Structure
*
* @return object The version related multiple structure
* @since 3.2.0
*/
public function multiple(): object
{
return $this->data->move->dynamic;
}
/**
* Get Joomla - Move Single Structure
*
* @return object The version related single structure
* @since 3.2.0
*/
public function single(): object
{
return $this->data->move->static;
}
/**
* Check if Folder is a Standard Folder
*
* @param string $folder The folder name
*
* @return bool true if the folder exists
* @since 3.2.0
*/
public function standardFolder(string $folder): bool
{
return in_array($folder, $this->standardFolders);
}
/**
* Check if File is a Standard Root File
*
* @param string $file The file name
*
* @return bool true if the file exists
* @since 3.2.0
*/
public function standardRootFile(string $file): bool
{
return in_array($file, $this->standardRootFiles);
}
/**
* Check if Data is Set
*
* @return bool
* @since 3.2.0
*/
private function isSet(): bool
{
return is_object($this->data) &&
isset($this->data->create) &&
isset($this->data->move) &&
isset($this->data->move->static) &&
isset($this->data->move->dynamic);
}
/**
* get the Joomla Version Data
*
* @return object|null The version data
* @since 3.2.0
*/
private function get(): ?object
{
// override option
$customSettings = $this->paths->template_path . '/settings_' .
$this->config->component_code_name . '.json';
// get the data
$version_data = $this->readJsonFile($customSettings);
if (is_null($version_data) || !$this->isValidData($version_data))
{
return null;
}
$this->loadExtraFolders();
$this->loadExtraFiles();
$this->addFolders($version_data);
$this->addFiles($version_data);
// Trigger Event: jcb_ce_onAfterSetJoomlaVersionData
$this->event->trigger(
'jcb_ce_onAfterSetJoomlaVersionData', [&$version_data]
);
return $version_data;
}
/**
* Read the Json file data
*
* @param string $filePath
*
* @return object|null The version data
* @since 3.2.0
*/
private function readJsonFile(string $filePath): ?object
{
if (FileHelper::exists($filePath))
{
$jsonContent = FileHelper::getContent($filePath);
}
else
{
$jsonContent = FileHelper::getContent($this->paths->template_path . '/settings.json');
}
if (JsonHelper::check($jsonContent))
{
return json_decode((string) $jsonContent);
}
return null;
}
/**
* Check if this is valid data
*
* @param object $versionData
*
* @return bool
* @since 3.2.0
*/
private function isValidData(object $versionData): bool
{
return isset($versionData->create) &&
isset($versionData->move) &&
isset($versionData->move->static) &&
isset($versionData->move->dynamic);
}
/**
* Add Extra/Dynamic folders
*
* @return void
* @since 3.2.0
*/
private function loadExtraFolders()
{
if ($this->component->isArray('folders') ||
$this->config->get('add_eximport', false) ||
$this->config->get('uikit', 0) ||
$this->config->get('footable', false))
{
$this->addImportViewFolder();
$this->addPhpSpreadsheetFolder();
$this->addUikitFolder();
$this->addFooTableFolder();
}
}
/**
* Add Import and Export Folder
*
* @return void
* @since 3.2.0
*/
private function addImportViewFolder()
{
if ($this->config->get('add_eximport', false))
{
// soon
}
}
/**
* Add Php Spreadsheet Folder
*
* @return void
* @since 3.2.0
*/
private function addPhpSpreadsheetFolder()
{
// move the phpspreadsheet Folder (TODO we must move this to a library package)
if ($this->config->get('add_eximport', false))
{
$this->component->appendArray('folders', [
'folderpath' => 'JPATH_LIBRARIES/phpspreadsheet/vendor',
'path' => '/libraries/phpspreadsheet/',
'rename' => 0
]);
}
}
/**
* Add Uikit Folders
*
* @return void
* @since 3.2.0
*/
private function addUikitFolder()
{
$uikit = $this->config->get('uikit', 0);
if (2 == $uikit || 1 == $uikit)
{
// move the UIKIT Folder into place
$this->component->appendArray('folders', [
'folder' => 'uikit-v2',
'path' => 'media',
'rename' => 0
]);
}
if (2 == $uikit || 3 == $uikit)
{
// move the UIKIT-3 Folder into place
$this->component->appendArray('folders', [
'folder' => 'uikit-v3',
'path' => 'media',
'rename' => 0
]);
}
}
/**
* Add Foo Table Folder
*
* @return void
* @since 3.2.0
*/
private function addFooTableFolder()
{
if (!$this->config->get('footable', false))
{
return;
}
$footable_version = $this->config->get('footable_version', 2);
if (2 == $footable_version)
{
// move the footable folder into place
$this->component->appendArray('folders', [
'folder' => 'footable-v2',
'path' => 'media',
'rename' => 0
]);
}
elseif (3 == $footable_version)
{
// move the footable folder into place
$this->component->appendArray('folders', [
'folder' => 'footable-v3',
'path' => 'media',
'rename' => 0
]);
}
}
/**
* Add Extra/Dynamic files
*
* @return void
* @since 3.2.0
*/
private function loadExtraFiles()
{
if ($this->component->isArray('files') ||
$this->config->get('google_chart', false))
{
$this->addGoogleChartFiles();
}
}
/**
* Add Google Chart Files
*
* @return void
* @since 3.2.0
*/
private function addGoogleChartFiles()
{
if ($this->config->get('google_chart', false))
{
// move the google chart files
$this->component->appendArray('files', [
'file' => 'google.jsapi.js',
'path' => 'media/js',
'rename' => 0
]);
$this->component->appendArray('files', [
'file' => 'chartbuilder.php',
'path' => 'admin/helpers',
'rename' => 0
]);
}
}
/**
* Add Folders
*
* @param object $versionData
*
* @return void
* @since 3.2.0
*/
private function addFolders(object &$versionData)
{
if (!$this->component->isArray('folders'))
{
return;
}
// pointer tracker
$pointer_tracker = 'h';
foreach ($this->component->get('folders') as $custom)
{
// check type of target type
$_target_type = 'c0mp0n3nt';
if (isset($custom['target_type']))
{
$_target_type = $custom['target_type'];
}
// for good practice
$this->pathfix->set(
$custom, ['path', 'folder', 'folderpath']
);
// fix custom path
if (isset($custom['path'])
&& StringHelper::check($custom['path']))
{
$custom['path'] = trim((string) $custom['path'], '/');
}
// by default custom path is true
$customPath = 'custom';
// set full path if this is a full path folder
if (!isset($custom['folder']) && isset($custom['folderpath']))
{
// update the dynamic path
$custom['folderpath'] = $this->dynamicpath->update(
$custom['folderpath']
);
// set the folder path with / if does not have a drive/windows full path
$custom['folder'] = (preg_match(
'/^[a-z]:/i', $custom['folderpath']
)) ? trim($custom['folderpath'], '/')
: '/' . trim($custom['folderpath'], '/');
// remove the file path
unset($custom['folderpath']);
// triget fullpath
$customPath = 'full';
}
// make sure we use the correct name
$pathArray = (array) explode('/', (string) $custom['path']);
$lastFolder = end($pathArray);
// only rename folder if last has folder name
if (isset($custom['rename']) && $custom['rename'] == 1)
{
$custom['path'] = str_replace(
'/' . $lastFolder, '', (string) $custom['path']
);
$rename = 'new';
$newname = $lastFolder;
}
elseif ('full' === $customPath)
{
// make sure we use the correct name
$folderArray = (array) explode('/', (string) $custom['folder']);
$lastFolder = end($folderArray);
$rename = 'new';
$newname = $lastFolder;
}
else
{
$rename = false;
$newname = '';
}
// insure we have no duplicates
$key_pointer = StringHelper::safe(
$custom['folder']
) . '_f' . $pointer_tracker;
$pointer_tracker++;
// fix custom path
$custom['path'] = ltrim((string) $custom['path'], '/');
// set new folder to object
$versionData->move->static->{$key_pointer} = new \stdClass();
$versionData->move->static->{$key_pointer}->naam = str_replace('//', '/', (string) $custom['folder']);
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = $rename;
$versionData->move->static->{$key_pointer}->newName = $newname;
$versionData->move->static->{$key_pointer}->type = 'folder';
$versionData->move->static->{$key_pointer}->custom = $customPath;
// set the target if type and id is found
if (isset($custom['target_id']) && isset($custom['target_type']))
{
$versionData->move->static->{$key_pointer}->_target = [
'key' => $custom['target_id'] . '_' . $custom['target_type'],
'type' => $custom['target_type']
];
}
}
$this->component->remove('folders');
}
/**
* Add Files
*
* @param object $versionData
*
* @return void
* @since 3.2.0
*/
private function addFiles(object &$versionData)
{
if (!$this->component->isArray('files')) {
return;
}
// pointer tracker
$pointer_tracker = 'h';
foreach ($this->component->get('files') as $custom)
{
// check type of target type
$_target_type = 'c0mp0n3nt';
if (isset($custom['target_type']))
{
$_target_type = $custom['target_type'];
}
// for good practice
$this->pathfix->set(
$custom, ['path', 'file', 'filepath']
);
// by default custom path is true
$customPath = 'custom';
// set full path if this is a full path file
if (!isset($custom['file']) && isset($custom['filepath']))
{
// update the dynamic path
$custom['filepath'] = $this->dynamicpath->update(
$custom['filepath']
);
// set the file path with / if does not have a drive/windows full path
$custom['file'] = (preg_match('/^[a-z]:/i', $custom['filepath']))
? trim($custom['filepath'], '/') : '/' . trim($custom['filepath'], '/');
// remove the file path
unset($custom['filepath']);
// triget fullpath
$customPath = 'full';
}
// make sure we have not duplicates
$key_pointer = StringHelper::safe(
$custom['file']
) . '_g' . $pointer_tracker;
$pointer_tracker++;
// set new file to object
$versionData->move->static->{$key_pointer} = new \stdClass();
$versionData->move->static->{$key_pointer}->naam = str_replace('//', '/', (string) $custom['file']);
// update the dynamic component name placholders in file names
$custom['path'] = $this->placeholder->update_(
$custom['path']
);
// get the path info
$pathInfo = pathinfo((string) $custom['path']);
if (isset($pathInfo['extension']) && $pathInfo['extension'])
{
$pathInfo['dirname'] = trim($pathInfo['dirname'], '/');
// set the info
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $pathInfo['dirname'];
$versionData->move->static->{$key_pointer}->rename = 'new';
$versionData->move->static->{$key_pointer}->newName = $pathInfo['basename'];
}
elseif ('full' === $customPath)
{
// fix custom path
$custom['path'] = ltrim((string) $custom['path'], '/');
// get file array
$fileArray = (array) explode('/', (string) $custom['file']);
// set the info
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = 'new';
$versionData->move->static->{$key_pointer}->newName = end($fileArray);
}
else
{
// fix custom path
$custom['path'] = ltrim((string) $custom['path'], '/');
// set the info
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = false;
}
$versionData->move->static->{$key_pointer}->type = 'file';
$versionData->move->static->{$key_pointer}->custom = $customPath;
// set the target if type and id is found
if (isset($custom['target_id'])
&& isset($custom['target_type']))
{
$versionData->move->static->{$key_pointer}->_target = [
'key' => $custom['target_id'] . '_' . $custom['target_type'],
'type' => $custom['target_type']
];
}
// check if file should be updated
if (!isset($custom['notnew']) || $custom['notnew'] == 0
|| $custom['notnew'] != 1)
{
$this->registry->appendArray('files.not.new', $key_pointer);
}
else
{
// update the file content
$this->registry->set('update.file.content.' . $key_pointer, true);
}
}
$this->component->remove('files');
}
}

View File

@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@@ -0,0 +1,752 @@
<?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\Component\JoomlaThree;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\EventInterface;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Dynamicpath;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Pathfix;
use VDM\Joomla\Utilities\FileHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component\SettingsInterface;
/**
* Compiler Component (Joomla Version) Settings
*
* @since 3.2.0
*/
final class Settings implements SettingsInterface
{
/**
* The standard folders
*
* @var array
* @since 3.2.0
*/
protected array $standardFolders = [
'site',
'admin',
'media'
];
/**
* The standard root files
*
* @var array
* @since 3.2.0
*/
protected array $standardRootFiles = [
'access.xml',
'config.xml',
'controller.php',
'index.html',
'README.txt'
];
/**
* Compiler Joomla Version Data
*
* @var object|null
* @since 3.2.0
*/
protected ?object $data = null;
/**
* 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 Placeholder
*
* @var Placeholder
* @since 3.2.0
*/
protected Placeholder $placeholder;
/**
* Compiler Component
*
* @var Component
* @since 3.2.0
**/
protected Component $component;
/**
* Compiler Utilities Paths
*
* @var Paths
* @since 3.2.0
*/
protected Paths $paths;
/**
* Compiler Component Dynamic Path
*
* @var Dynamicpath
* @since 3.2.0
**/
protected Dynamicpath $dynamicpath;
/**
* Compiler Component Pathfix
*
* @var Pathfix
* @since 3.2.0
**/
protected Pathfix $pathfix;
/**
* Constructor
*
* @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 Placeholder|null $placeholder The compiler placeholder object.
* @param Component|null $component The component class.
* @param Paths|null $paths The compiler paths object.
* @param Dynamicpath|null $dynamicpath The compiler dynamic path object.
* @param Pathfix|null $pathfix The compiler path fixing object.
*
* @since 3.2.0
*/
public function __construct(?Config $config = null, ?Registry $registry = null,
?EventInterface $event = null, ?Placeholder $placeholder = null,
?Component $component = null, ?Paths $paths = null,
?Dynamicpath $dynamicpath = null, ?Pathfix $pathfix = null)
{
$this->config = $config ?: Compiler::_('Config');
$this->registry = $registry ?: Compiler::_('Registry');
$this->event = $event ?: Compiler::_('Event');
$this->placeholder = $placeholder ?: Compiler::_('Placeholder');
$this->component = $component ?: Compiler::_('Component');
$this->paths = $paths ?: Compiler::_('Utilities.Paths');
$this->dynamicpath = $dynamicpath ?: Compiler::_('Utilities.Dynamicpath');
$this->pathfix = $pathfix ?: Compiler::_('Utilities.Pathfix');
// add component endpoint file to stander list of root files
$this->standardRootFiles[] = $this->component->get('name_code') . '.php';
}
/**
* Check if data set is loaded
*
* @return bool
* @since 3.2.0
*/
public function exists(): bool
{
if (!$this->isSet())
{
// load the data
$this->data = $this->get();
if (!$this->isSet())
{
return false;
}
}
return true;
}
/**
* Get Joomla - Folder Structure to Create
*
* @return object The version related structure
* @since 3.2.0
*/
public function structure(): object
{
return $this->data->create;
}
/**
* Get Joomla - Move Multiple Structure
*
* @return object The version related multiple structure
* @since 3.2.0
*/
public function multiple(): object
{
return $this->data->move->dynamic;
}
/**
* Get Joomla - Move Single Structure
*
* @return object The version related single structure
* @since 3.2.0
*/
public function single(): object
{
return $this->data->move->static;
}
/**
* Check if Folder is a Standard Folder
*
* @param string $folder The folder name
*
* @return bool true if the folder exists
* @since 3.2.0
*/
public function standardFolder(string $folder): bool
{
return in_array($folder, $this->standardFolders);
}
/**
* Check if File is a Standard Root File
*
* @param string $file The file name
*
* @return bool true if the file exists
* @since 3.2.0
*/
public function standardRootFile(string $file): bool
{
return in_array($file, $this->standardRootFiles);
}
/**
* Check if Data is Set
*
* @return bool
* @since 3.2.0
*/
private function isSet(): bool
{
return is_object($this->data) &&
isset($this->data->create) &&
isset($this->data->move) &&
isset($this->data->move->static) &&
isset($this->data->move->dynamic);
}
/**
* get the Joomla Version Data
*
* @return object|null The version data
* @since 3.2.0
*/
private function get(): ?object
{
// override option
$customSettings = $this->paths->template_path . '/settings_' .
$this->config->component_code_name . '.json';
// get the data
$version_data = $this->readJsonFile($customSettings);
if (is_null($version_data) || !$this->isValidData($version_data))
{
return null;
}
$this->loadExtraFolders();
$this->loadExtraFiles();
$this->addFolders($version_data);
$this->addFiles($version_data);
// Trigger Event: jcb_ce_onAfterSetJoomlaVersionData
$this->event->trigger(
'jcb_ce_onAfterSetJoomlaVersionData', [&$version_data]
);
return $version_data;
}
/**
* Read the Json file data
*
* @param string $filePath
*
* @return object|null The version data
* @since 3.2.0
*/
private function readJsonFile(string $filePath): ?object
{
if (FileHelper::exists($filePath))
{
$jsonContent = FileHelper::getContent($filePath);
}
else
{
$jsonContent = FileHelper::getContent($this->paths->template_path . '/settings.json');
}
if (JsonHelper::check($jsonContent))
{
return json_decode((string) $jsonContent);
}
return null;
}
/**
* Check if this is valid data
*
* @param object $versionData
*
* @return bool
* @since 3.2.0
*/
private function isValidData(object $versionData): bool
{
return isset($versionData->create) &&
isset($versionData->move) &&
isset($versionData->move->static) &&
isset($versionData->move->dynamic);
}
/**
* Add Extra/Dynamic folders
*
* @return void
* @since 3.2.0
*/
private function loadExtraFolders()
{
if ($this->component->isArray('folders') ||
$this->config->get('add_eximport', false) ||
$this->config->get('uikit', 0) ||
$this->config->get('footable', false))
{
$this->addImportViewFolder();
$this->addPhpSpreadsheetFolder();
$this->addUikitFolder();
$this->addFooTableFolder();
}
}
/**
* Add Import and Export Folder
*
* @return void
* @since 3.2.0
*/
private function addImportViewFolder()
{
if ($this->config->get('add_eximport', false))
{
$this->component->appendArray('folders', [
'folder' => 'importViews',
'path' => 'admin/views/import',
'rename' => 1
]);
}
}
/**
* Add Php Spreadsheet Folder
*
* @return void
* @since 3.2.0
*/
private function addPhpSpreadsheetFolder()
{
// move the phpspreadsheet Folder (TODO we must move this to a library package)
if ($this->config->get('add_eximport', false))
{
$this->component->appendArray('folders', [
'folderpath' => 'JPATH_LIBRARIES/phpspreadsheet/vendor',
'path' => '/libraries/phpspreadsheet/',
'rename' => 0
]);
}
}
/**
* Add Uikit Folders
*
* @return void
* @since 3.2.0
*/
private function addUikitFolder()
{
$uikit = $this->config->get('uikit', 0);
if (2 == $uikit || 1 == $uikit)
{
// move the UIKIT Folder into place
$this->component->appendArray('folders', [
'folder' => 'uikit-v2',
'path' => 'media',
'rename' => 0
]);
}
if (2 == $uikit || 3 == $uikit)
{
// move the UIKIT-3 Folder into place
$this->component->appendArray('folders', [
'folder' => 'uikit-v3',
'path' => 'media',
'rename' => 0
]);
}
}
/**
* Add Foo Table Folder
*
* @return void
* @since 3.2.0
*/
private function addFooTableFolder()
{
if (!$this->config->get('footable', false))
{
return;
}
$footable_version = $this->config->get('footable_version', 2);
if (2 == $footable_version)
{
// move the footable folder into place
$this->component->appendArray('folders', [
'folder' => 'footable-v2',
'path' => 'media',
'rename' => 0
]);
}
elseif (3 == $footable_version)
{
// move the footable folder into place
$this->component->appendArray('folders', [
'folder' => 'footable-v3',
'path' => 'media',
'rename' => 0
]);
}
}
/**
* Add Extra/Dynamic files
*
* @return void
* @since 3.2.0
*/
private function loadExtraFiles()
{
if ($this->component->isArray('files') ||
$this->config->get('google_chart', false))
{
$this->addGoogleChartFiles();
}
}
/**
* Add Google Chart Files
*
* @return void
* @since 3.2.0
*/
private function addGoogleChartFiles()
{
if ($this->config->get('google_chart', false))
{
// move the google chart files
$this->component->appendArray('files', [
'file' => 'google.jsapi.js',
'path' => 'media/js',
'rename' => 0
]);
$this->component->appendArray('files', [
'file' => 'chartbuilder.php',
'path' => 'admin/helpers',
'rename' => 0
]);
}
}
/**
* Add Folders
*
* @param object $versionData
*
* @return void
* @since 3.2.0
*/
private function addFolders(object &$versionData)
{
if (!$this->component->isArray('folders'))
{
return;
}
// pointer tracker
$pointer_tracker = 'h';
foreach ($this->component->get('folders') as $custom)
{
// check type of target type
$_target_type = 'c0mp0n3nt';
if (isset($custom['target_type']))
{
$_target_type = $custom['target_type'];
}
// for good practice
$this->pathfix->set(
$custom, ['path', 'folder', 'folderpath']
);
// fix custom path
if (isset($custom['path'])
&& StringHelper::check($custom['path']))
{
$custom['path'] = trim((string) $custom['path'], '/');
}
// by default custom path is true
$customPath = 'custom';
// set full path if this is a full path folder
if (!isset($custom['folder']) && isset($custom['folderpath']))
{
// update the dynamic path
$custom['folderpath'] = $this->dynamicpath->update(
$custom['folderpath']
);
// set the folder path with / if does not have a drive/windows full path
$custom['folder'] = (preg_match(
'/^[a-z]:/i', $custom['folderpath']
)) ? trim($custom['folderpath'], '/')
: '/' . trim($custom['folderpath'], '/');
// remove the file path
unset($custom['folderpath']);
// triget fullpath
$customPath = 'full';
}
// make sure we use the correct name
$pathArray = (array) explode('/', (string) $custom['path']);
$lastFolder = end($pathArray);
// only rename folder if last has folder name
if (isset($custom['rename']) && $custom['rename'] == 1)
{
$custom['path'] = str_replace(
'/' . $lastFolder, '', (string) $custom['path']
);
$rename = 'new';
$newname = $lastFolder;
}
elseif ('full' === $customPath)
{
// make sure we use the correct name
$folderArray = (array) explode('/', (string) $custom['folder']);
$lastFolder = end($folderArray);
$rename = 'new';
$newname = $lastFolder;
}
else
{
$rename = false;
$newname = '';
}
// insure we have no duplicates
$key_pointer = StringHelper::safe(
$custom['folder']
) . '_f' . $pointer_tracker;
$pointer_tracker++;
// fix custom path
$custom['path'] = ltrim((string) $custom['path'], '/');
// set new folder to object
$versionData->move->static->{$key_pointer} = new \stdClass();
$versionData->move->static->{$key_pointer}->naam = str_replace('//', '/', (string) $custom['folder']);
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = $rename;
$versionData->move->static->{$key_pointer}->newName = $newname;
$versionData->move->static->{$key_pointer}->type = 'folder';
$versionData->move->static->{$key_pointer}->custom = $customPath;
// set the target if type and id is found
if (isset($custom['target_id']) && isset($custom['target_type']))
{
$versionData->move->static->{$key_pointer}->_target = [
'key' => $custom['target_id'] . '_' . $custom['target_type'],
'type' => $custom['target_type']
];
}
}
$this->component->remove('folders');
}
/**
* Add Files
*
* @param object $versionData
*
* @return void
* @since 3.2.0
*/
private function addFiles(object &$versionData)
{
if (!$this->component->isArray('files')) {
return;
}
// pointer tracker
$pointer_tracker = 'h';
foreach ($this->component->get('files') as $custom)
{
// check type of target type
$_target_type = 'c0mp0n3nt';
if (isset($custom['target_type']))
{
$_target_type = $custom['target_type'];
}
// for good practice
$this->pathfix->set(
$custom, ['path', 'file', 'filepath']
);
// by default custom path is true
$customPath = 'custom';
// set full path if this is a full path file
if (!isset($custom['file']) && isset($custom['filepath']))
{
// update the dynamic path
$custom['filepath'] = $this->dynamicpath->update(
$custom['filepath']
);
// set the file path with / if does not have a drive/windows full path
$custom['file'] = (preg_match('/^[a-z]:/i', $custom['filepath']))
? trim($custom['filepath'], '/') : '/' . trim($custom['filepath'], '/');
// remove the file path
unset($custom['filepath']);
// triget fullpath
$customPath = 'full';
}
// make sure we have not duplicates
$key_pointer = StringHelper::safe(
$custom['file']
) . '_g' . $pointer_tracker;
$pointer_tracker++;
// set new file to object
$versionData->move->static->{$key_pointer} = new \stdClass();
$versionData->move->static->{$key_pointer}->naam = str_replace('//', '/', (string) $custom['file']);
// update the dynamic component name placholders in file names
$custom['path'] = $this->placeholder->update_(
$custom['path']
);
// get the path info
$pathInfo = pathinfo((string) $custom['path']);
if (isset($pathInfo['extension']) && $pathInfo['extension'])
{
$pathInfo['dirname'] = trim($pathInfo['dirname'], '/');
// set the info
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $pathInfo['dirname'];
$versionData->move->static->{$key_pointer}->rename = 'new';
$versionData->move->static->{$key_pointer}->newName = $pathInfo['basename'];
}
elseif ('full' === $customPath)
{
// fix custom path
$custom['path'] = ltrim((string) $custom['path'], '/');
// get file array
$fileArray = (array) explode('/', (string) $custom['file']);
// set the info
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = 'new';
$versionData->move->static->{$key_pointer}->newName = end($fileArray);
}
else
{
// fix custom path
$custom['path'] = ltrim((string) $custom['path'], '/');
// set the info
$versionData->move->static->{$key_pointer}->path = $_target_type . '/' . $custom['path'];
$versionData->move->static->{$key_pointer}->rename = false;
}
$versionData->move->static->{$key_pointer}->type = 'file';
$versionData->move->static->{$key_pointer}->custom = $customPath;
// set the target if type and id is found
if (isset($custom['target_id'])
&& isset($custom['target_type']))
{
$versionData->move->static->{$key_pointer}->_target = [
'key' => $custom['target_id'] . '_' . $custom['target_type'],
'type' => $custom['target_type']
];
}
// check if file should be updated
if (!isset($custom['notnew']) || $custom['notnew'] == 0
|| $custom['notnew'] != 1)
{
$this->registry->appendArray('files.not.new', $key_pointer);
}
else
{
// update the file content
$this->registry->set('update.file.content.' . $key_pointer, true);
}
}
$this->component->remove('files');
}
}

View File

@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>

View File

@@ -0,0 +1,150 @@
<?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\Component;
use Joomla\CMS\Factory;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Utilities\GetHelper;
use VDM\Joomla\Utilities\JsonHelper;
use VDM\Joomla\Utilities\ArrayHelper;
use VDM\Joomla\Utilities\String\NamespaceHelper;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component\PlaceholderInterface;
/**
* Get a Components Global Placeholders
*
* @since 3.2.0
*/
final class Placeholder implements PlaceholderInterface
{
/**
* Placeholders
*
* @var array
* @since 3.2.0
**/
protected $placeholders = null;
/**
* Compiler Config
*
* @var Config
* @since 3.2.0
**/
protected $config;
/**
* Database object to query local DB
*
* @since 3.2.0
**/
protected $db;
/**
* Constructor.
*
* @param Config $config The compiler config object.
* @param \JDatabaseDriver $db The Database Driver object.
*
* @since 3.2.0
**/
public function __construct(?Config $config = null)
{
$this->config = $config ?: Compiler::_('Config');
$this->db = Factory::getDbo();
}
/**
* get all System Placeholders
*
* @return array The global placeholders
*
* @since 3.2.0
*/
public function get(): array
{
// set only once
if (is_array($this->placeholders))
{
return $this->placeholders;
}
// load the config
$config = $this->config;
// load the db
$db = $this->db;
// reset bucket
$bucket = [];
// Create a new query object.
$query = $db->getQuery(true);
$query->select($db->quoteName(array('a.target', 'a.value')));
// from these tables
$query->from('#__componentbuilder_placeholder AS a');
// Reset the query using our newly populated query object.
$db->setQuery($query);
// Load the items
$db->execute();
if ($db->getNumRows())
{
$bucket = $db->loadAssocList('target', 'value');
// open all the code
foreach ($bucket as $key => &$code)
{
$code = base64_decode((string) $code);
}
}
// set component place holders
$bucket[Placefix::_h('component')] = $config->component_code_name;
$bucket[Placefix::_h('Component')] = StringHelper::safe($config->component_code_name, 'F');
$bucket[Placefix::_h('COMPONENT')] = StringHelper::safe($config->component_code_name, 'U');
$bucket[Placefix::_('component')] = $bucket[Placefix::_h('component')];
$bucket[Placefix::_('Component')] = $bucket[Placefix::_h('Component')];
$bucket[Placefix::_('COMPONENT')] = $bucket[Placefix::_h('COMPONENT')];
$bucket[Placefix::_h('LANG_PREFIX')] = $config->lang_prefix;
$bucket[Placefix::_('LANG_PREFIX')] = $bucket[Placefix::_h('LANG_PREFIX')];
$bucket[Placefix::_h('ComponentNamespace')] = NamespaceHelper::safeSegment(StringHelper::safe($config->component_code_name, 'F'));
$bucket[Placefix::_('ComponentNamespace')] = $bucket[Placefix::_h('ComponentNamespace')];
$bucket[Placefix::_h('NamespacePrefix')] = $config->namespace_prefix;
$bucket[Placefix::_('NamespacePrefix')] = $config->namespace_prefix;
$bucket[Placefix::_h('NAMESPACEPREFIX')] = $config->namespace_prefix;
$bucket[Placefix::_('NAMESPACEPREFIX')] = $config->namespace_prefix;
// get the current components overrides
if (($_placeholders = GetHelper::var(
'component_placeholders', $config->component_id,
'joomla_component', 'addplaceholders'
)) !== false
&& JsonHelper::check($_placeholders))
{
$_placeholders = json_decode((string) $_placeholders, true);
if (ArrayHelper::check($_placeholders))
{
foreach ($_placeholders as $row)
{
$bucket[$row['target']] = str_replace(array_keys($bucket), array_values($bucket), $row['value']);
}
}
}
$this->placeholders = $bucket;
return $bucket;
}
}

View File

@@ -0,0 +1,117 @@
<?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\Component;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component\SettingsInterface as Settings;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Folder;
use VDM\Joomla\Utilities\ObjectHelper;
/**
* Build/Create Component Structure
*
* @since 3.2.0
*/
final class Structure
{
/**
* Compiler Component Joomla Version Settings
*
* @var Settings
* @since 3.2.0
*/
protected Settings $settings;
/**
* Compiler Paths
*
* @var Paths
* @since 3.2.0
*/
protected Paths $paths;
/**
* Compiler Utilities Folder
*
* @var Folder
* @since 3.2.0
*/
protected Folder $folder;
/**
* Constructor
*
* @param Settings|null $settings The compiler component joomla version settings object.
* @param Paths|null $paths The compiler paths object.
* @param Folder|null $folder The compiler folder object.
*
* @since 3.2.0
*/
public function __construct(?Settings $settings = null, ?Paths $paths = null, ?Folder $folder = null)
{
$this->settings = $settings ?: Compiler::_('Component.Settings');
$this->paths = $paths ?: Compiler::_('Utilities.Paths');
$this->folder = $folder ?: Compiler::_('Utilities.Folder');
}
/**
* Build the Component Structure
*
* @return bool
* @since 3.2.0
*/
public function build(): bool
{
if ($this->settings->exists())
{
// setup the main component path
$this->folder->create($this->paths->component_path);
// build the version structure
$this->folders(
$this->settings->structure(),
$this->paths->component_path
);
return true;
}
return false;
}
/**
* Create the folder and subfolders
*
* @param object $folders The object[] of folders
* @param string $path The path
*
* @return void
* @since 3.2.0
*/
protected function folders(object $folders, string $path)
{
foreach ($folders as $folder => $sub_folders)
{
$new_path = $path . '/' . $folder;
$this->folder->create($new_path);
if (ObjectHelper::check($sub_folders))
{
$this->folders($sub_folders, $new_path);
}
}
}
}

View File

@@ -0,0 +1,354 @@
<?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\Component;
use VDM\Joomla\Componentbuilder\Compiler\Factory as Compiler;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component\SettingsInterface as Settings;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Model\Createdate;
use VDM\Joomla\Componentbuilder\Compiler\Model\Modifieddate;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Structure;
use VDM\Joomla\Utilities\ObjectHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Placefix;
/**
* Multiple Files and Folders Builder Class
*
* @since 3.2.0
*/
final class Structuremultiple
{
/**
* Compiler Config
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* The compiler registry
*
* @var Registry
* @since 3.2.0
*/
protected Registry $registry;
/**
* Compiler Component Joomla Version Settings
*
* @var Settings
* @since 3.2.0
*/
protected Settings $settings;
/**
* Compiler Component
*
* @var Component
* @since 3.2.0
**/
protected Component $component;
/**
* Compiler Model Createdate
*
* @var Createdate
* @since 3.2.0
**/
protected Createdate $createdate;
/**
* Compiler Model Modifieddate
*
* @var Modifieddate
* @since 3.2.0
**/
protected Modifieddate $modifieddate;
/**
* Compiler Utility to Build Structure
*
* @var Structure
* @since 3.2.0
**/
protected Structure $structure;
/**
* Constructor
*
* @param Config|null $config The compiler config object.
* @param Registry|null $registry The compiler registry object.
* @param Settings|null $settings The compiler component Joomla version settings object.
* @param Component|null $component The component class.
* @param Createdate|null $createdate The compiler model to get create date class.
* @param Modifieddate|null $modifieddate The compiler model to get modified date class.
* @param Structure|null $structure The compiler structure to build dynamic folder and files class.
*
* @since 3.2.0
*/
public function __construct(?Config $config = null, ?Registry $registry = null,
?Settings $settings = null, ?Component $component = null,
?Createdate $createdate = null, ?Modifieddate $modifieddate = null,
?Structure $structure = null)
{
$this->config = $config ?: Compiler::_('Config');
$this->registry = $registry ?: Compiler::_('Registry');
$this->settings = $settings ?: Compiler::_('Component.Settings');
$this->component = $component ?: Compiler::_('Component');
$this->createdate = $createdate ?: Compiler::_('Model.Createdate');
$this->modifieddate = $modifieddate ?: Compiler::_('Model.Modifieddate');
$this->structure = $structure ?: Compiler::_('Utilities.Structure');
}
/**
* Build the Multiple Files & Folders
*
* @return bool
* @since 3.2.0
*/
public function build(): bool
{
$success = false;
if ($this->settings->exists())
{
$success = $this->admin();
$success = $this->site() || $success;
$success = $this->custom() || $success;
}
return $success;
}
/**
* Build the Dynamic Admin Files & Folders
*
* @return bool
* @since 3.2.0
*/
protected function admin(): bool
{
if (!$this->component->isArray('admin_views'))
{
return false;
}
// check if we have a dynamic dashboard
if (!$this->registry->get('build.dashboard'))
{
// setup the default dashboard
$target = ['admin' => $this->component->get('name_code')];
$this->structure->build($target, 'dashboard');
}
$config = [];
$checkin = false;
foreach ($this->component->get('admin_views') as $view)
{
if (!$this->isValidAdminView($view, $config))
{
continue;
}
$this->buildAdminView($view, $config);
// quick set of checkin once
if (!$checkin && isset($view['checkin']) && $view['checkin'] == 1)
{
// switch to add checking to config
$checkin = true;
$this->config->set('add_checkin', $checkin);
}
}
return true;
}
/**
* Build the Dynamic Site Files & Folders
*
* @return bool
* @since 3.2.0
*/
protected function site(): bool
{
if (!$this->component->isArray('site_views'))
{
return false;
}
$config = [];
foreach ($this->component->get('site_views') as $view)
{
if (!$this->isValidView($view, $config))
{
continue;
}
$this->buildView($view, $config, 'site');
}
return true;
}
/**
* Build the Dynamic Custom Admin Files & Folders
*
* @return bool
* @since 3.2.0
*/
protected function custom(): bool
{
if (!$this->component->isArray('custom_admin_views'))
{
return false;
}
$config = [];
foreach ($this->component->get('custom_admin_views') as $view)
{
if (!$this->isValidView($view, $config))
{
continue;
}
$this->buildView($view, $config, 'custom_admin');
}
return true;
}
/**
* Check if the view is a valid view
*
* @param array $view
* @param array $config
*
* @return bool
* @since 3.2.0
*/
private function isValidAdminView(array $view, array &$config): bool
{
if (!isset($view['settings']) || !ObjectHelper::check($view['settings'])
|| ((!isset($view['settings']->name_list) || $view['settings']->name_list == 'null')
&& (!isset($view['settings']->name_single) || $view['settings']->name_single == 'null')))
{
return false;
}
$created = $this->createdate->get($view);
$modified = $this->modifieddate->get($view);
$config = [
Placefix::_h('CREATIONDATE') => $created,
Placefix::_h('BUILDDATE') => $modified,
Placefix::_h('VERSION') => $view['settings']->version
];
return true;
}
/**
* Check if the view is a valid view
*
* @param array $view
* @param array $config
*
* @return bool
* @since 3.2.0
*/
private function isValidView(array $view, array &$config): bool
{
if (!isset($view['settings']) || !ObjectHelper::check($view['settings'])
|| !isset($view['settings']->main_get)
|| !ObjectHelper::check($view['settings']->main_get)
|| !isset($view['settings']->main_get->gettype)
|| ($view['settings']->main_get->gettype != 1 && $view['settings']->main_get->gettype != 2))
{
return false;
}
$created = $this->createdate->get($view);
$modified = $this->modifieddate->get($view);
$config = [
Placefix::_h('CREATIONDATE') => $created,
Placefix::_h('BUILDDATE') => $modified,
Placefix::_h('VERSION') => $view['settings']->version
];
return true;
}
/**
* Build the admin view
*
* @param array $view
* @param array $config
*
* @return void
* @since 3.2.0
*/
private function buildAdminView(array $view, array $config)
{
// build the admin edit view
if ($view['settings']->name_single != 'null')
{
$target = ['admin' => $view['settings']->name_single];
$this->structure->build($target, 'single', false, $config);
// build the site edit view (of this admin view)
if (isset($view['edit_create_site_view'])
&& is_numeric($view['edit_create_site_view'])
&& $view['edit_create_site_view'] > 0)
{
// setup the front site edit-view files
$target = ['site' => $view['settings']->name_single];
$this->structure->build($target, 'edit', false, $config);
}
}
// build the list view
if ($view['settings']->name_list != 'null')
{
$target = ['admin' => $view['settings']->name_list];
$this->structure->build($target, 'list', false, $config);
}
}
/**
* Build the custom view
*
* @param array $view
* @param array $config
* @param string $type
*
* @return void
* @since 3.2.0
*/
private function buildView(array $view, array $config, string $type)
{
$target = [$type => $view['settings']->code];
$view_type = ($view['settings']->main_get->gettype == 1) ? 'single' : 'list';
$this->structure->build($target, $view_type, false, $config);
}
}

View File

@@ -0,0 +1,646 @@
<?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\Component;
use Joomla\CMS\Factory;
use Joomla\CMS\Application\CMSApplication;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Filesystem\Folder;
use Joomla\CMS\Filesystem\File;
use VDM\Joomla\Componentbuilder\Compiler\Config;
use VDM\Joomla\Componentbuilder\Compiler\Registry;
use VDM\Joomla\Componentbuilder\Compiler\Placeholder;
use VDM\Joomla\Componentbuilder\Compiler\Interfaces\Component\SettingsInterface as Settings;
use VDM\Joomla\Componentbuilder\Compiler\Component;
use VDM\Joomla\Componentbuilder\Compiler\Builder\ContentOne as Content;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Counter;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Paths;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Files;
use VDM\Joomla\Utilities\StringHelper;
use VDM\Joomla\Componentbuilder\Compiler\Utilities\Indent;
/**
* Single Files and Folders Builder Class
*
* @since 3.2.0
*/
final class Structuresingle
{
/**
* The new name
*
* @var string
* @since 3.2.0
*/
protected string $newName;
/**
* Current Full Path
*
* @var string
* @since 3.2.0
*/
protected string $currentFullPath;
/**
* Package Full Path
*
* @var string
* @since 3.2.0
*/
protected string $packageFullPath;
/**
* ZIP Full Path
*
* @var string
* @since 3.2.0
*/
protected string $zipFullPath;
/**
* The Config Class.
*
* @var Config
* @since 3.2.0
*/
protected Config $config;
/**
* The Registry Class.
*
* @var Registry
* @since 3.2.0
*/
protected Registry $registry;
/**
* The Placeholder Class.
*
* @var Placeholder
* @since 3.2.0
*/
protected Placeholder $placeholder;
/**
* The SettingsInterface Class.
*
* @var Settings
* @since 3.2.0
*/
protected Settings $settings;
/**
* The Component Class.
*
* @var Component
* @since 3.2.0
*/
protected Component $component;
/**
* The ContentOne Class.
*
* @var Content
* @since 3.2.0
*/
protected Content $content;
/**
* The Counter Class.
*
* @var Counter
* @since 3.2.0
*/
protected Counter $counter;
/**
* The Paths Class.
*
* @var Paths
* @since 3.2.0
*/
protected Paths $paths;
/**
* The Files Class.
*
* @var Files
* @since 3.2.0
*/
protected Files $files;
/**
* Application object.
*
* @var CMSApplication
* @since 3.2.0
**/
protected CMSApplication $app;
/**
* Constructor.
*
* @param Config $config The Config Class.
* @param Registry $registry The Registry Class.
* @param Placeholder $placeholder The Placeholder Class.
* @param Settings $settings The SettingsInterface Class.
* @param Component $component The Component Class.
* @param Content $content The ContentOne Class.
* @param Counter $counter The Counter Class.
* @param Paths $paths The Paths Class.
* @param Files $files The Files Class.
* @param CMSApplication|null $app The CMS Application object.
*
* @since 3.2.0
*/
public function __construct(Config $config, Registry $registry,
Placeholder $placeholder, Settings $settings,
Component $component, Content $content, Counter $counter,
Paths $paths, Files $files, ?CMSApplication $app = null)
{
$this->config = $config;
$this->registry = $registry;
$this->placeholder = $placeholder;
$this->settings = $settings;
$this->component = $component;
$this->content = $content;
$this->counter = $counter;
$this->paths = $paths;
$this->files = $files;
$this->app = $app ?: Factory::getApplication();
}
/**
* Build the Single Files & Folders
*
* @return bool
* @since 3.2.0
*/
public function build(): bool
{
if ($this->settings->exists())
{
// TODO needs more looking at this must be dynamic actually
$this->registry->appendArray('files.not.new', 'LICENSE.txt');
// do license check
$LICENSE = $this->doLicenseCheck();
// do README check
$README = $this->doReadmeCheck();
// do CHANGELOG check
$CHANGELOG = $this->doChangelogCheck();
// start moving
foreach ($this->settings->single() as $target => $details)
{
// if not gnu/gpl license dont add the LICENSE.txt file
if ($details->naam === 'LICENSE.txt' && !$LICENSE)
{
continue;
}
// if not needed do not add
if (($details->naam === 'README.md' || $details->naam === 'README.txt')
&& !$README)
{
continue;
}
// if not needed do not add
if ($details->naam === 'CHANGELOG.md' && !$CHANGELOG)
{
continue;
}
// set new name
$this->setNewName($details);
// set all paths
$this->setPaths($details);
// check if the path exists
if ($this->pathExist($details))
{
// set the target
$this->setTarget($target, $details);
}
// set dynamic target as needed
$this->setDynamicTarget($details);
}
return true;
}
return false;
}
/**
* Check if license must be added
*
* @return bool
* @since 3.2.0
*/
private function doLicenseCheck(): bool
{
$licenseChecker = strtolower((string) $this->component->get('license', ''));
if (strpos($licenseChecker, 'gnu') !== false
&& strpos(
$licenseChecker, '2'
) !== false
&& (strpos($licenseChecker, 'gpl') !== false
|| strpos(
$licenseChecker, 'general public license'
) !== false))
{
return true;
}
return false;
}
/**
* Check if readme must be added
*
* @return bool
* @since 3.2.0
*/
private function doReadmeCheck(): bool
{
return (bool) $this->component->get('addreadme', false);
}
/**
* Check if changelog must be added
*
* @return bool
* @since 3.2.0
*/
private function doChangelogCheck(): bool
{
return (bool) $this->component->get('changelog', false);
}
/**
* Set the new name
*
* @param object $details
*
* @return void
* @since 3.2.0
*/
private function setNewName(object $details)
{
// do the file renaming
if (isset($details->rename) && $details->rename)
{
if ($details->rename === 'new')
{
$newName = $details->newName;
}
else
{
$naam = $details->naam ?? 'error';
$newName = str_replace(
$details->rename,
$this->config->component_code_name,
(string) $naam
);
}
}
else
{
$newName = $details->naam ?? 'error';
}
$this->newName = $this->placeholder->update_($newName);
}
/**
* Set all needed paths
*
* @param object $details
*
* @return void
* @since 3.2.0
*/
private function setPaths(object $details)
{
// check if we have a target value
if (isset($details->_target))
{
// set destination path
$zipPath = str_replace(
$details->_target['type'] . '/', '', (string) $details->path
);
$path = str_replace(
$details->_target['type'] . '/',
$this->registry->get('dynamic_paths.' . $details->_target['key'], '') . '/',
(string) $details->path
);
}
else
{
// set destination path
$zipPath = str_replace('c0mp0n3nt/', '', (string) $details->path);
$path = str_replace(
'c0mp0n3nt/', $this->paths->component_path . '/', (string) $details->path
);
}
// set the template folder path
$templatePath = (isset($details->custom) && $details->custom)
? (($details->custom !== 'full') ? $this->paths->template_path_custom
. '/' : '') : $this->paths->template_path . '/';
// set the final paths
$currentFullPath = (preg_match('/^[a-z]:/i', (string) $details->naam)) ? $details->naam
: $templatePath . '/' . $details->naam;
$this->currentFullPath = str_replace('//', '/', (string) $currentFullPath);
$this->packageFullPath = str_replace('//', '/', $path . '/' . $this->newName);
$this->zipFullPath = str_replace(
'//', '/', $zipPath . '/' . $this->newName
);
}
/**
* Check if path exists
*
* @param object $details
*
* @return bool
* @since 3.2.0
*/
private function pathExist(object $details): bool
{
// check if this has a type
if (!isset($details->type))
{
return false;
}
// take action based on type
elseif ($details->type === 'file' && !File::exists($this->currentFullPath))
{
$this->app->enqueueMessage(
Text::_('COM_COMPONENTBUILDER_HR_HTHREEFILE_PATH_ERRORHTHREE'), 'Error'
);
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_THE_FILE_PATH_BSB_DOES_NOT_EXIST_AND_WAS_NOT_ADDED',
$this->currentFullPath
), 'Error'
);
return false;
}
elseif ($details->type === 'folder' && !Folder::exists($this->currentFullPath))
{
$this->app->enqueueMessage(
Text::_('COM_COMPONENTBUILDER_HR_HTHREEFOLDER_PATH_ERRORHTHREE'),
'Error'
);
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_THE_FOLDER_PATH_BSB_DOES_NOT_EXIST_AND_WAS_NOT_ADDED',
$this->currentFullPath
), 'Error'
);
return false;
}
return true;
}
/**
* Set the target based on target type
*
* @param string $target
* @param object $details
*
* @return void
* @since 3.2.0
*/
private function setTarget(string $target, object $details)
{
// take action based on type
if ($details->type === 'file')
{
// move the file
$this->moveFile();
// register the file
$this->registerFile($target, $details);
}
elseif ($details->type === 'folder')
{
// move the folder to its place
Folder::copy(
$this->currentFullPath, $this->packageFullPath, '', true
);
// count the folder created
$this->counter->folder++;
}
}
/**
* Move/Copy the file into place
*
* @return void
* @since 3.2.0
*/
private function moveFile()
{
// get base name && get the path only
$packageFullPath0nly = str_replace(
basename($this->packageFullPath), '', $this->packageFullPath
);
// check if path exist, if not creat it
if (!Folder::exists($packageFullPath0nly))
{
Folder::create($packageFullPath0nly);
}
// move the file to its place
File::copy($this->currentFullPath, $this->packageFullPath);
// count the file created
$this->counter->file++;
}
/**
* Register the file
*
* @param string $target
* @param object $details
*
* @return void
* @since 3.2.0
*/
private function registerFile(string $target, object $details)
{
// store the new files
if (!in_array($target, $this->registry->get('files.not.new', [])))
{
if (isset($details->_target))
{
$this->files->appendArray($details->_target['key'],
[
'path' => $this->packageFullPath,
'name' => $this->newName,
'zip' => $this->zipFullPath
]
);
}
else
{
$this->files->appendArray('static',
[
'path' => $this->packageFullPath,
'name' => $this->newName,
'zip' => $this->zipFullPath
]
);
}
}
// ensure we update this file if needed
if ($this->registry->exists('update.file.content.' . $target))
{
// remove the pointer
$this->registry->remove('update.file.content.' . $target);
// set the full path
$this->registry->set('update.file.content.' . $this->packageFullPath, $this->packageFullPath);
}
}
/**
* Set Dynamic Target
*
* @param object $details
*
* @return void
* @since 3.2.0
*/
private function setDynamicTarget(object $details)
{
// only add if no target found since those belong to plugins and modules
if (!isset($details->_target))
{
// check if we should add the dynamic folder moving script to the installer script
$checker = array_values((array) explode('/', $this->zipFullPath));
// TODO <-- this may not be the best way, will keep an eye on this.
// We basicly only want to check if a folder is added that is not in the stdFolders array
if (isset($checker[0])
&& StringHelper::check($checker[0])
&& !$this->settings->standardFolder($checker[0]))
{
// activate dynamic folders
$this->setDynamicFolders();
}
elseif (count((array) $checker) == 2
&& StringHelper::check($checker[0]))
{
$add_to_extra = false;
// set the target
$eNAME = 'FILES';
$ename = 'filename';
// this should not happen and must have been caught by the above if statment
if ($details->type === 'folder')
{
// only folders outside the standard folder are added
$eNAME = 'FOLDERS';
$ename = 'folder';
$add_to_extra = true;
}
// if this is a file, it can only be added to the admin/site/media folders
// all other folders are moved as a whole so their files do not need to be declared
elseif ($this->settings->standardFolder($checker[0])
&& !$this->settings->standardRootFile($checker[1]))
{
$add_to_extra = true;
}
// add if valid folder/file
if ($add_to_extra)
{
// set the tab
$eTab = Indent::_(2);
if ('admin' === $checker[0])
{
$eTab = Indent::_(3);
}
// set the xml file
$key_ = 'EXSTRA_'
. StringHelper::safe(
$checker[0], 'U'
) . '_' . $eNAME;
$this->content->add($key_,
PHP_EOL . $eTab . "<" . $ename . ">"
. $checker[1] . "</" . $ename . ">");
}
}
}
}
/**
* 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'))
{
// add the setDynamicF0ld3rs() method to the install scipt.php file
$this->registry->set('set_move_folders_install_script', true);
$function = 'setDynamicF0ld3rs';
$script = 'script.php';
if ($this->config->get('joomla_version', 3) != 3)
{
$function = 'moveFolders';
$script = 'ComponentnameInstallerScript.php';
}
// 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'
);
}
}
}

View File

@@ -0,0 +1 @@
<html><body bgcolor="#FFFFFF"></body></html>