crash backup
Some checks failed
CI / general_module_workflow_php (push) Has been cancelled

This commit is contained in:
Dennis Eichhorn 2025-03-21 02:48:21 +00:00
parent a02ebcb17e
commit ade92f3735
11 changed files with 178 additions and 123 deletions

View File

@ -31,4 +31,6 @@ abstract class AssetType extends Enum
public const JS = 1;
public const JSLATE = 2;
public const LINK = 3;
}

View File

@ -165,14 +165,14 @@ final class EventManager implements \Countable
* @param string $id Sub-requirement for event (can be regex)
* @param mixed $data Data to pass to the callback
*
* @return bool returns true on successfully triggering ANY event, false if NO event could be triggered which also includes sub-requirements missing
* @return array
*
* @since 1.0.0
*/
public function triggerSimilar(string $group, string $id = '', mixed $data = null) : bool
public function triggerSimilar(string $group, string $id = '', mixed $data = null) : array
{
if (empty($this->callbacks)) {
return false;
return [];
}
$groupIsRegex = \str_starts_with($group, '/');
@ -219,14 +219,14 @@ final class EventManager implements \Countable
$data['@triggerGroup'] ??= $group;
$triggerValue = false;
$result = [];
foreach ($groups as $groupName => $ids) {
foreach ($ids as $id) {
$triggerValue = $this->trigger($groupName, $id, $data) || $triggerValue;
\array_merge($result, $this->trigger($groupName, $id, $data));
}
}
return $triggerValue;
return $result;
}
/**
@ -236,14 +236,14 @@ final class EventManager implements \Countable
* @param string $id Sub-requirement for event
* @param mixed $data Data to pass to the callback
*
* @return bool returns true on successfully triggering the event, false if the event couldn't be triggered which also includes sub-requirements missing
* @return array
*
* @since 1.0.0
*/
public function trigger(string $group, string $id = '', mixed $data = null) : bool
public function trigger(string $group, string $id = '', mixed $data = null) : array
{
if (!isset($this->callbacks[$group])) {
return false;
return [];
}
if (isset($this->groups[$group])) {
@ -251,9 +251,10 @@ final class EventManager implements \Countable
}
if ($this->hasOutstanding($group)) {
return false;
return [];
}
$result = [];
foreach ($this->callbacks[$group]['callbacks'] as $func) {
if (\is_array($data)) {
$data['@triggerGroup'] ??= $group;
@ -267,7 +268,7 @@ final class EventManager implements \Countable
$data['@triggerId'] = $id;
}
$this->dispatcher->dispatch($func, ...\array_values($data));
\array_merge($result, $this->dispatcher->dispatch($func, ...\array_values($data)));
}
if ($this->callbacks[$group]['remove']) {
@ -276,7 +277,7 @@ final class EventManager implements \Countable
$this->reset($group);
}
return true;
return $result;
}
/**

View File

@ -199,6 +199,8 @@ final class Kernel
\imagepng($im, $outPath);
} elseif (\strripos($outPath, 'jpg') !== false || \strripos($outPath, 'jpeg') !== false) {
\imagejpeg($im, $outPath);
} elseif (\strripos($outPath, 'webp') !== false) {
\imagewebp($im, $outPath);
} else {
\imagegif($im, $outPath);
}

View File

@ -115,6 +115,8 @@ final class Skew
\imagepng($im, $outPath);
} elseif (\strripos($outPath, 'jpg') !== false || \strripos($outPath, 'jpeg') !== false) {
\imagejpeg($im, $outPath);
} elseif (\strripos($outPath, 'webp') !== false) {
\imagewebp($im, $outPath);
} else {
\imagegif($im, $outPath);
}

View File

@ -124,6 +124,8 @@ final class Thresholding
\imagepng($out, $outPath);
} elseif (\strripos($outPath, 'jpg') !== false || \strripos($outPath, 'jpeg') !== false) {
\imagejpeg($out, $outPath);
} elseif (\strripos($outPath, 'webp') !== false) {
\imagewebp($im, $outPath);
} else {
\imagegif($out, $outPath);
}

View File

@ -111,7 +111,7 @@ final class Head implements RenderableInterface
*/
public function addAsset(int $type, string $uri, array $attributes = []) : void
{
$this->assets[$uri] = ['type' => $type, 'attributes' => $attributes];
$this->assets[] = ['uri' => $uri, 'type' => $type, 'attributes' => $attributes];
}
/**
@ -279,9 +279,19 @@ final class Head implements RenderableInterface
public function renderAssets() : string
{
$rendered = '';
foreach ($this->assets as $uri => $asset) {
foreach ($this->assets as $asset) {
if ($asset['type'] === AssetType::CSS) {
$rendered .= '<link rel="stylesheet" type="text/css" href="' . $uri . '"';
$rendered .= '<link rel="stylesheet" type="text/css" href="' . $asset['uri'] . '"';
foreach ($asset['attributes'] as $key => $attribute) {
$rendered .= \is_string($key)
? ' ' . $key . '="' . $attribute . '"'
: ' ' . $attribute;
}
$rendered .= '>';
} elseif ($asset['type'] === AssetType::LINK) {
$rendered .= '<link href="' . $asset['uri'] . '"';
foreach ($asset['attributes'] as $key => $attribute) {
$rendered .= \is_string($key)
@ -291,7 +301,7 @@ final class Head implements RenderableInterface
$rendered .= '>';
} elseif ($asset['type'] === AssetType::JS) {
$rendered .= '<script src="' . $uri . '"';
$rendered .= '<script src="' . $asset['uri'] . '"';
foreach ($asset['attributes'] as $key => $attribute) {
$rendered .= \is_string($key)
@ -316,9 +326,9 @@ final class Head implements RenderableInterface
public function renderAssetsLate() : string
{
$rendered = '';
foreach ($this->assets as $uri => $asset) {
foreach ($this->assets as $asset) {
if ($asset['type'] === AssetType::JSLATE) {
$rendered .= '<script src="' . $uri . '"';
$rendered .= '<script src="' . $asset['uri'] . '"';
foreach ($asset['attributes'] as $key => $attribute) {
$rendered .= ' ' . $key . '="' . $attribute . '"';

View File

@ -787,15 +787,29 @@ abstract class ModuleAbstract
* @param string $trigger Trigger for the event manager
* @param string $ip Ip
*
* @return void
* @return bool
*
* @since 1.0.0
*/
protected function createModel(int $account, mixed $obj, string | \Closure $mapper, string $trigger, string $ip) : void
protected function createModel(int $account, mixed $obj, string | \Closure $mapper, string $trigger, string $ip) : bool
{
$trigger = static::NAME . '-' . $trigger . '-create';
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $obj);
$data = [
$account,
null, $obj,
StringUtils::intHash(\is_string($mapper) ? $mapper : \get_class($mapper)), $trigger,
static::NAME,
null,
null,
$ip,
];
$eventResult = $this->app->eventManager->triggerSimilar('PRE:' . $trigger, '', $data);
if ($eventResult !== [] && \in_array(-1, $eventResult, true)) {
return false;
}
$id = 0;
if (\is_string($mapper)) {
@ -804,19 +818,13 @@ abstract class ModuleAbstract
$mapper();
}
$data = [
$account,
null, $obj,
StringUtils::intHash(\is_string($mapper) ? $mapper : \get_class($mapper)), $trigger,
static::NAME,
(string) $id,
null,
$ip,
];
$data[6] = (string) $id;
/** @phpstan-ignore-next-line */
self::$auditor?->eventLogCreate(...$data);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', $data);
$this->app->eventManager->triggerSimilar('POST:' . $trigger, '', $data);
return true;
}
/**
@ -832,38 +840,45 @@ abstract class ModuleAbstract
* @param string $trigger Trigger for the event manager
* @param string $ip Ip
*
* @return void
* @return bool
*
* @since 1.0.0
*/
protected function createModels(int $account, array $objs, string | \Closure $mapper, string $trigger, string $ip) : void
protected function createModels(int $account, array $objs, string | \Closure $mapper, string $trigger, string $ip) : bool
{
$trigger = static::NAME . '-' . $trigger . '-create';
foreach ($objs as $obj) {
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $obj);
$id = 0;
$data = [
$account,
null, $obj,
StringUtils::intHash(\is_string($mapper) ? $mapper : \get_class($mapper)), $trigger,
static::NAME,
'',
null,
$ip,
];
$eventResult = $this->app->eventManager->triggerSimilar('PRE:' . $trigger, '', $data);
if ($eventResult !== [] && \in_array(-1, $eventResult, true)) {
continue;
}
$id = 0;
if (\is_string($mapper)) {
$id = $mapper::create()->execute($obj);
} else {
$mapper();
}
$data = [
$account,
null, $obj,
StringUtils::intHash(\is_string($mapper) ? $mapper : \get_class($mapper)), $trigger,
static::NAME,
(string) $id,
null,
$ip,
];
$data[6] = (string) $id;
/** @phpstan-ignore-next-line */
self::$auditor?->eventLogCreate(...$data);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', $data);
$this->app->eventManager->triggerSimilar('POST:' . $trigger, '', $data);
}
return true;
}
/**
@ -880,36 +895,43 @@ abstract class ModuleAbstract
* @param string $trigger Trigger for the event manager
* @param string $ip Ip
*
* @return void
* @return bool
*
* @since 1.0.0
*/
protected function updateModel(int $account, mixed $old, mixed $new, string | \Closure $mapper, string $trigger, string $ip) : void
protected function updateModel(int $account, mixed $old, mixed $new, string | \Closure $mapper, string $trigger, string $ip) : bool
{
$trigger = static::NAME . '-' . $trigger . '-update';
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $old);
$id = 0;
if (\is_string($mapper)) {
$id = $mapper::update()->execute($new);
} else {
$mapper();
}
$data = [
$account,
$old, $new,
StringUtils::intHash(\is_string($mapper) ? $mapper : \get_class($mapper)), $trigger,
static::NAME,
(string) $id,
null,
null,
$ip,
];
$eventResult = $this->app->eventManager->triggerSimilar('PRE:' . $trigger, '', $data);
if ($eventResult !== [] && \in_array(-1, $eventResult, true)) {
return false;
}
$id = 0;
if (\is_string($mapper)) {
$id = $mapper::update()->execute($new);
} else {
$mapper();
}
$data[6] = (string) $id;
/** @phpstan-ignore-next-line */
self::$auditor?->eventLogUpdate(...$data);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', $data);
$this->app->eventManager->triggerSimilar('POST:' . $trigger, '', $data);
return true;
}
/**
@ -925,36 +947,43 @@ abstract class ModuleAbstract
* @param string $trigger Trigger for the event manager
* @param string $ip Ip
*
* @return void
* @return bool
*
* @since 1.0.0
*/
protected function deleteModel(int $account, mixed $obj, string | \Closure $mapper, string $trigger, string $ip) : void
protected function deleteModel(int $account, mixed $obj, string | \Closure $mapper, string $trigger, string $ip) : bool
{
$trigger = static::NAME . '-' . $trigger . '-delete';
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $obj);
$id = 0;
if (\is_string($mapper)) {
$id = $mapper::delete()->execute($obj);
} else {
$mapper();
}
$data = [
$account,
$obj, null,
StringUtils::intHash(\is_string($mapper) ? $mapper : \get_class($mapper)), $trigger,
static::NAME,
(string) $id,
'',
null,
$ip,
];
$eventResult = $this->app->eventManager->triggerSimilar('PRE:' . $trigger, '', $data);
if ($eventResult !== [] && \in_array(-1, $eventResult, true)) {
return false;
}
$id = 0;
if (\is_string($mapper)) {
$id = $mapper::delete()->execute($obj);
} else {
$mapper();
}
$data[6] = (string) $id;
/** @phpstan-ignore-next-line */
self::$auditor?->eventLogDelete(...$data);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', $data);
$this->app->eventManager->triggerSimilar('POST:' . $trigger, '', $data);
return true;
}
/**
@ -996,7 +1025,7 @@ abstract class ModuleAbstract
* @param string $trigger Trigger for the event manager
* @param string $ip Ip
*
* @return void
* @return bool
*
* @since 1.0.0
*/
@ -1008,17 +1037,14 @@ abstract class ModuleAbstract
string $field,
string $trigger,
string $ip
) : void
) : bool
{
if (empty($rel1) || empty($rel2)) {
return;
return false;
}
$trigger = static::NAME . '-' . $trigger . '-relation-create';
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $rel1);
$mapper::writer()->createRelationTable($field, \is_array($rel2) ? $rel2 : [$rel2], $rel1);
$data = [
$account,
'', [$rel1 => $rel2],
@ -1029,9 +1055,18 @@ abstract class ModuleAbstract
$ip,
];
$eventResult = $this->app->eventManager->triggerSimilar('PRE:' . $trigger, '', $data);
if ($eventResult !== [] && \in_array(-1, $eventResult, true)) {
return false;
}
$mapper::writer()->createRelationTable($field, \is_array($rel2) ? $rel2 : [$rel2], $rel1);
/** @phpstan-ignore-next-line */
self::$auditor?->eventLogRelationCreate(...$data);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', $data);
$this->app->eventManager->triggerSimilar('POST:' . $trigger, '', $data);
return true;
}
/**
@ -1049,23 +1084,14 @@ abstract class ModuleAbstract
* @param string $trigger Trigger for the event manager
* @param string $ip Ip
*
* @return void
* @return bool
*
* @since 1.0.0
*/
protected function deleteModelRelation(int $account, mixed $rel1, mixed $rel2, string $mapper, string $field, string $trigger, string $ip) : void
protected function deleteModelRelation(int $account, mixed $rel1, mixed $rel2, string $mapper, string $field, string $trigger, string $ip) : bool
{
$trigger = static::NAME . '-' . $trigger . '-relation-delete';
$this->app->eventManager->triggerSimilar('PRE:Module:' . $trigger, '', $rel1);
$mapper::remover()->deleteRelationTable(
$field,
$rel2 === null
? null
: (\is_array($rel2) ? $rel2 : [$rel2]),
$rel1
);
$data = [
$account,
[$rel1 => $rel2], '',
@ -1076,8 +1102,23 @@ abstract class ModuleAbstract
$ip,
];
$eventResult = $this->app->eventManager->triggerSimilar('PRE:' . $trigger, '', $data);
if ($eventResult !== [] && \in_array(-1, $eventResult, true)) {
return false;
}
$mapper::remover()->deleteRelationTable(
$field,
$rel2 === null
? null
: (\is_array($rel2) ? $rel2 : [$rel2]),
$rel1
);
/** @phpstan-ignore-next-line */
self::$auditor?->eventLogRelationDelete(...$data);
$this->app->eventManager->triggerSimilar('POST:Module:' . $trigger, '', $data);
$this->app->eventManager->triggerSimilar('POST:' . $trigger, '', $data);
return true;
}
}

View File

@ -225,6 +225,26 @@ abstract class CodeAbstract
\imagedestroy($res);
}
/**
* Save to file
*
* @param string $file File path/name
*
* @return void
*
* @since 1.0.0
*/
public function saveToWebpFile(string $file) : void
{
$res = $this->get();
if ($res === null) {
return;
}
\imagewebp($res, $file);
\imagedestroy($res);
}
/**
* Save to file
*

View File

@ -180,6 +180,8 @@ final class ImageUtils
\imagepng($dst, $dstPath);
} elseif (\stripos($srcPath, '.gif')) {
\imagegif($dst, $dstPath);
} elseif (\stripos($srcPath, '.webp')) {
\imagewebp($dst, $dstPath);
}
\imagedestroy($src);
@ -347,6 +349,8 @@ final class ImageUtils
\imagepng($dst, $out);
} elseif (\stripos($out, '.gif')) {
\imagegif($dst, $out);
} elseif (\stripos($out, '.webp')) {
\imagewebp($dst, $out);
}
\imagedestroy($src1);

View File

@ -106,34 +106,6 @@ class View extends ViewAbstract
$this->l11n = $response !== null ? $response->header->l11n : new Localization();
}
/**
* Check if data exists
*
* @param string $id Data Id
*
* @return bool
*
* @since 1.0.0
*/
public function hasData(string $id) : bool
{
return isset($this->data[$id]);
}
/**
* Get data attached to view
*
* @param string $id Data Id
*
* @return mixed
*
* @since 1.0.0
*/
public function getData(string $id) : mixed
{
return $this->data[$id] ?? null;
}
/**
* Set data of view
*

View File

@ -63,10 +63,9 @@ final class ViewTest extends \PHPUnit\Framework\TestCase
self::assertEmpty($view->getTemplate());
self::assertEmpty($view->getViews());
self::assertIsArray($view->getViews());
self::assertFalse($view->hasData('0'));
self::assertFalse($view->getView('0'));
self::assertFalse($view->removeView('0'));
self::assertNull($view->getData('0'));
self::assertNull($view->data['0']);
self::assertFalse($view->removeData('0'));
self::assertEmpty($view->toArray());
}
@ -174,7 +173,7 @@ final class ViewTest extends \PHPUnit\Framework\TestCase
$view = new View($this->app->l11nManager);
$view->data['key'] = 'value';
self::assertEquals('value', $view->getData('key'));
self::assertEquals('value', $view->data['key']);
}
#[\PHPUnit\Framework\Attributes\Group('framework')]
@ -184,7 +183,7 @@ final class ViewTest extends \PHPUnit\Framework\TestCase
$view = new View($this->app->l11nManager);
$view->data['key2'] = 'valu2';
self::assertEquals('valu2', $view->getData('key2'));
self::assertEquals('valu2', $view->data['key2']);
}
#[\PHPUnit\Framework\Attributes\Group('framework')]
@ -195,7 +194,7 @@ final class ViewTest extends \PHPUnit\Framework\TestCase
$view->data['key2'] = 'valu2';
self::assertTrue($view->removeData('key2'));
self::assertNull($view->getData('key2'));
self::assertNull($view->data['key2']);
}
#[\PHPUnit\Framework\Attributes\Group('framework')]