Stable release of v5.0.0-alpha1
First alpha release of Component Builder towards Joomla 5 (very unstable...).
This commit is contained in:
@@ -12,9 +12,11 @@
|
||||
namespace VDM\Joomla\Utilities\Component;
|
||||
|
||||
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\CMS\Factory;
|
||||
use Joomla\CMS\Component\ComponentHelper;
|
||||
use Joomla\Input\Input;
|
||||
use Joomla\Registry\Registry;
|
||||
use VDM\Joomla\Utilities\String\NamespaceHelper;
|
||||
|
||||
|
||||
/**
|
||||
@@ -27,10 +29,18 @@ abstract class Helper
|
||||
/**
|
||||
* The current option
|
||||
*
|
||||
* @var string
|
||||
* @var string|null
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static string $option;
|
||||
public static ?string $option = null;
|
||||
|
||||
/**
|
||||
* The component manifest list cache
|
||||
*
|
||||
* @var array
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static array $manifest = [];
|
||||
|
||||
/**
|
||||
* The component params list cache
|
||||
@@ -67,27 +77,52 @@ abstract class Helper
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the component option
|
||||
* Set the component option
|
||||
*
|
||||
* @param string|null $option The option
|
||||
*
|
||||
* @return void
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function setOption(?string $option): void
|
||||
{
|
||||
self::$option = $option;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the component option
|
||||
*
|
||||
* @param string|null $default The default return value if none is found
|
||||
*
|
||||
* @return string|null A component option
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function getOption(string $default = 'empty'): ?string
|
||||
public static function getOption(?string $default = 'empty'): ?string
|
||||
{
|
||||
if (empty(self::$option))
|
||||
{
|
||||
// get the option from the url input
|
||||
self::$option = (new Input)->getString('option', false);
|
||||
self::$option = (new Input)->getString('option', null);
|
||||
}
|
||||
|
||||
if (self::$option)
|
||||
if (empty(self::$option))
|
||||
{
|
||||
return self::$option;
|
||||
$app = Factory::getApplication();
|
||||
|
||||
// Check if the getInput method exists in the application object
|
||||
if (method_exists($app, 'getInput'))
|
||||
{
|
||||
// get the option from the application
|
||||
self::$option = $app->getInput()->getCmd('option', $default);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the default value if getInput method does not exist
|
||||
self::$option = $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
return self::$option;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -125,24 +160,96 @@ abstract class Helper
|
||||
*
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function get(string $option = null, string $default = null): ?string
|
||||
public static function get(?string $option = null, ?string $default = null): ?string
|
||||
{
|
||||
// check that we have an option
|
||||
// and get the code name from it
|
||||
if (($code_name = self::getCode($option, false)) !== false)
|
||||
if (($code_name = self::getCode($option, null)) !== null)
|
||||
{
|
||||
// we build the helper class name
|
||||
$helper_name = '\\' . \ucfirst($code_name) . 'Helper';
|
||||
|
||||
// check if class exist
|
||||
if (class_exists($helper_name))
|
||||
{
|
||||
return $helper_name;
|
||||
}
|
||||
|
||||
// try loading namespace
|
||||
if (($namespace = self::getNamespace($option)) !== null)
|
||||
{
|
||||
$name = \ucfirst($code_name) . 'Helper';
|
||||
$namespace_helper = '\\' . $namespace . '\Administrator\Helper\\' . NamespaceHelper::safeSegment($name); // TODO target site or admin locations not just admin...
|
||||
if (class_exists($namespace_helper))
|
||||
{
|
||||
return $namespace_helper;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the component namespace if set
|
||||
*
|
||||
* @param string|null $option The option for the component.
|
||||
* @param string|null $default The default return value if none is found
|
||||
*
|
||||
* @return string|null A component namespace
|
||||
*
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function getNamespace(?string $option = null): ?string
|
||||
{
|
||||
$manifest = self::getManifest($option);
|
||||
|
||||
return $manifest->namespace ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the component abstract helper class
|
||||
*
|
||||
* @param string|null $option The option for the component.
|
||||
* @param string|null $default The default return value if none is found
|
||||
*
|
||||
* @return object|null A component helper name
|
||||
*
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function getManifest(?string $option = null): ?object
|
||||
{
|
||||
if ($option === null
|
||||
&& ($option = self::getOption($option)) === null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// get global manifest_cache values
|
||||
if (!isset(self::$manifest[$option]))
|
||||
{
|
||||
$db = Factory::getDbo();
|
||||
$query = $db->getQuery(true);
|
||||
|
||||
$query->select($db->quoteName('manifest_cache'))
|
||||
->from($db->quoteName('#__extensions'))
|
||||
->where($db->quoteName('type') . ' = ' . $db->quote('component'))
|
||||
->where($db->quoteName('element') . ' LIKE ' . $db->quote($option));
|
||||
|
||||
$db->setQuery($query);
|
||||
|
||||
try {
|
||||
$manifest = $db->loadResult();
|
||||
self::$manifest[$option] = json_decode($manifest);
|
||||
} catch (\Exception $e) {
|
||||
// Handle the database error appropriately.
|
||||
self::$manifest[$option] = null;
|
||||
}
|
||||
}
|
||||
|
||||
return self::$manifest[$option];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the helper class of this component has a method
|
||||
*
|
||||
@@ -153,10 +260,10 @@ abstract class Helper
|
||||
*
|
||||
* @since 3.0.11
|
||||
*/
|
||||
public static function methodExists(string $method, string $option = null): bool
|
||||
public static function methodExists(string $method, ?string $option = null): bool
|
||||
{
|
||||
// get the helper class
|
||||
return ($helper = self::get($option, false)) !== false &&
|
||||
return ($helper = self::get($option, null)) !== null &&
|
||||
method_exists($helper, $method);
|
||||
}
|
||||
|
||||
@@ -173,7 +280,7 @@ abstract class Helper
|
||||
public static function _(string $method, array $arguments = [], ?string $option = null)
|
||||
{
|
||||
// get the helper class
|
||||
if (($helper = self::get($option, false)) !== false &&
|
||||
if (($helper = self::get($option, null)) !== null &&
|
||||
method_exists($helper, $method))
|
||||
{
|
||||
// we know this is not ideal...
|
||||
|
@@ -89,8 +89,8 @@ abstract class FileHelper
|
||||
/**
|
||||
* get the content of a file
|
||||
*
|
||||
* @param string $path The path to the file
|
||||
* @param string/bool $none The return value if no content was found
|
||||
* @param string $path The path to the file
|
||||
* @param mixed $none The return value if no content was found
|
||||
*
|
||||
* @return string On success
|
||||
*
|
||||
@@ -150,7 +150,7 @@ abstract class FileHelper
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function write($path, $data)
|
||||
public static function write($path, $data): bool
|
||||
{
|
||||
$klaar = false;
|
||||
if (StringHelper::check($data))
|
||||
@@ -179,11 +179,11 @@ abstract class FileHelper
|
||||
* @param string $folder The local path to parse
|
||||
* @param array $fileTypes The type of files to get
|
||||
*
|
||||
* @return void
|
||||
* @return array|null
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function getPaths($folder, $fileTypes = array('\.php', '\.js', '\.css', '\.less'), $recurse = true, $full = true)
|
||||
public static function getPaths($folder, $fileTypes = array('\.php', '\.js', '\.css', '\.less'), $recurse = true, $full = true): ?array
|
||||
{
|
||||
if (Folder::exists($folder))
|
||||
{
|
||||
@@ -219,7 +219,7 @@ abstract class FileHelper
|
||||
// return array of files
|
||||
return array_map( fn($file) => str_replace('./', '/', (string) $file), (array) ArrayHelper::merge($files));
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,7 +236,7 @@ abstract class FileHelper
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function getPath($type = 'path', $target = 'filepath', $fileType = null, $key = '', $default = '', $createIfNotSet = true)
|
||||
public static function getPath($type = 'path', $target = 'filepath', $fileType = null, $key = '', $default = '', $createIfNotSet = true): string
|
||||
{
|
||||
// make sure to always have a string/path
|
||||
if(!StringHelper::check($default))
|
||||
@@ -316,7 +316,7 @@ abstract class FileHelper
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function exists($path)
|
||||
public static function exists($path): bool
|
||||
{
|
||||
$exists = false;
|
||||
// if this is a local path
|
||||
|
@@ -75,24 +75,24 @@ abstract class FormHelper
|
||||
// element was not returned
|
||||
return;
|
||||
}
|
||||
switch (get_class($node))
|
||||
|
||||
if ($node instanceof \stdClass)
|
||||
{
|
||||
case 'stdClass':
|
||||
if (property_exists($node, 'comment'))
|
||||
{
|
||||
self::comment($xml, $node->comment);
|
||||
}
|
||||
if (property_exists($node, 'fieldXML'))
|
||||
{
|
||||
self::append($xml, $node->fieldXML);
|
||||
}
|
||||
break;
|
||||
case 'SimpleXMLElement':
|
||||
$domXML = \dom_import_simplexml($xml);
|
||||
$domNode = \dom_import_simplexml($node);
|
||||
$domXML->appendChild($domXML->ownerDocument->importNode($domNode, true));
|
||||
$xml = \simplexml_import_dom($domXML);
|
||||
break;
|
||||
if (property_exists($node, 'comment'))
|
||||
{
|
||||
self::comment($xml, $node->comment);
|
||||
}
|
||||
if (property_exists($node, 'fieldXML'))
|
||||
{
|
||||
self::append($xml, $node->fieldXML);
|
||||
}
|
||||
}
|
||||
elseif ($node instanceof \SimpleXMLElement)
|
||||
{
|
||||
$domXML = \dom_import_simplexml($xml);
|
||||
$domNode = \dom_import_simplexml($node);
|
||||
$domXML->appendChild($domXML->ownerDocument->importNode($domNode, true));
|
||||
$xml = \simplexml_import_dom($domXML);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ abstract class FormHelper
|
||||
{
|
||||
foreach ($attributes as $key => $value)
|
||||
{
|
||||
$xml->addAttribute($key, $value);
|
||||
$xml->addAttribute($key, $value ?? '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ abstract class FormHelper
|
||||
foreach ($options as $key => $value)
|
||||
{
|
||||
$addOption = $xml->addChild('option');
|
||||
$addOption->addAttribute('value', $key);
|
||||
$addOption->addAttribute('value', $key ?? '');
|
||||
$addOption[] = $value;
|
||||
}
|
||||
}
|
||||
|
@@ -113,14 +113,14 @@ abstract class GetHelper
|
||||
$where = Factory::getUser()->id;
|
||||
}
|
||||
|
||||
if(is_null($main))
|
||||
if($main === null)
|
||||
{
|
||||
$main = Helper::getCode();
|
||||
}
|
||||
|
||||
if (!ArrayHelper::check($where) && $where > 0)
|
||||
{
|
||||
$where = array($where);
|
||||
$where = [$where];
|
||||
}
|
||||
|
||||
if (ArrayHelper::check($where))
|
||||
|
@@ -138,7 +138,7 @@ abstract class GuidHelper
|
||||
* @param string|array $what
|
||||
* @param string|null $component
|
||||
*
|
||||
* @return mix
|
||||
* @return mixed
|
||||
*
|
||||
* @since 3.0.9
|
||||
*/
|
||||
|
@@ -38,30 +38,41 @@ abstract class NamespaceHelper
|
||||
// Split the string into namespace segments
|
||||
$segments = explode('\\', $string);
|
||||
|
||||
foreach ($segments as &$segment)
|
||||
{
|
||||
// Check if segment starts with a number
|
||||
if (preg_match("/^\d/", $segment))
|
||||
{
|
||||
// Extract the starting number(s)
|
||||
preg_match("/^\d+/", $segment, $matches);
|
||||
|
||||
if (isset($matches[0]))
|
||||
{
|
||||
$numberWord = StringHelper::numbers($matches[0]);
|
||||
$segment = str_replace($matches[0], $numberWord, $segment);
|
||||
}
|
||||
}
|
||||
|
||||
// Transliterate string TODO: look again as this makes it lowercase
|
||||
// $segment = StringHelper::transliterate($segment);
|
||||
|
||||
// Make sure segment only contains valid characters
|
||||
$segment = preg_replace("/[^A-Za-z0-9]/", '', $segment);
|
||||
}
|
||||
// make each segment safe
|
||||
$segments = array_map([self::class, 'safeSegment'], $segments);
|
||||
|
||||
// Join the namespace segments back together
|
||||
return implode('\\', $segments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Making one namespace segment safe
|
||||
*
|
||||
* @param string $string The namespace segment string you would like to make safe
|
||||
*
|
||||
* @return string on success
|
||||
* @since 3.0.9
|
||||
*/
|
||||
public static function safeSegment(string $string): string
|
||||
{
|
||||
// Check if segment starts with a number
|
||||
if (preg_match("/^\d/", $string))
|
||||
{
|
||||
// Extract the starting number(s)
|
||||
preg_match("/^\d+/", $string, $matches);
|
||||
|
||||
if (isset($matches[0]))
|
||||
{
|
||||
$numberWord = StringHelper::numbers($matches[0]);
|
||||
$string = str_replace($matches[0], $numberWord, $string);
|
||||
}
|
||||
}
|
||||
|
||||
// Transliterate string TODO: look again as this makes it lowercase
|
||||
// $segment = StringHelper::transliterate($segment);
|
||||
|
||||
// Make sure segment only contains valid characters
|
||||
return preg_replace("/[^A-Za-z0-9]/", '', $string);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -50,18 +50,18 @@ abstract class StringHelper
|
||||
/**
|
||||
* Shorten a string
|
||||
*
|
||||
* @input string The you would like to shorten
|
||||
* @input string The sting that you would like to shorten
|
||||
*
|
||||
* @returns string on success
|
||||
*
|
||||
* @since 3.0.9
|
||||
* @since 3.2.0
|
||||
*/
|
||||
public static function shorten($string, $length = 40, $addTip = true)
|
||||
{
|
||||
if (self::check($string))
|
||||
{
|
||||
$initial = strlen((string) $string);
|
||||
$words = preg_split('/([\s\n\r]+)/', (string) $string, null, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$words = preg_split('/([\s\n\r]+)/', (string) $string, -1, PREG_SPLIT_DELIM_CAPTURE);
|
||||
$words_count = count((array)$words);
|
||||
|
||||
$word_length = 0;
|
||||
|
Reference in New Issue
Block a user