331 lines
9.0 KiB
PHP
331 lines
9.0 KiB
PHP
|
<?php
|
||
|
/**
|
||
|
* @package Joomla.Component.Builder
|
||
|
*
|
||
|
* @created 4th September, 2022
|
||
|
* @author Llewellyn van der Merwe <https://dev.vdm.io>
|
||
|
* @git Joomla Component Builder <https://git.vdm.dev/joomla/Component-Builder>
|
||
|
* @copyright Copyright (C) 2015 Vast Development Method. All rights reserved.
|
||
|
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||
|
*/
|
||
|
|
||
|
namespace VDM\Joomla\Componentbuilder\Compiler\Model;
|
||
|
|
||
|
|
||
|
use VDM\Joomla\Componentbuilder\Compiler\Config;
|
||
|
use VDM\Joomla\Componentbuilder\Compiler\Customcode\Dispenser;
|
||
|
use VDM\Joomla\Componentbuilder\Compiler\Builder\Router as Builder;
|
||
|
use VDM\Joomla\Utilities\ArrayHelper;
|
||
|
use VDM\Joomla\Utilities\StringHelper;
|
||
|
use VDM\Joomla\Utilities\JsonHelper;
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Model Component Site Router Class
|
||
|
*
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
class Router
|
||
|
{
|
||
|
/**
|
||
|
* The Config Class.
|
||
|
*
|
||
|
* @var Config
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected Config $config;
|
||
|
|
||
|
/**
|
||
|
* The Dispenser Class.
|
||
|
*
|
||
|
* @var Dispenser
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected Dispenser $dispenser;
|
||
|
|
||
|
/**
|
||
|
* The Router Class.
|
||
|
*
|
||
|
* @var Builder
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected Builder $builder;
|
||
|
|
||
|
/**
|
||
|
* The gui mapper array
|
||
|
*
|
||
|
* @var array
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected array $guiMapper = [
|
||
|
'table' => 'component_router',
|
||
|
'id' => null,
|
||
|
'field' => null,
|
||
|
'type' => 'php'
|
||
|
];
|
||
|
|
||
|
/**
|
||
|
* The field targets
|
||
|
*
|
||
|
* @var array
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected array $targets = [
|
||
|
'before' => 'constructor_before_parent',
|
||
|
'after' => 'constructor_after_parent',
|
||
|
'method' => 'methods'
|
||
|
];
|
||
|
|
||
|
/**
|
||
|
* Constructor.
|
||
|
*
|
||
|
* @param Config $config The Config Class.
|
||
|
* @param Dispenser $dispenser The Dispenser Class.
|
||
|
* @param Builder $builder The Router Class.
|
||
|
*
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
public function __construct(Config $config, Dispenser $dispenser, Builder $builder)
|
||
|
{
|
||
|
$this->config = $config;
|
||
|
$this->dispenser = $dispenser;
|
||
|
$this->builder = $builder;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Set Router
|
||
|
*
|
||
|
* @param object $item The item data
|
||
|
*
|
||
|
* @return void
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
public function set(object &$item)
|
||
|
{
|
||
|
$this->config->lang_target = 'site';
|
||
|
foreach ($this->targets as $target)
|
||
|
{
|
||
|
// add the code
|
||
|
if ($item->{"router_mode_{$target}"} == 3
|
||
|
&& StringHelper::check($item->{"router_{$target}_code"}))
|
||
|
{
|
||
|
// update GUI mapper field
|
||
|
$this->guiMapper['field'] = "{$target}_code";
|
||
|
$this->dispenser->set(
|
||
|
$item->{"router_{$target}_code"},
|
||
|
"_site_router_",
|
||
|
$target,
|
||
|
null,
|
||
|
$this->guiMapper
|
||
|
);
|
||
|
}
|
||
|
unset($item->{"router_{$target}_code"});
|
||
|
}
|
||
|
|
||
|
// get the site views
|
||
|
$views = $this->getSiteViews($item->site_views ?? [], $item->admin_views ?? []);
|
||
|
$edit_views = $this->getSiteEditViews($item->admin_views);
|
||
|
|
||
|
// get the edit site views
|
||
|
$this->builder->set('views',
|
||
|
ArrayHelper::merge([$views, $edit_views])
|
||
|
);
|
||
|
|
||
|
if ($item->router_mode_constructor_before_parent == 2
|
||
|
&& JsonHelper::check($item->router_constructor_before_parent_manual))
|
||
|
{
|
||
|
// build and validate the constructor before parent call code
|
||
|
$this->builder->set('manual',
|
||
|
json_decode($item->router_constructor_before_parent_manual)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
// clear the data from the item
|
||
|
foreach ($this->targets as $key => $target)
|
||
|
{
|
||
|
// set the modes
|
||
|
$this->builder->set("mode_{$key}",
|
||
|
(int) $item->{"router_mode_{$target}"}
|
||
|
);
|
||
|
|
||
|
unset($item->{"router_mode_{$target}"});
|
||
|
}
|
||
|
|
||
|
unset($item->router_constructor_before_parent_manual);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the array of site views with additional details.
|
||
|
*
|
||
|
* This method processes each site view to enrich it with additional details such as the associated table,
|
||
|
* alias keys, and other relevant information. The enrichment is based on the view's settings and the admin views.
|
||
|
*
|
||
|
* @param array $siteViews The site views to be processed.
|
||
|
* @param array $adminViews The admin views used for fetching additional data.
|
||
|
*
|
||
|
* @return array An array of objects, each representing a site view with enriched details.
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected function getSiteViews(array $siteViews, array $adminViews): array
|
||
|
{
|
||
|
return array_map(function ($view) use ($adminViews) {
|
||
|
// Attempt to get the main selection details from the view's settings.
|
||
|
$selection = $this->getMainSelection($view['settings']->main_get->main_get ?? null);
|
||
|
|
||
|
// We can only work with ID if the [main get] is a [getItem] dynamicGet for this site view.
|
||
|
$key = ($view['settings']->main_get->gettype == 1) ? 'id' : null;
|
||
|
|
||
|
// Construct the enriched view object.
|
||
|
return (object) [
|
||
|
'view' => $view['settings']->code,
|
||
|
'View' => $view['settings']->Code,
|
||
|
'stable' => ($selection['view'] === $view['settings']->code), // sanity check
|
||
|
'target_view' => $selection['view'],
|
||
|
'table' => $selection['table'],
|
||
|
'table_name' => $selection['name'],
|
||
|
'alias' => $this->getSiteViewAliasKey($selection['name'] ?? null, $adminViews),
|
||
|
'key' => $key,
|
||
|
'form' => false
|
||
|
];
|
||
|
}, $siteViews);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the array of site edit views
|
||
|
*
|
||
|
* This method processes the provided admin views to extract and return an array of site edit views.
|
||
|
* Each site edit view is constructed based on specific conditions from the admin view's settings.
|
||
|
*
|
||
|
* @param array|null $views The admin views to process.
|
||
|
*
|
||
|
* @return array An array of site edit views, each as an object with view, table, alias, key, and form properties.
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected function getSiteEditViews(?array $views): array
|
||
|
{
|
||
|
$siteEditViews = [];
|
||
|
|
||
|
// Return early if no views are provided.
|
||
|
if (empty($views))
|
||
|
{
|
||
|
return $siteEditViews;
|
||
|
}
|
||
|
|
||
|
foreach ($views as $view)
|
||
|
{
|
||
|
// Check if the view is marked for edit/create on the site.
|
||
|
if (!empty($view['edit_create_site_view']))
|
||
|
{
|
||
|
$siteEditViews[] = (object) [
|
||
|
'view' => $view['settings']->name_single_code,
|
||
|
'View' => StringHelper::safe($view['settings']->name_single_code, 'F'),
|
||
|
'stable' => true,
|
||
|
'target_view' => $view['settings']->name_single_code,
|
||
|
'table' => '#__' . $this->config->component_code_name . '_' . $view['settings']->name_single_code,
|
||
|
'alias' => $this->getSiteEditViewAliasKey($view['settings']->fields ?? null),
|
||
|
'key' => 'id',
|
||
|
'form' => true
|
||
|
];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $siteEditViews;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the site edit view alias key value
|
||
|
*
|
||
|
* This method fetches the alias keys for a given site edit view by matching the view name
|
||
|
* against a list of admin views. It processes the admin views to find a match and then
|
||
|
* retrieves the alias keys from the matched view's settings.
|
||
|
*
|
||
|
* @param string|null $viewName The view name to match.
|
||
|
* @param array $adminViews The admin views to search within.
|
||
|
*
|
||
|
* @return string|null The alias key for the site edit view, or null if not found.
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected function getSiteViewAliasKey(?string $viewName, array $adminViews): ?string
|
||
|
{
|
||
|
// Return early if no view name is provided or admin views are empty.
|
||
|
if ($viewName === null || empty($adminViews))
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
foreach ($adminViews as $view)
|
||
|
{
|
||
|
// Check if the current view matches the specified view name and has fields defined.
|
||
|
if ($view['settings']->name_single_code === $viewName && is_array($view['settings']->fields ?? null))
|
||
|
{
|
||
|
// If a match is found, retrieve and return the site edit view alias keys.
|
||
|
return $this->getSiteEditViewAliasKey($view['settings']->fields);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Return an empty array if no matching view is found.
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the site view alias key value
|
||
|
*
|
||
|
* @param array|null $fields The main get object
|
||
|
*
|
||
|
* @return string|null
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected function getSiteEditViewAliasKey(?array $fields): ?string
|
||
|
{
|
||
|
if ($fields !== null)
|
||
|
{
|
||
|
foreach ($fields as $field)
|
||
|
{
|
||
|
if (isset($field['alias']) && $field['alias'] && $field['type_name'] === 'text')
|
||
|
{
|
||
|
return $field['base_name'];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the view (main selection) table and view name value
|
||
|
* from the main get object
|
||
|
*
|
||
|
* @param array|null $gets The main get objects
|
||
|
*
|
||
|
* @return array
|
||
|
* @since 3.2.0
|
||
|
*/
|
||
|
protected function getMainSelection(?array $gets): array
|
||
|
{
|
||
|
if ($gets !== null)
|
||
|
{
|
||
|
foreach ($gets as $get)
|
||
|
{
|
||
|
// get the main table
|
||
|
if (isset($get['as'])
|
||
|
&& $get['as'] === 'a'
|
||
|
&& isset($get['selection'])
|
||
|
&& ArrayHelper::check($get['selection'])
|
||
|
&& isset($get['selection']['select_gets'])
|
||
|
&& ArrayHelper::check($get['selection']['select_gets'])
|
||
|
&& isset($get['selection']['name']) && isset($get['selection']['table']))
|
||
|
{
|
||
|
$name = $get['selection']['name'];
|
||
|
$view = $get['selection']['view'];
|
||
|
$table = $get['selection']['table'];
|
||
|
|
||
|
return ['table' => $table, 'view' => $view, 'name' => $name];
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return [];
|
||
|
}
|
||
|
}
|
||
|
|