mirror of
https://github.com/Karaka-Management/phpOMS.git
synced 2026-02-09 13:38:41 +00:00
Went through todos
This commit is contained in:
parent
b2d001c0ae
commit
a7451d330d
|
|
@ -29,6 +29,10 @@ use phpOMS\Utils\ArrayUtils;
|
||||||
*
|
*
|
||||||
* @todo Lock data for concurrency (e.g. table row lock or heartbeat)
|
* @todo Lock data for concurrency (e.g. table row lock or heartbeat)
|
||||||
* https://github.com/Karaka-Management/Karaka/issues/152
|
* https://github.com/Karaka-Management/Karaka/issues/152
|
||||||
|
*
|
||||||
|
* @performance Database inserts happen one at a time.
|
||||||
|
* Try to find a way to optimize this with multiple inserts in one go.
|
||||||
|
* https://github.com/Karaka-Management/phpOMS/issues/370
|
||||||
*/
|
*/
|
||||||
final class WriteMapper extends DataMapperAbstract
|
final class WriteMapper extends DataMapperAbstract
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -159,6 +159,10 @@ class Builder extends BuilderAbstract
|
||||||
*
|
*
|
||||||
* @return self
|
* @return self
|
||||||
*
|
*
|
||||||
|
* @todo Allow to create db indices in json files
|
||||||
|
* e.g. "index": {"idx1": ["col1"], "idx2": ["col1", "col2"] }
|
||||||
|
* https://github.com/Karaka-Management/phpOMS/issues/355
|
||||||
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public static function createFromSchema(array $definition, ConnectionAbstract $connection) : self
|
public static function createFromSchema(array $definition, ConnectionAbstract $connection) : self
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,8 @@ final class Sphere implements D3ShapeInterface
|
||||||
/**
|
/**
|
||||||
* Calculating the distance between two points on a sphere
|
* Calculating the distance between two points on a sphere
|
||||||
*
|
*
|
||||||
|
* Geocoding
|
||||||
|
*
|
||||||
* @param float $latStart Latitude of start point in deg
|
* @param float $latStart Latitude of start point in deg
|
||||||
* @param float $longStart Longitude of start point in deg
|
* @param float $longStart Longitude of start point in deg
|
||||||
* @param float $latEnd Latitude of target point in deg
|
* @param float $latEnd Latitude of target point in deg
|
||||||
|
|
@ -77,6 +79,27 @@ final class Sphere implements D3ShapeInterface
|
||||||
return $angle * $radius;
|
return $angle * $radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a bounding box around a lat/lon defined by a distance in meter
|
||||||
|
*
|
||||||
|
* @param float $lat Latitude
|
||||||
|
* @param float $lon Longitude
|
||||||
|
* @param float $distance Radius in meter
|
||||||
|
*
|
||||||
|
* @return array {a:array{lat:float, lon:float}, b:array{lat:float, lon:float}, c:array{lat:float, lon:float}, d:array{lat:float, lon:float}}
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function boundingBox(float $lat, float $lon, float $distance) : array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'a' => ['lat' => $lat + (1 / 111133.0 / 2 * $distance), 'lon' => $lon - (1 / 111320.0 * \cos(\deg2rad($lat - (1 / 111133.0 / 2 * $distance))) * $distance)],
|
||||||
|
'b' => ['lat' => $lat + (1 / 111133.0 / 2 * $distance), 'lon' => $lon + (1 / 111320.0 * \cos(\deg2rad($lat - (1 / 111133.0 / 2 * $distance))) * $distance)],
|
||||||
|
'c' => ['lat' => $lat - (1 / 111133.0 / 2 * $distance), 'lon' => $lon - (1 / 111320.0 * \cos(\deg2rad($lat - (1 / 111133.0 / 2 * $distance))) * $distance)],
|
||||||
|
'd' => ['lat' => $lat - (1 / 111133.0 / 2 * $distance), 'lon' => $lon + (1 / 111320.0 * \cos(\deg2rad($lat - (1 / 111133.0 / 2 * $distance))) * $distance)],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create sphere by radius
|
* Create sphere by radius
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -124,4 +124,46 @@ final class Numbers
|
||||||
|
|
||||||
return $count;
|
return $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remap numbers between 0 and X to 0 and 100
|
||||||
|
*
|
||||||
|
* @param int $number Number to remap
|
||||||
|
* @param int $max Max possible number
|
||||||
|
* @param float $exp Exponential modifier
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function remapRangeExponentially(int $number, int $max, float $exp = 1.0) : float
|
||||||
|
{
|
||||||
|
if ($number > $max) {
|
||||||
|
$number = $max;
|
||||||
|
}
|
||||||
|
|
||||||
|
$exponent = ($number / $max) * $exp;
|
||||||
|
$mapped = (exp($exponent) - 1) / (exp($exp) - 1) * 100;
|
||||||
|
|
||||||
|
return $mapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remap numbers between 0 and X to 0 and 100
|
||||||
|
*
|
||||||
|
* @param int $number Number to remap
|
||||||
|
* @param int $max Max possible number
|
||||||
|
*
|
||||||
|
* @return float
|
||||||
|
*
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
public static function remapRangeLog(int $number, int $max) : float
|
||||||
|
{
|
||||||
|
if ($number > $max) {
|
||||||
|
$number = $max;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (log($number + 1) / log($max + 1)) * 100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,134 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Jingga
|
|
||||||
*
|
|
||||||
* PHP Version 8.2
|
|
||||||
*
|
|
||||||
* @package phpOMS\Model\Message
|
|
||||||
* @copyright Dennis Eichhorn
|
|
||||||
* @license OMS License 2.0
|
|
||||||
* @version 1.0.0
|
|
||||||
* @link https://jingga.app
|
|
||||||
*/
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace phpOMS\Model\Message;
|
|
||||||
|
|
||||||
use phpOMS\Contract\SerializableInterface;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reload class.
|
|
||||||
*
|
|
||||||
* @package phpOMS\Model\Message
|
|
||||||
* @license OMS License 2.0
|
|
||||||
* @link https://jingga.app
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
final class Reload implements \JsonSerializable, SerializableInterface
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Message type.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
public const TYPE = 'reload';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delay in ms.
|
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
private int $delay = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param int $delay Delay in ms
|
|
||||||
*
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
public function __construct(int $delay = 0)
|
|
||||||
{
|
|
||||||
$this->delay = $delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set delay.
|
|
||||||
*
|
|
||||||
* @param int $delay Delay in ms
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
public function setDelay(int $delay) : void
|
|
||||||
{
|
|
||||||
$this->delay = $delay;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Render message.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
public function serialize() : string
|
|
||||||
{
|
|
||||||
return $this->__toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function unserialize(mixed $raw) : void
|
|
||||||
{
|
|
||||||
if (!\is_string($raw)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$unserialized = \json_decode($raw, true);
|
|
||||||
if (!\is_array($unserialized)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->delay = $unserialized['time'] ?? 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Stringify.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
return (string) \json_encode($this->toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generate message array.
|
|
||||||
*
|
|
||||||
* @return array<string, mixed>
|
|
||||||
*
|
|
||||||
* @since 1.0.0
|
|
||||||
*/
|
|
||||||
public function toArray() : array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'type' => self::TYPE,
|
|
||||||
'time' => $this->delay,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function jsonSerialize() : mixed
|
|
||||||
{
|
|
||||||
return $this->toArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -43,6 +43,18 @@ abstract class StatusAbstract
|
||||||
*/
|
*/
|
||||||
public const PATH = '';
|
public const PATH = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routes.
|
||||||
|
*
|
||||||
|
* Include consideres the state of the file during script execution.
|
||||||
|
* This means setting it to empty has no effect if it was not empty before.
|
||||||
|
* There are also other merging bugs that can happen.
|
||||||
|
*
|
||||||
|
* @var array<string, array>
|
||||||
|
* @since 1.0.0
|
||||||
|
*/
|
||||||
|
private static array $routes = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deactivate module.
|
* Deactivate module.
|
||||||
*
|
*
|
||||||
|
|
@ -105,14 +117,17 @@ abstract class StatusAbstract
|
||||||
throw new PermissionException($destRoutePath); // @codeCoverageIgnore
|
throw new PermissionException($destRoutePath); // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @noinspection PhpIncludeInspection */
|
if (!isset(self::$routes[$destRoutePath])) {
|
||||||
$appRoutes = include $destRoutePath;
|
/** @noinspection PhpIncludeInspection */
|
||||||
|
self::$routes[$destRoutePath] = include $destRoutePath;
|
||||||
|
}
|
||||||
|
|
||||||
/** @noinspection PhpIncludeInspection */
|
/** @noinspection PhpIncludeInspection */
|
||||||
$moduleRoutes = include $srcRoutePath;
|
$moduleRoutes = include $srcRoutePath;
|
||||||
|
|
||||||
$appRoutes = \array_merge_recursive($appRoutes, $moduleRoutes);
|
self::$routes[$destRoutePath] = \array_merge_recursive(self::$routes[$destRoutePath], $moduleRoutes);
|
||||||
|
|
||||||
\file_put_contents($destRoutePath, '<?php return ' . ArrayParser::serializeArray($appRoutes) . ';', \LOCK_EX);
|
\file_put_contents($destRoutePath, '<?php return ' . ArrayParser::serializeArray(self::$routes[$destRoutePath]) . ';', \LOCK_EX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -150,22 +165,31 @@ abstract class StatusAbstract
|
||||||
if ($child instanceof Directory) {
|
if ($child instanceof Directory) {
|
||||||
/** @var File $file */
|
/** @var File $file */
|
||||||
foreach ($child as $file) {
|
foreach ($child as $file) {
|
||||||
if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php'))
|
$appName = \basename($file->getName(), '.php');
|
||||||
|| ($appInfo !== null && \basename($file->getName(), '.php') !== $appInfo->getInternalName())
|
|
||||||
|
if (!\is_dir(__DIR__ . '/../../' . $child->getName() . '/' . $appName)
|
||||||
|
|| ($appInfo !== null && $appName !== $appInfo->getInternalName())
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
self::installRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/' . $type . '.php', $file->getPath());
|
self::installRoutesHooks(
|
||||||
|
__DIR__ . '/../../' . $child->getName() . '/' . $appName . '/' . $type . '.php',
|
||||||
|
$file->getPath()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} elseif ($child instanceof File) {
|
} elseif ($child instanceof File) {
|
||||||
|
$appName = \basename($child->getName(), '.php');
|
||||||
if (!\is_dir(__DIR__ . '/../../' . $child->getName())
|
if (!\is_dir(__DIR__ . '/../../' . $child->getName())
|
||||||
|| ($appInfo !== null && \basename($child->getName(), '.php') !== $appInfo->getInternalName())
|
|| ($appInfo !== null && $appName !== $appInfo->getInternalName())
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
self::installRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . $type . '.php', $child->getPath());
|
self::installRoutesHooks(
|
||||||
|
__DIR__ . '/../../' . $child->getName() . '/' . $type . '.php',
|
||||||
|
$child->getPath()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -227,7 +251,10 @@ abstract class StatusAbstract
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
self::uninstallRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/'. $type . '.php', $file->getPath());
|
self::uninstallRoutesHooks(
|
||||||
|
__DIR__ . '/../../' . $child->getName() . '/' . \basename($file->getName(), '.php') . '/'. $type . '.php',
|
||||||
|
$file->getPath()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} elseif ($child instanceof File) {
|
} elseif ($child instanceof File) {
|
||||||
if (!\is_dir(__DIR__ . '/../../' . $child->getName())
|
if (!\is_dir(__DIR__ . '/../../' . $child->getName())
|
||||||
|
|
@ -236,7 +263,10 @@ abstract class StatusAbstract
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
self::uninstallRoutesHooks(__DIR__ . '/../../' . $child->getName() . '/'. $type . '.php', $child->getPath());
|
self::uninstallRoutesHooks(
|
||||||
|
__DIR__ . '/../../' . $child->getName() . '/'. $type . '.php',
|
||||||
|
$child->getPath()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,4 +114,81 @@ final class Guard
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static function isSafeFile(string $path) : bool
|
||||||
|
{
|
||||||
|
$tmp = \strtolower($path);
|
||||||
|
if (\str_ends_with($tmp, '.csv')) {
|
||||||
|
return self::isSafeXml($path);
|
||||||
|
} elseif (\str_ends_with($tmp, '.xml')) {
|
||||||
|
return self::isSafeCsv($path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isSafeXml(string $path) : bool
|
||||||
|
{
|
||||||
|
$maxEntityDepth = 7;
|
||||||
|
$xml = \file_get_contents($path);
|
||||||
|
|
||||||
|
// Detect injections
|
||||||
|
$injectionPatterns = [
|
||||||
|
'/<!ENTITY\s+%(\w+)\s+"(.+)">/',
|
||||||
|
'/<!ENTITY\s+%(\w+)\s+SYSTEM\s+"(.+)">/',
|
||||||
|
'/<!ENTITY\s+(\w+)\s+"(.+)">/',
|
||||||
|
'/<!DOCTYPE\s+(.+)\s+SYSTEM\s+"(.+)">/'
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($injectionPatterns as $pattern) {
|
||||||
|
if (\preg_match($pattern, $xml) !== false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$reader = new \XMLReader();
|
||||||
|
|
||||||
|
$reader->XML($xml);
|
||||||
|
$reader->setParserProperty(\XMLReader::SUBST_ENTITIES, true);
|
||||||
|
|
||||||
|
$foundBillionLaughsAttack = false;
|
||||||
|
$entityCount = 0;
|
||||||
|
|
||||||
|
while ($reader->read()) {
|
||||||
|
if ($reader->nodeType === \XMLReader::ENTITY_REF) {
|
||||||
|
++$entityCount;
|
||||||
|
|
||||||
|
if ($entityCount > $maxEntityDepth) {
|
||||||
|
$foundBillionLaughsAttack = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !$foundBillionLaughsAttack;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isSafeCsv(string $path) : bool
|
||||||
|
{
|
||||||
|
$input = \fopen($path, 'r');
|
||||||
|
if (!$input) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (($row = \fgetcsv($input)) !== false) {
|
||||||
|
foreach ($row as &$cell) {
|
||||||
|
if (\preg_match('/^[\x00-\x08\x0B\x0C\x0E-\x1F]+/', $cell) !== false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\in_array($cell[0] ?? '', ['=', '+', '-', '@'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
\fclose($input);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,8 @@ final class FileUtils
|
||||||
*
|
*
|
||||||
* @return int Extension type
|
* @return int Extension type
|
||||||
*
|
*
|
||||||
|
* @question Consider to move directly to ExtensionType enum and create ::fromExtension()
|
||||||
|
*
|
||||||
* @since 1.0.0
|
* @since 1.0.0
|
||||||
*/
|
*/
|
||||||
public static function getExtensionType(string $extension) : int
|
public static function getExtensionType(string $extension) : int
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ final class HttpUri implements UriInterface
|
||||||
return ((!empty($_SERVER['HTTPS'] ?? '') && ($_SERVER['HTTPS'] ?? '') !== 'off')
|
return ((!empty($_SERVER['HTTPS'] ?? '') && ($_SERVER['HTTPS'] ?? '') !== 'off')
|
||||||
|| (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https')
|
|| (($_SERVER['HTTP_X_FORWARDED_PROTO'] ?? '') === 'https')
|
||||||
|| (($_SERVER['HTTP_X_FORWARDED_SSL'] ?? '') === 'on') ? 'https' : 'http')
|
|| (($_SERVER['HTTP_X_FORWARDED_SSL'] ?? '') === 'on') ? 'https' : 'http')
|
||||||
. '://' . ($_SERVER['HTTP_HOST'] ?? ''). ($_SERVER['REQUEST_URI'] ?? '');
|
. '://' . ($_SERVER['HTTP_HOST'] ?? '') . ($_SERVER['REQUEST_URI'] ?? '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -281,8 +281,8 @@ final class UriFactory
|
||||||
? '#' . \str_replace('\#', '#', $urlStructure['fragment']) : '');
|
? '#' . \str_replace('\#', '#', $urlStructure['fragment']) : '');
|
||||||
|
|
||||||
return \str_replace(
|
return \str_replace(
|
||||||
['%5C%7B', '%5C%7D', '%5C%3F', '%5C%23'],
|
['%5C%7B', '%5C%7D', '%5C%3F', '%5C%23', '%C2%B0'],
|
||||||
['{', '}', '?', '#'],
|
['{', '}', '?', '#', '°'],
|
||||||
$escaped
|
$escaped
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,10 @@ final class Zip implements ArchiveInterface
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$zip = new \ZipArchive();
|
$zip = new \ZipArchive();
|
||||||
if (!$zip->open($source)) {
|
if (!$zip->open($source)
|
||||||
|
|| $zip->numFiles > 10000
|
||||||
|
|| (($zip->statIndex(0)['size'] ?? 0) + ($zip->statIndex(1)['size'] ?? 0)) > 2e+9
|
||||||
|
) {
|
||||||
return false; // @codeCoverageIgnore
|
return false; // @codeCoverageIgnore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1274,6 +1274,9 @@ class Markdown
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo Optimize away the child <span> element for spoilers (if reasonable)
|
||||||
|
// If possible don't forget to adjust scss
|
||||||
|
// https://github.com/Karaka-Management/phpOMS/issues/367
|
||||||
return [
|
return [
|
||||||
'extent' => \strlen($matches[0]),
|
'extent' => \strlen($matches[0]),
|
||||||
'element' => [
|
'element' => [
|
||||||
|
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* Jingga
|
|
||||||
*
|
|
||||||
* PHP Version 8.2
|
|
||||||
*
|
|
||||||
* @package tests
|
|
||||||
* @copyright 2013 Dennis Eichhorn
|
|
||||||
* @license OMS License 2.0
|
|
||||||
* @version 1.0.0
|
|
||||||
* @link https://jingga.app
|
|
||||||
*/
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace phpOMS\tests\phpOMS\Model\Message;
|
|
||||||
|
|
||||||
use phpOMS\Model\Message\Reload;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
#[\PHPUnit\Framework\Attributes\CoversClass(\phpOMS\Model\Message\Reload::class)]
|
|
||||||
final class ReloadTest extends \PHPUnit\Framework\TestCase
|
|
||||||
{
|
|
||||||
#[\PHPUnit\Framework\Attributes\Group('framework')]
|
|
||||||
public function testDefault() : void
|
|
||||||
{
|
|
||||||
$obj = new Reload();
|
|
||||||
|
|
||||||
/* Testing default values */
|
|
||||||
self::assertEquals(0, $obj->toArray()['time']);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[\PHPUnit\Framework\Attributes\Group('framework')]
|
|
||||||
public function testSetGet() : void
|
|
||||||
{
|
|
||||||
$obj = new Reload(5);
|
|
||||||
|
|
||||||
self::assertEquals(['type' => 'reload', 'time' => 5], $obj->toArray());
|
|
||||||
self::assertEquals(\json_encode(['type' => 'reload', 'time' => 5]), $obj->serialize());
|
|
||||||
self::assertEquals(['type' => 'reload', 'time' => 5], $obj->jsonSerialize());
|
|
||||||
|
|
||||||
$obj->setDelay(6);
|
|
||||||
self::assertEquals(['type' => 'reload', 'time' => 6], $obj->toArray());
|
|
||||||
|
|
||||||
$obj2 = new Reload();
|
|
||||||
$obj2->unserialize($obj->serialize());
|
|
||||||
self::assertEquals($obj, $obj2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user