HtmlBuilder: change all return error to Throw, update Element/StrinReplace
We do not return old style bool on error, we throw Exceptions: HtmlBuilderExcpetion Element has more classes to set tag, id, etc with basic checks for valid data String Replace to set strings is one array with key -> value entries Errors thrown on index for element/replace blocks
This commit is contained in:
@@ -6,11 +6,15 @@
|
||||
* DESCRIPTION:
|
||||
* html builder: array
|
||||
* static build for array lists (not objects)
|
||||
*
|
||||
* Recommended to use the Object one or for speed the String Replace
|
||||
*/
|
||||
|
||||
namespace CoreLibs\Template\HtmlBuilder;
|
||||
|
||||
use CoreLibs\Template\HtmlBuilder\General\Settings;
|
||||
use CoreLibs\Template\HtmlBuilder\General\Error;
|
||||
use CoreLibs\Template\HtmlBuilder\General\HtmlBuilderExcpetion;
|
||||
|
||||
class Block
|
||||
{
|
||||
@@ -22,6 +26,7 @@ class Block
|
||||
* @param string $content
|
||||
* @param array<string> $css,
|
||||
* @param array<string,string> $options
|
||||
* @throws HtmlBuilderExcpetion
|
||||
*/
|
||||
public static function cel(
|
||||
string $tag,
|
||||
@@ -30,6 +35,14 @@ class Block
|
||||
array $css = [],
|
||||
array $options = []
|
||||
): array {
|
||||
if (!preg_match("/^[A-Za-z]+$/", $tag)) {
|
||||
Error::setError(
|
||||
'201',
|
||||
'invalid or empty tag',
|
||||
['tag' => $tag]
|
||||
);
|
||||
throw new HtmlBuilderExcpetion('Invalid or empty tag');
|
||||
}
|
||||
return [
|
||||
'tag' => $tag,
|
||||
'id' => $id,
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace CoreLibs\Template\HtmlBuilder;
|
||||
|
||||
use CoreLibs\Template\HtmlBuilder\General\Settings;
|
||||
use CoreLibs\Template\HtmlBuilder\General\Error;
|
||||
use CoreLibs\Template\HtmlBuilder\General\HtmlBuilderExcpetion;
|
||||
|
||||
class Element
|
||||
{
|
||||
@@ -46,6 +47,7 @@ class Element
|
||||
* eg: onClick => 'something();'
|
||||
* id, css are skipped
|
||||
* name only set on input/button
|
||||
* @throws HtmlBuilderExcpetion
|
||||
*/
|
||||
public function __construct(
|
||||
string $tag,
|
||||
@@ -54,6 +56,28 @@ class Element
|
||||
array $css = [],
|
||||
array $options = []
|
||||
) {
|
||||
// exit if not valid tag
|
||||
try {
|
||||
$this->setTag($tag);
|
||||
} catch (HtmlBuilderExcpetion $e) {
|
||||
throw new HtmlBuilderExcpetion('Could not create Element', 0, $e);
|
||||
}
|
||||
$this->setId($id);
|
||||
$this->setName($options['name'] ?? '');
|
||||
$this->setContent($content);
|
||||
$this->addCss(...$css);
|
||||
$this->setOptions($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* set tag
|
||||
*
|
||||
* @param string $tag
|
||||
* @return void
|
||||
* @throws HtmlBuilderExcpetion
|
||||
*/
|
||||
public function setTag(string $tag): void
|
||||
{
|
||||
// tag must be letters only
|
||||
if (!preg_match("/^[A-Za-z]+$/", $tag)) {
|
||||
Error::setError(
|
||||
@@ -61,9 +85,29 @@ class Element
|
||||
'invalid or empty tag',
|
||||
['tag' => $tag]
|
||||
);
|
||||
return;
|
||||
throw new HtmlBuilderExcpetion('Invalid or empty tag');
|
||||
}
|
||||
$this->tag = $tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the tag name
|
||||
*
|
||||
* @return string HTML element tag
|
||||
*/
|
||||
public function getTag(): string
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
|
||||
/**
|
||||
* set the element id
|
||||
*
|
||||
* @param string $id
|
||||
* @return void
|
||||
*/
|
||||
public function setId(string $id): void
|
||||
{
|
||||
// invalid id and name check too
|
||||
// be strict: [a-zA-Z0-9], -, _
|
||||
// cannot start with digit, two hyphens or a hyphen with a digit:
|
||||
@@ -77,63 +121,11 @@ class Element
|
||||
Error::setWarning(
|
||||
'202',
|
||||
'possible invalid id',
|
||||
['id' => $id, 'tag' => $this->tag]
|
||||
['id' => $id, 'tag' => $this->getTag()]
|
||||
);
|
||||
// TODO: shoud throw error
|
||||
}
|
||||
$this->id = $id;
|
||||
if (
|
||||
!empty($options['name']) &&
|
||||
!preg_match("/^[A-Za-z][\w-]*$/", $options['name'])
|
||||
) {
|
||||
Error::setWarning(
|
||||
'203',
|
||||
'possible invalid name',
|
||||
['name' => $options['name'], 'id' => $this->id, 'tag' => $this->tag]
|
||||
);
|
||||
}
|
||||
// same as id
|
||||
$this->name = $options['name'] ?? '';
|
||||
// anything allowed
|
||||
$this->content = $content;
|
||||
// should do check for empty/invalid css
|
||||
foreach ($css as $_css) {
|
||||
if (empty($_css)) {
|
||||
Error::setError(
|
||||
'204',
|
||||
'cannot have empty css string',
|
||||
);
|
||||
continue;
|
||||
}
|
||||
// -?[_A-Za-z][_A-Za-z0-9-]*
|
||||
if (!preg_match("/^-?[_A-Za-z][_A-Za-z0-9-]*$/", $_css)) {
|
||||
Error::setWarning(
|
||||
'205',
|
||||
'possible invalid css string',
|
||||
['css' => $_css, 'id' => $this->id, 'tag' => $this->tag]
|
||||
);
|
||||
}
|
||||
$this->css[] = $_css;
|
||||
}
|
||||
// some basic options check
|
||||
foreach ($options as $key => $value) {
|
||||
if (empty($key)) {
|
||||
Error::setError(
|
||||
'110',
|
||||
'Cannot set option with empty key',
|
||||
['id' => $this->id, 'tag' => $this->tag]
|
||||
);
|
||||
continue;
|
||||
}
|
||||
if ($value === null) {
|
||||
Error::setError(
|
||||
'210',
|
||||
'Cannot set option with null value',
|
||||
['id' => $this->id, 'tag' => $this->tag]
|
||||
);
|
||||
continue;
|
||||
}
|
||||
$this->options[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,13 +139,26 @@ class Element
|
||||
}
|
||||
|
||||
/**
|
||||
* get the tag name
|
||||
* Set name for elements
|
||||
* only for elements that need it (input/button/form)
|
||||
*
|
||||
* @return string HTML element tag
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
public function getTag(): string
|
||||
public function setName(string $name): void
|
||||
{
|
||||
return $this->tag;
|
||||
if (
|
||||
!empty($name) &&
|
||||
!preg_match("/^[A-Za-z][\w-]*$/", $name)
|
||||
) {
|
||||
Error::setWarning(
|
||||
'203',
|
||||
'possible invalid name',
|
||||
['name' => $name, 'id' => $this->getId(), 'tag' => $this->getTag()]
|
||||
);
|
||||
// TODO: shoud throw error
|
||||
}
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,11 +207,21 @@ class Element
|
||||
'Cannot set option with empty key',
|
||||
['id' => $this->getId(), 'tag' => $this->getTag()]
|
||||
);
|
||||
// TODO: shoud throw error
|
||||
continue;
|
||||
}
|
||||
// if data is null
|
||||
if ($value === null) {
|
||||
unset($this->options[$key]);
|
||||
if (isset($this->options[$key])) {
|
||||
unset($this->options[$key]);
|
||||
} else {
|
||||
Error::setError(
|
||||
'210',
|
||||
'Cannot set option with null value',
|
||||
['id' => $this->getId(), 'tag' => $this->getTag()]
|
||||
);
|
||||
}
|
||||
// TODO: shoud throw error
|
||||
continue;
|
||||
}
|
||||
$this->options[$key] = $value;
|
||||
@@ -243,6 +258,7 @@ class Element
|
||||
*
|
||||
* @param Element $sub One or many elements to add
|
||||
* @return void
|
||||
* @throws HtmlBuilderExcpetion
|
||||
*/
|
||||
public function addSub(Element ...$sub): void
|
||||
{
|
||||
@@ -252,10 +268,10 @@ class Element
|
||||
if ($_sub == $this) {
|
||||
Error::setError(
|
||||
'100',
|
||||
'Cannot assign Element, this would create a loop',
|
||||
'Cannot assign Element to itself, this would create an infinite loop',
|
||||
['id' => $this->getId(), 'tag' => $this->getTag()]
|
||||
);
|
||||
continue;
|
||||
throw new HtmlBuilderExcpetion('Cannot assign Element to itself, this would create an infinite loop');
|
||||
}
|
||||
array_push($this->sub, $_sub);
|
||||
}
|
||||
@@ -319,7 +335,29 @@ class Element
|
||||
*/
|
||||
public function addCss(string ...$css): Element
|
||||
{
|
||||
$this->css = array_unique(array_merge($this->css, $css));
|
||||
// should do check for empty/invalid css
|
||||
$_set_css = [];
|
||||
foreach ($css as $_css) {
|
||||
if (empty($_css)) {
|
||||
Error::setError(
|
||||
'204',
|
||||
'cannot have empty css string',
|
||||
);
|
||||
// TODO: shoud throw error
|
||||
continue;
|
||||
}
|
||||
// -?[_A-Za-z][_A-Za-z0-9-]*
|
||||
if (!preg_match("/^-?[_A-Za-z][_A-Za-z0-9-]*$/", $_css)) {
|
||||
Error::setWarning(
|
||||
'205',
|
||||
'possible invalid css string',
|
||||
['css' => $_css, 'id' => $this->id, 'tag' => $this->tag]
|
||||
);
|
||||
// TODO: shoud throw error
|
||||
}
|
||||
$_set_css[] = $_css;
|
||||
}
|
||||
$this->css = array_unique(array_merge($this->css, $_set_css));
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* AUTOR: Clemens Schwaighofer
|
||||
* CREATED: 2023/6/28
|
||||
* DESCRIPTION:
|
||||
* Exception class for the HtmlBuilder blocks
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace CoreLibs\Template\HtmlBuilder\General;
|
||||
|
||||
/**
|
||||
* Exception class for HtmlBuilder
|
||||
*/
|
||||
class HtmlBuilderExcpetion extends \Exception
|
||||
{
|
||||
}
|
||||
|
||||
// __END__
|
||||
@@ -12,12 +12,13 @@ declare(strict_types=1);
|
||||
namespace CoreLibs\Template\HtmlBuilder;
|
||||
|
||||
use CoreLibs\Template\HtmlBuilder\General\Error;
|
||||
use CoreLibs\Template\HtmlBuilder\General\HtmlBuilderExcpetion;
|
||||
|
||||
class StringReplace
|
||||
{
|
||||
/** @var array<string,string> */
|
||||
private static array $elements = [];
|
||||
/** @var array<string,array<string,string>> */
|
||||
/** @var array<string,string> */
|
||||
private static array $replace = [];
|
||||
|
||||
/**
|
||||
@@ -28,16 +29,14 @@ class StringReplace
|
||||
* if same index is tried twice it will set an error and skip
|
||||
*
|
||||
* @param array<string,string> ...$element Elements to load
|
||||
* @return bool False if double index or other error
|
||||
* True on ok
|
||||
* @return void
|
||||
* @throws HtmlBuilderExcpetion
|
||||
*/
|
||||
public static function loadElements(array ...$element): bool
|
||||
public static function loadElements(array ...$element): void
|
||||
{
|
||||
$error = false;
|
||||
foreach ($element as $el) {
|
||||
$index = $el[0] ?? '';
|
||||
if (empty($index)) {
|
||||
$error = true;
|
||||
Error::setError(
|
||||
'310',
|
||||
'Index cannot be an empty string',
|
||||
@@ -45,9 +44,9 @@ class StringReplace
|
||||
'element' => $index
|
||||
]
|
||||
);
|
||||
throw new HtmlBuilderExcpetion('Index cannot be an empty string');
|
||||
}
|
||||
if (isset(self::$elements[$index])) {
|
||||
$error = true;
|
||||
Error::setError(
|
||||
'311',
|
||||
'Index already exists',
|
||||
@@ -55,11 +54,11 @@ class StringReplace
|
||||
'element' => $index
|
||||
]
|
||||
);
|
||||
throw new HtmlBuilderExcpetion('Index already exists: ' . $index);
|
||||
}
|
||||
// content check?
|
||||
self::$elements[$index] = $el[1];
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -80,7 +79,7 @@ class StringReplace
|
||||
'element' => $index
|
||||
]
|
||||
);
|
||||
return;
|
||||
throw new HtmlBuilderExcpetion('Index does not exists: ' . $index);
|
||||
}
|
||||
// allow empty reset
|
||||
self::$elements[$index] = $element;
|
||||
@@ -91,13 +90,14 @@ class StringReplace
|
||||
* if not found will return false
|
||||
*
|
||||
* @param string $index
|
||||
* @return string|false
|
||||
* @return string
|
||||
* @throws HtmlBuilderExcpetion
|
||||
*/
|
||||
public static function getElement(string $index): string|bool
|
||||
public static function getElement(string $index): string
|
||||
{
|
||||
if (!isset(self::$elements[$index])) {
|
||||
Error::setError('321', 'Index not found in elements', ['element' => $index]);
|
||||
return false;
|
||||
throw new HtmlBuilderExcpetion('Index not found in elements array: ' . $index);
|
||||
}
|
||||
return self::$elements[$index];
|
||||
}
|
||||
@@ -120,12 +120,13 @@ class StringReplace
|
||||
*
|
||||
* @param string $index
|
||||
* @return string
|
||||
* @throws HtmlBuilderExcpetion
|
||||
*/
|
||||
public static function getReplaceBlock(string $index): string
|
||||
{
|
||||
if (!isset(self::$replace[$index])) {
|
||||
Error::setError('331', 'Index not found in replace block', ['replace' => $index]);
|
||||
return '';
|
||||
throw new HtmlBuilderExcpetion('Index not found in replace block array: ' . $index);
|
||||
}
|
||||
return self::$replace[$index];
|
||||
}
|
||||
@@ -136,14 +137,12 @@ class StringReplace
|
||||
* if index not found in relement list will return false
|
||||
*
|
||||
* @param string $index index of set element
|
||||
* @param array<string> $replace array of text to search for
|
||||
* @param array<string> $content content data to be set for replace
|
||||
* @param array<string,string> $replace array of text to search (key) and replace (value) for
|
||||
* @return string|false
|
||||
*/
|
||||
public static function buildElement(
|
||||
string $index,
|
||||
array $replace,
|
||||
array $content,
|
||||
string $replace_index = ''
|
||||
): string|bool {
|
||||
if (self::getElement($index) === false) {
|
||||
@@ -152,11 +151,19 @@ class StringReplace
|
||||
if ($replace_index) {
|
||||
self::setReplaceBlock(
|
||||
$replace_index,
|
||||
self::replaceData(self::$elements[$index], $replace, $content)
|
||||
self::replaceData(
|
||||
self::$elements[$index],
|
||||
array_keys($replace),
|
||||
array_values($replace)
|
||||
)
|
||||
);
|
||||
return self::getReplaceBlock($replace_index);
|
||||
} else {
|
||||
return self::replaceData(self::$elements[$index], $replace, $content);
|
||||
return self::replaceData(
|
||||
self::$elements[$index],
|
||||
array_keys($replace),
|
||||
array_values($replace)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,17 +173,14 @@ class StringReplace
|
||||
* replace array they will be added.
|
||||
* if the replace and content count is not the same then an error will be thrown
|
||||
*
|
||||
* @param string $data
|
||||
* @param array<string> $replace
|
||||
* @param array<string> $content
|
||||
* @return string|bool
|
||||
* @param string $data
|
||||
* @param array<string,string> $replace
|
||||
* @return string
|
||||
* @throws HtmlBuilderExcpetion
|
||||
*/
|
||||
public static function replaceData(string $data, array $replace, array $content): string|bool
|
||||
public static function replaceData(string $data, array $replace): string
|
||||
{
|
||||
if (count($replace) != count($content)) {
|
||||
Error::setError('340', 'Replace and content count differ');
|
||||
return false;
|
||||
}
|
||||
$replace = array_keys($replace);
|
||||
// all replace data must have {} around
|
||||
array_walk($replace, function (&$entry) {
|
||||
if (!str_starts_with($entry, '{')) {
|
||||
@@ -185,9 +189,10 @@ class StringReplace
|
||||
if (!str_ends_with($entry, '}')) {
|
||||
$entry .= '}';
|
||||
}
|
||||
// do some validation?
|
||||
});
|
||||
// replace content
|
||||
return str_replace($replace, $content, $data);
|
||||
return str_replace($replace, array_values($replace), $data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user