Fixed issue #957 to load classes namespace. Refactored search classes. Improved the Power compiler class.

This commit is contained in:
2022-10-06 19:34:44 +02:00
parent dcb4f86ee2
commit 9db33ad449
40 changed files with 447 additions and 257 deletions

View File

@@ -44,6 +44,14 @@ class Power implements PowerInterface
**/
public array $active = [];
/**
* The url to the power, if there is an error.
*
* @var string
* @since 3.2.0
**/
protected string $fixUrl;
/**
* The state of all loaded powers
*
@@ -200,7 +208,7 @@ class Power implements PowerInterface
$tmp_lang_target = $this->config->lang_target;
$this->config->lang_target = 'both';
// we set the fix usr if needed
$fix_url
$this->fixUrl
= '"index.php?option=com_componentbuilder&view=powers&task=power.edit&id='
. $this->active[$guid]->id . '" target="_blank"';
// set some keys
@@ -219,217 +227,37 @@ class Power implements PowerInterface
$this->active[$guid]->official_name = StringHelper::safe(
$this->active[$guid]->name, 'W'
);
// set namespace
$this->active[$guid]->namespace = $this->placeholder->update(
$this->active[$guid]->namespace, $this->placeholder->active
);
// validate namespace
if (strpos($this->active[$guid]->namespace, '\\') === false)
// set name space
if (!$this->setNamespace($guid))
{
// we raise an error message
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_HTHREES_NAMESPACE_ERROR_SHTHREEPYOU_MUST_ATLEAST_HAVE_TWO_SECTIONS_IN_YOUR_NAMESPACE_YOU_JUST_HAVE_ONE_THIS_IS_AN_UNACCEPTABLE_ACTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPTHIS_S_WAS_THEREFORE_REMOVED_A_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP',
ucfirst($this->active[$guid]->type), $this->active[$guid]->name, $this->active[$guid]->namespace,
'"https://www.php-fig.org/psr/psr-4/" target="_blank"', $this->active[$guid]->type,
$fix_url),
'Error'
);
$this->state[$guid] = false;
unset($this->active[$guid]);
// reset back to starting value
$this->config->lang_target = $tmp_lang_target;
// we break out here
return false;
}
else
{
// setup the path array
$path_array = (array) explode('\\', $this->active[$guid]->namespace);
// make sure all sub folders in src dir is set and remove all characters that will not work in folders naming
$this->active[$guid]->namespace = NamespaceHelper::safe(str_replace('.', '\\', $this->active[$guid]->namespace));
// make sure it has two or more
if (ArrayHelper::check($path_array) <= 1)
{
// we raise an error message
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_HTHREES_NAMESPACE_ERROR_SHTHREEPYOU_MUST_ATLEAST_HAVE_TWO_SECTIONS_IN_YOUR_NAMESPACE_YOU_JUST_HAVE_ONE_S_THIS_IS_AN_UNACCEPTABLE_ACTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPTHIS_S_WAS_THEREFORE_REMOVED_A_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP',
ucfirst($this->active[$guid]->type), $this->active[$guid]->name, $this->active[$guid]->namespace,
'"https://www.php-fig.org/psr/psr-4/" target="_blank"', $this->active[$guid]->type,
$fix_url),
'Error'
);
$this->state[$guid] = false;
unset($this->active[$guid]);
// reset back to starting value
$this->config->lang_target = $tmp_lang_target;
// we break out here
return false;
}
// get the file and class name (the last value in array)
$file_name = array_pop($path_array);
// src array bucket
$src_array = array();
// do we have src folders
if (strpos($file_name, '.') !== false)
{
// we have src folders in the namespace
$src_array = (array) explode('.', $file_name);
// get the file and class name (the last value in array)
$this->active[$guid]->file_name = array_pop($src_array);
// namespace array
$namespace_array = array_merge($path_array, $src_array);
}
else
{
// set the file name
$this->active[$guid]->file_name = $file_name;
// namespace array
$namespace_array = $path_array;
}
// the last value is the same as the class name
if ($this->active[$guid]->file_name !== $this->active[$guid]->class_name)
{
// we raise an error message
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_PS_NAMING_MISMATCH_ERROR_SPPTHE_S_NAME_IS_BSB_AND_THE_ENDING_FILE_NAME_IN_THE_NAMESPACE_IS_BSB_THIS_IS_BAD_CONVENTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPA_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP',
ucfirst($this->active[$guid]->type), $this->active[$guid]->name, $this->active[$guid]->type, $this->active[$guid]->class_name, $this->active[$guid]->file_name,
'"https://www.php-fig.org/psr/psr-4/" target="_blank"',
$fix_url),
'Error'
);
$this->state[$guid] = false;
unset($this->active[$guid]);
// reset back to starting value
$this->config->lang_target = $tmp_lang_target;
// we break out here
return false;
}
// make sure the arrays are namespace safe
$path_array = array_map(function ($val) {
return NamespaceHelper::safe($val);
}, $path_array);
$namespace_array = array_map(function ($val) {
return NamespaceHelper::safe($val);
}, $namespace_array);
// set the actual class namespace
$this->active[$guid]->_namespace = implode('\\', $namespace_array);
// prefix values
$this->active[$guid]->_namespace_prefix = $path_array;
// get the parent folder (the first value in array)
$prefix_folder = implode('.', $path_array);
// make sub folders if still found
$sub_folder = '';
if (ArrayHelper::check($src_array))
{
// make sure the arrays are namespace safe
$sub_folder = '/' . implode('/', array_map(function ($val) {
return NamespaceHelper::safe($val);
}, $src_array));
}
// now we set the paths
$this->active[$guid]->path_jcb = $this->config->get('jcb_powers_path', 'libraries/jcb_powers');
$this->active[$guid]->path_parent = $this->active[$guid]->path_jcb . '/' . $prefix_folder;
$this->active[$guid]->path = $this->active[$guid]->path_parent . '/src' . $sub_folder;
}
// load use ids
$use = array();
$as = array();
// check if we have use selection
$this->active[$guid]->use_selection = (isset($this->active[$guid]->use_selection)
&& JsonHelper::check(
$this->active[$guid]->use_selection
)) ? json_decode($this->active[$guid]->use_selection, true) : null;
if ($this->active[$guid]->use_selection)
{
$use = array_values(array_map(function ($u) use(&$as) {
// track the AS options
if (empty($u['as']))
{
$as[$u['use']] = 'default';
}
else
{
$as[$u['use']] = (string) $u['as'];
}
// return the guid
return $u['use'];
}, $this->active[$guid]->use_selection));
}
// check if we have load selection
$this->active[$guid]->load_selection = (isset($this->active[$guid]->load_selection)
&& JsonHelper::check(
$this->active[$guid]->load_selection
)) ? json_decode($this->active[$guid]->load_selection, true) : null;
if ($this->active[$guid]->load_selection)
{
// load use ids
array_map(function ($l) {
// just load it directly and be done with it
return $this->set($l['load']);
}, $this->active[$guid]->load_selection);
}
// see if we have implements
$this->active[$guid]->implement_names = array();
// does this implement
$this->active[$guid]->implements = (isset($this->active[$guid]->implements)
&& JsonHelper::check(
$this->active[$guid]->implements
)) ? json_decode($this->active[$guid]->implements, true) : null;
if ($this->active[$guid]->implements)
{
foreach ($this->active[$guid]->implements as $implement)
{
if ($implement == -1
&& StringHelper::check($this->active[$guid]->implements_custom))
{
$this->active[$guid]->implement_names[] = $this->placeholder->update(
$this->customcode->update($this->active[$guid]->implements_custom),
$this->placeholder->active
);
// just add this once
unset($this->active[$guid]->implements_custom);
}
// does this extend existing
elseif (GuidHelper::valid($implement))
{
// check if it was set
if ($this->set($implement))
{
// get the name
$this->active[$guid]->implement_names[] = $this->get($implement, 1)->class_name;
// add to use
$use[] = $implement;
}
}
}
}
// does this extend something
$this->active[$guid]->extends_name = null;
// we first check for custom extending options
if ($this->active[$guid]->extends == -1
&& StringHelper::check($this->active[$guid]->extends_custom))
{
$this->active[$guid]->extends_name = $this->placeholder->update(
$this->customcode->update($this->active[$guid]->extends_custom),
$this->placeholder->active
);
// just add once
unset($this->active[$guid]->extends_custom);
}
// does this extend existing
elseif (GuidHelper::valid($this->active[$guid]->extends))
{
// check if it was set
if ($this->set($this->active[$guid]->extends))
{
// get the name
$this->active[$guid]->extends_name = $this->get($this->active[$guid]->extends, 1)->class_name;
// add to use
$use[] = $this->active[$guid]->extends;
}
}
$use = [];
$as = [];
// set extra classes
$this->setLoadSelection($guid);
// set use classes
$this->setUseSelection($guid, $use, $as);
// set implement interfaces
$this->setImplements($guid, $use);
// set extend class
$this->setExtend($guid, $use);
// set GUI mapper
$guiMapper = array('table' => 'power', 'id' => (int) $this->active[$guid]->id, 'type' => 'php');
// add the licensing template
if ($this->active[$guid]->add_licensing_template == 2 &&
StringHelper::check($this->active[$guid]->licensing_template))
@@ -453,6 +281,7 @@ class Power implements PowerInterface
$this->active[$guid]->add_licensing_template = 1;
$this->active[$guid]->licensing_template = '';
}
// add the header script
if ($this->active[$guid]->add_head == 1)
{
@@ -470,35 +299,13 @@ class Power implements PowerInterface
$guiMapper
) . PHP_EOL;
}
// now add all the extra use statements
if (ArrayHelper::check($use))
{
foreach (array_unique($use) as $u)
{
if ($this->set($u))
{
$add_use = $this->get($u, 1)->namespace;
// check if it is already added manually, you know how some people are
if (strpos($this->active[$guid]->head, $add_use) === false)
{
// check if it has an AS option
if (isset($as[$u]) && StringHelper::check($as[$u]) && $as[$u] !== 'default')
{
$this->active[$guid]->head .= 'use ' . $add_use . ' as ' . $as[$u] . ';' . PHP_EOL;
}
else
{
$this->active[$guid]->head .= 'use ' . $add_use . ';' . PHP_EOL;
}
}
}
}
}
// now set the description
$this->active[$guid]->description = (StringHelper::check($this->active[$guid]->description)) ? $this->placeholder->update(
$this->customcode->update($this->active[$guid]->description),
$this->placeholder->active
) : '';
// add the main code if set
if (StringHelper::check($this->active[$guid]->main_class_code))
{
@@ -516,6 +323,10 @@ class Power implements PowerInterface
$guiMapper
);
}
// load the use classes
$this->setUseAs($guid, $use, $as);
// reset back to starting value
$this->config->lang_target = $tmp_lang_target;
@@ -536,6 +347,327 @@ class Power implements PowerInterface
$this->state[$guid] = false;
return false;
}
}
/**
* Set the namespace for this power
*
* @param string $guid The global unique id of the power
*
* @return void
* @since 3.2.0
*/
protected function setNamespace(string $guid)
{
// set namespace
$this->active[$guid]->namespace = $this->placeholder->update(
$this->active[$guid]->namespace, $this->placeholder->active
);
// validate namespace
if (strpos($this->active[$guid]->namespace, '\\') === false)
{
// we raise an error message
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_HTHREES_NAMESPACE_ERROR_SHTHREEPYOU_MUST_ATLEAST_HAVE_TWO_SECTIONS_IN_YOUR_NAMESPACE_YOU_JUST_HAVE_ONE_THIS_IS_AN_UNACCEPTABLE_ACTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPTHIS_S_WAS_THEREFORE_REMOVED_A_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP',
ucfirst($this->active[$guid]->type), $this->active[$guid]->name, $this->active[$guid]->namespace,
'"https://www.php-fig.org/psr/psr-4/" target="_blank"', $this->active[$guid]->type,
$this->fixUrl),
'Error'
);
// we break out here
return false;
}
// setup the path array
$path_array = (array) explode('\\', $this->active[$guid]->namespace);
// make sure all sub folders in src dir is set and remove all characters that will not work in folders naming
$this->active[$guid]->namespace = NamespaceHelper::safe(str_replace('.', '\\', $this->active[$guid]->namespace));
// make sure it has two or more
if (ArrayHelper::check($path_array) <= 1)
{
// we raise an error message
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_HTHREES_NAMESPACE_ERROR_SHTHREEPYOU_MUST_ATLEAST_HAVE_TWO_SECTIONS_IN_YOUR_NAMESPACE_YOU_JUST_HAVE_ONE_S_THIS_IS_AN_UNACCEPTABLE_ACTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPTHIS_S_WAS_THEREFORE_REMOVED_A_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP',
ucfirst($this->active[$guid]->type), $this->active[$guid]->name, $this->active[$guid]->namespace,
'"https://www.php-fig.org/psr/psr-4/" target="_blank"', $this->active[$guid]->type,
$this->fixUrl),
'Error'
);
// we break out here
return false;
}
// get the file and class name (the last value in array)
$file_name = array_pop($path_array);
// src array bucket
$src_array = [];
// do we have src folders
if (strpos($file_name, '.') !== false)
{
// we have src folders in the namespace
$src_array = (array) explode('.', $file_name);
// get the file and class name (the last value in array)
$this->active[$guid]->file_name = array_pop($src_array);
// namespace array
$namespace_array = array_merge($path_array, $src_array);
}
else
{
// set the file name
$this->active[$guid]->file_name = $file_name;
// namespace array
$namespace_array = $path_array;
}
// the last value is the same as the class name
if ($this->active[$guid]->file_name !== $this->active[$guid]->class_name)
{
// we raise an error message
$this->app->enqueueMessage(
Text::sprintf('COM_COMPONENTBUILDER_PS_NAMING_MISMATCH_ERROR_SPPTHE_S_NAME_IS_BSB_AND_THE_ENDING_FILE_NAME_IN_THE_NAMESPACE_IS_BSB_THIS_IS_BAD_CONVENTION_PLEASE_SEE_A_HREFS_PSRFOURA_FOR_MORE_INFOPPA_HREFSCLICK_HEREA_TO_FIX_THIS_ISSUEP',
ucfirst($this->active[$guid]->type), $this->active[$guid]->name, $this->active[$guid]->type, $this->active[$guid]->class_name, $this->active[$guid]->file_name,
'"https://www.php-fig.org/psr/psr-4/" target="_blank"',
$this->fixUrl),
'Error'
);
// we break out here
return false;
}
// make sure the arrays are namespace safe
$path_array = array_map(function ($val) {
return NamespaceHelper::safe($val);
}, $path_array);
$namespace_array = array_map(function ($val) {
return NamespaceHelper::safe($val);
}, $namespace_array);
// set the actual class namespace
$this->active[$guid]->_namespace = implode('\\', $namespace_array);
// prefix values
$this->active[$guid]->_namespace_prefix = $path_array;
// get the parent folder (the first value in array)
$prefix_folder = implode('.', $path_array);
// make sub folders if still found
$sub_folder = '';
if (ArrayHelper::check($src_array))
{
// make sure the arrays are namespace safe
$sub_folder = '/' . implode('/', array_map(function ($val) {
return NamespaceHelper::safe($val);
}, $src_array));
}
// now we set the paths
$this->active[$guid]->path_jcb = $this->config->get('jcb_powers_path', 'libraries/jcb_powers');
$this->active[$guid]->path_parent = $this->active[$guid]->path_jcb . '/' . $prefix_folder;
$this->active[$guid]->path = $this->active[$guid]->path_parent . '/src' . $sub_folder;
return true;
}
/**
* Set Use Classess
*
* @param string $guid The global unique id of the power
* @param array $use The use array
* @param array $as The use as array
*
* @return void
* @since 3.2.0
*/
protected function setUseSelection(string $guid, array &$use, array &$as)
{
// check if we have use selection
$this->active[$guid]->use_selection = (isset($this->active[$guid]->use_selection)
&& JsonHelper::check(
$this->active[$guid]->use_selection
)) ? json_decode($this->active[$guid]->use_selection, true) : null;
if ($this->active[$guid]->use_selection)
{
$use = array_values(array_map(function ($u) use(&$as) {
// track the AS options
if (empty($u['as']))
{
$as[$u['use']] = 'default';
}
else
{
$as[$u['use']] = (string) $u['as'];
}
// return the guid
return $u['use'];
}, $this->active[$guid]->use_selection));
}
}
/**
* Load Extra Classes
*
* @param string $guid The global unique id of the power
*
* @return void
* @since 3.2.0
*/
protected function setLoadSelection(string $guid)
{
// check if we have load selection
$this->active[$guid]->load_selection = (isset($this->active[$guid]->load_selection)
&& JsonHelper::check(
$this->active[$guid]->load_selection
)) ? json_decode($this->active[$guid]->load_selection, true) : null;
if ($this->active[$guid]->load_selection)
{
// load use ids
array_map(function ($power) {
// just load it directly and be done with it
return $this->set($power['load']);
}, $this->active[$guid]->load_selection);
}
}
/**
* Set Implements Interface classes
*
* @param string $guid The global unique id of the power
* @param array $use The use array
*
* @return void
* @since 3.2.0
*/
protected function setImplements(string $guid, array &$use)
{
// see if we have implements
$this->active[$guid]->implement_names = [];
// does this implement
$this->active[$guid]->implements = (isset($this->active[$guid]->implements)
&& JsonHelper::check(
$this->active[$guid]->implements
)) ? json_decode($this->active[$guid]->implements, true) : null;
if ($this->active[$guid]->implements)
{
foreach ($this->active[$guid]->implements as $implement)
{
if ($implement == -1
&& StringHelper::check($this->active[$guid]->implements_custom))
{
$this->active[$guid]->implement_names[] = $this->placeholder->update(
$this->customcode->update($this->active[$guid]->implements_custom),
$this->placeholder->active
);
// just add this once
unset($this->active[$guid]->implements_custom);
}
// does this extend existing
elseif (GuidHelper::valid($implement))
{
// check if it was set
if ($this->set($implement))
{
// get the name
$this->active[$guid]->implement_names[] = $this->get($implement, 1)->class_name;
// add to use
$use[] = $implement;
}
}
}
}
}
/**
* Set Extend Class
*
* @param string $guid The global unique id of the power
* @param array $use The use array
*
* @return void
* @since 3.2.0
*/
protected function setExtend(string $guid, array &$use)
{
// does this extend something
$this->active[$guid]->extends_name = null;
// we first check for custom extending options
if ($this->active[$guid]->extends == -1
&& StringHelper::check($this->active[$guid]->extends_custom))
{
$this->active[$guid]->extends_name = $this->placeholder->update(
$this->customcode->update($this->active[$guid]->extends_custom),
$this->placeholder->active
);
// just add once
unset($this->active[$guid]->extends_custom);
}
// does this extend existing
elseif (GuidHelper::valid($this->active[$guid]->extends))
{
// check if it was set
if ($this->set($this->active[$guid]->extends))
{
// get the name
$this->active[$guid]->extends_name = $this->get($this->active[$guid]->extends, 1)->class_name;
// add to use
$use[] = $this->active[$guid]->extends;
}
}
}
/**
* Set Extra Use Classes
*
* @param string $guid The global unique id of the power
* @param array $use The use array
*
* @return void
* @since 3.2.0
*/
protected function setUseAs($guid, $use, $as)
{
// now add all the extra use statements
if (ArrayHelper::check($use))
{
foreach (array_unique($use) as $u)
{
if ($this->set($u))
{
// get the namespace
$add_use = $this->get($u, 1)->namespace;
// check if it has an AS option
if (isset($as[$u]) && StringHelper::check($as[$u]) && $as[$u] !== 'default')
{
$add_use = 'use ' . $add_use . ' as ' . $as[$u] . ';';
}
else
{
$add_use = 'use ' . $add_use . ';';
}
// check if it is already added manually
if (strpos($this->active[$guid]->head, $add_use) === false)
{
$this->active[$guid]->head .= $add_use . PHP_EOL;
}
}
}
}
}
}