Test fixes
Some checks failed
CI / general_module_workflow_php (push) Has been cancelled

This commit is contained in:
Dennis Eichhorn 2024-05-16 02:14:55 +00:00
parent f84b33f7fa
commit a7f9eab55a
66 changed files with 725 additions and 663 deletions

View File

@ -341,13 +341,7 @@ class Account implements \JsonSerializable
*/
public function generatePassword(string $password) : void
{
$temp = \password_hash($password, \PASSWORD_BCRYPT);
if ($temp === false) {
throw new \Exception('Internal password_hash error.'); // @codeCoverageIgnore
}
$this->password = $temp;
$this->password = \password_hash($password, \PASSWORD_BCRYPT);
}
/**
@ -396,15 +390,24 @@ class Account implements \JsonSerializable
];
}
/**
* Fill object from array
*
* @param array{id:int, name:array{0:string, 1:string, 2:string}, email:string, login:string, type:int, status:int, groups:array, permissions:array, l11n:array} $account Account data
*
* @return void
*
* @since 1.0.0
*/
public function from (array $account) : void
{
$this->id = $account['id'];
$this->name1 = $account['name'][0];
$this->name2 = $account['name'][1];
$this->name3 = $account['name'][2];
$this->email = $account['email'];
$this->login = $account['login'];
$this->type = $account['type'];
$this->id = $account['id'];
$this->name1 = $account['name'][0];
$this->name2 = $account['name'][1];
$this->name3 = $account['name'][2];
$this->email = $account['email'];
$this->login = $account['login'];
$this->type = $account['type'];
$this->status = $account['status'];
$this->l11n = Localization::fromJson($account['l11n']);

View File

@ -110,7 +110,7 @@ class Group implements \JsonSerializable
'permissions' => $this->permissions,
'members' => $this->members,
'parents' => $this->parents,
'status' => $this->status,
'status' => $this->status,
];
}
@ -130,16 +130,25 @@ class Group implements \JsonSerializable
return $this->toArray();
}
/**
* Create object from array
*
* @param array{id:int, name:string, description:string, members:array, parents:array, status:int, permissions?:array} $group Group data
*
* @return self
*
* @since 1.0.0
*/
public static function fromJson(array $group) : self
{
$new = new self();
$new->id = $group['id'];
$new->name = $group['name'];
$new->id = $group['id'];
$new->name = $group['name'];
$new->description = $group['description'];
$new->members = $group['members'];
$new->parents = $group['parents'];
$new->status = $group['status'];
$new->members = $group['members'];
$new->parents = $group['parents'];
$new->status = $group['status'];
foreach (($group['permissions'] ?? []) as $permission) {
$new->permissions[] = PermissionAbstract::fromJson($permission);

View File

@ -352,42 +352,51 @@ class PermissionAbstract implements \JsonSerializable
public function jsonSerialize() : mixed
{
return [
'id' => $this->id,
'unit' => $this->unit,
'app' => $this->app,
'module' => $this->module,
'from' => $this->from,
'category' => $this->category,
'element' => $this->element,
'component' => $this->component,
'hasRead' => $this->hasRead,
'hasModify' => $this->hasModify,
'hasCreate' => $this->hasCreate,
'hasDelete' => $this->hasDelete,
'defaultCPermissions' => $this->defaultCPermissions,
'hasPermission' => $this->hasPermission,
'defaultPPermissions' => $this->defaultPPermissions,
'id' => $this->id,
'unit' => $this->unit,
'app' => $this->app,
'module' => $this->module,
'from' => $this->from,
'category' => $this->category,
'element' => $this->element,
'component' => $this->component,
'hasRead' => $this->hasRead,
'hasModify' => $this->hasModify,
'hasCreate' => $this->hasCreate,
'hasDelete' => $this->hasDelete,
'defaultCPermissions' => $this->defaultCPermissions,
'hasPermission' => $this->hasPermission,
'defaultPPermissions' => $this->defaultPPermissions,
];
}
/**
* Create object from json string
*
* @param array{id:int, unit:?int, app:?int, module:?string, from:?string, category:?int, element:?int, component:?int, hasRead:bool, hasModify:bool, hasCreate:bool, hasDelete:bool, defaultCPermissions:?string, hasPermission:bool, defaultPPermissions:?string} $permission Permission
*
* @return self
*
* @since 1.0.0
*/
public static function fromJson(array $permission) : self
{
$new = new self();
$new->id = $permission['id'];
$new->unit = $permission['unit'];
$new->app = $permission['app'];
$new->module = $permission['module'];
$new->from = $permission['from'];
$new->category = $permission['category'];
$new->element = $permission['element'];
$new->component = $permission['component'];
$new->hasRead = $permission['hasRead'];
$new->hasModify = $permission['hasModify'];
$new->hasCreate = $permission['hasCreate'];
$new->hasDelete = $permission['hasDelete'];
$new->id = $permission['id'];
$new->unit = $permission['unit'];
$new->app = $permission['app'];
$new->module = $permission['module'];
$new->from = $permission['from'];
$new->category = $permission['category'];
$new->element = $permission['element'];
$new->component = $permission['component'];
$new->hasRead = $permission['hasRead'];
$new->hasModify = $permission['hasModify'];
$new->hasCreate = $permission['hasCreate'];
$new->hasDelete = $permission['hasDelete'];
$new->defaultCPermissions = $permission['defaultCPermissions'];
$new->hasPermission = $permission['hasPermission'];
$new->hasPermission = $permission['hasPermission'];
$new->defaultPPermissions = $permission['defaultPPermissions'];
return $new;

View File

@ -89,7 +89,7 @@ class Point implements PointInterface
/**
* {@inheritdoc}
*/
public function isEquals(Point $point) : bool
public function isEquals(self $point) : bool
{
return $this->name === $point->name && $this->coordinates === $point->coordinates;
}

View File

@ -27,8 +27,8 @@ namespace phpOMS\Algorithm\Clustering;
* @since 1.0.0
*
* @property array<int, int|float> $coordinates
* @property string $name
* @property int $group
* @property string $name
* @property int $group
*/
interface PointInterface
{

View File

@ -617,10 +617,10 @@ final class DHLParcelDEShipping implements ShippingInterface
return [
'date' => $response->getDataDateTime('manifestDate'),
'b64' => $response->getDataArray('manifest')['b64'],
'zpl2' => $response->getDataArray('manifest')['zpl2'],
'url' => $response->getDataArray('manifest')['url'],
'format' => $response->getDataArray('manifest')['printFormat'],
'b64' => $response->getDataArray('manifest')['b64'] ?? '',
'zpl2' => $response->getDataArray('manifest')['zpl2'] ?? '',
'url' => $response->getDataArray('manifest')['url'] ?? '',
'format' => $response->getDataArray('manifest')['printFormat'] ?? '',
];
}

View File

@ -112,9 +112,9 @@ final class ApplicationInfo
/**
* Set data
*
* @param string $path Value path
* @param mixed $data Scalar or array of data to set
* @param string $delim Delimiter of path
* @param string $path Value path
* @param mixed $data Scalar or array of data to set
* @param non-empty-string $delim Delimiter of path
*
* @return void
*

View File

@ -173,10 +173,6 @@ final class ApplicationManager
public function reInit(string $appPath) : void
{
$info = $this->loadInfo($appPath . '/info.json');
if ($info === null) {
return;
}
if (($path = \realpath($appPath)) === false) {
return; // @codeCoverageIgnore
}

View File

@ -152,7 +152,6 @@ final class MemoryCF
/**
* Find similar users
*
*
* @param array $ranking Array of item ratings (e.g. products, movies, ...)
*
* @return array

View File

@ -149,7 +149,7 @@ abstract class GrammarAbstract
*
* @since 1.0.0
*/
public function expressionizeTableColumn(array $elements, BuilderAbstract $query = null, bool $column = true) : string
public function expressionizeTableColumn(array $elements, ?BuilderAbstract $query = null, bool $column = true) : string
{
$expression = '';
@ -166,7 +166,7 @@ abstract class GrammarAbstract
// If we have a subquery, we need to copy the binds over
foreach ($element->binds as $bind) {
$query->bind($bind);
};
}
}
} elseif ($element instanceof \Closure) {
$expression .= $element() . (\is_string($key) ? ' AS ' . $key : '') . ', ';
@ -243,18 +243,18 @@ abstract class GrammarAbstract
protected function compileValue(BuilderAbstract $query, mixed $value) : string
{
$compiled = '';
$type = -1;
$type = -1;
if (\is_string($value)) {
if ($query->usePreparedStmt) {
$type = \PDO::PARAM_STR;
$type = \PDO::PARAM_STR;
$compiled = $value;
} else {
$compiled = $query->quote($value);
}
} elseif (\is_int($value)) {
if ($query->usePreparedStmt) {
$type = \PDO::PARAM_INT;
$type = \PDO::PARAM_INT;
$compiled = $value;
} else {
$compiled = (string) $value;
@ -271,7 +271,7 @@ abstract class GrammarAbstract
$compiled = $values . $this->compileValue($query, $value[$count]) . ')';
} elseif ($value instanceof \DateTimeInterface) {
if ($query->usePreparedStmt) {
$type = \PDO::PARAM_STR;
$type = \PDO::PARAM_STR;
$compiled = $value->format($this->datetimeFormat);
} else {
$compiled = $query->quote($value->format($this->datetimeFormat));
@ -280,7 +280,7 @@ abstract class GrammarAbstract
$compiled = 'NULL';
} elseif (\is_bool($value)) {
if ($query->usePreparedStmt) {
$type = \PDO::PARAM_BOOL;
$type = \PDO::PARAM_BOOL;
$compiled = $value;
} else {
$compiled = (string) ((int) $value);
@ -298,7 +298,7 @@ abstract class GrammarAbstract
$encoded = \json_encode($value);
if ($query->usePreparedStmt) {
$type = $encoded ? \PDO::PARAM_STR : \PDO::PARAM_STR;
$type = $encoded ? \PDO::PARAM_STR : \PDO::PARAM_STR;
$compiled = $encoded ? $value : null;
} else {
$compiled = $encoded ? $query->quote($encoded) : 'NULL';
@ -320,7 +320,7 @@ abstract class GrammarAbstract
} else {
$query->bind([
'value' => $compiled,
'type' => $type,
'type' => $type,
]);
$compiled = '?';

View File

@ -1463,9 +1463,9 @@ class Builder extends BuilderAbstract
} elseif ($column instanceof SerializableInterface) {
return $column->serialize();
} elseif ($column instanceof self) {
$tmp = $column->usePreparedStmt;
$tmp = $column->usePreparedStmt;
$column->usePreparedStmt = false;
$hash = \md5($column->toSql());
$hash = \md5($column->toSql());
$column->usePreparedStmt = $tmp;
return $hash;

View File

@ -270,7 +270,7 @@ class Grammar extends GrammarAbstract
foreach ($wheres as $where) {
foreach ($where as $element) {
$expression = '';
$prefix = '';
$prefix = '';
if (!$first) {
$prefix = ' ' . \strtoupper($element['boolean']) . ' ';
@ -286,7 +286,7 @@ class Grammar extends GrammarAbstract
// BUT we are only allowed to do this once per wheres builder
foreach ($element['column']->binds as $bind) {
$query->bind($bind);
};
}
}
} elseif ($element['column'] instanceof \Closure) {
$expression .= $element['column']();
@ -308,7 +308,7 @@ class Grammar extends GrammarAbstract
if (isset($element['value']) && (!empty($element['value']) || !$isArray)) {
if ($isArray && \count($element['value']) === 1) {
$element['value'] = \reset($element['value']);
$element['value'] = \reset($element['value']);
$element['operator'] = '=';
}
@ -323,7 +323,7 @@ class Grammar extends GrammarAbstract
}
$outer .= $prefix . $expression;
$first = false;
$first = false;
}
}
@ -347,10 +347,9 @@ class Grammar extends GrammarAbstract
protected function compileLimit(Builder $query, int $limit) : string
{
if ($query->usePreparedStmt) {
$query->bind([
'value' => $limit,
'type' => \PDO::PARAM_INT,
'type' => \PDO::PARAM_INT,
]);
$limit = '?';
@ -372,10 +371,9 @@ class Grammar extends GrammarAbstract
protected function compileOffset(Builder $query, int $offset) : string
{
if ($query->usePreparedStmt) {
$query->bind([
'value' => $offset,
'type' => \PDO::PARAM_INT,
'type' => \PDO::PARAM_INT,
]);
$offset = '?';
@ -412,7 +410,7 @@ class Grammar extends GrammarAbstract
// If we have a subquery, we need to copy the binds over
foreach ($join['table']->binds as $bind) {
$query->bind($bind);
};
}
}
}
@ -482,7 +480,7 @@ class Grammar extends GrammarAbstract
// If we have a subquery, we need to copy the binds over
foreach ($element['column']->binds as $bind) {
$query->bind($bind);
};
}
}
} elseif ($element['column'] instanceof \Closure) {
$expression .= $element['column']();

View File

@ -199,7 +199,7 @@ class Builder extends BuilderAbstract
*/
public static function createFromSchema(array $definition, ConnectionAbstract $connection) : self
{
$builder = new self($connection);
$builder = new self($connection);
$builder->usePreparedStmt = false;
$builder->createTable($definition['name'] ?? '');

View File

@ -1,7 +1,7 @@
{
".*": {
"name": "[a-z\\_]+",
".*?description": ".*",
".*?comment": ".*",
"fields": {
".*": {
"name": "[a-z0-9\\_]+",
@ -15,7 +15,7 @@
".*?foreignTable": "[a-z0-9\\_]+",
".*?foreignKey": "[a-z0-9\\_]+",
".*?annotations": ".*",
".*?description": ".*"
".*?comment": ".*"
}
}
}

View File

@ -87,21 +87,21 @@ final class Dispatcher implements DispatcherInterface
/** @var \Closure $function */
$function = $dispatch[0] . '::' . $dispatch[2];
$views[$controller] = $data === null ? $function() : $function(...$data);
$views[$controller] = empty($data) ? $function() : $function(...$data);
} elseif ($c === 2) {
$obj = $this->getController($dispatch[0]);
$views[$controller] = $data === null
$views[$controller] = empty($data)
? $obj->{$dispatch[1]}()
: $obj->{$dispatch[1]}(...$data);
}
} elseif (\is_array($controller)) {
foreach ($controller as $controllerSingle) {
$views += $data === null
$views += empty($data)
? $this->dispatch($controllerSingle)
: $this->dispatch($controllerSingle, ...$data);
}
} else {
$views[] = $data === null
$views[] = empty($data)
? $controller($this->app)
: $controller($this->app, ...$data);
}

View File

@ -65,7 +65,7 @@ final class Kernel
/**
* Kernel matrix for blurring
*
* @var array<int, int[]>
* @var array<int, float[]>
* @since 1.0.0
*/
public const KERNEL_BOX_BLUR = [
@ -77,7 +77,7 @@ final class Kernel
/**
* Kernel matrix for gaussian blurring
*
* @var array<int, int[]>
* @var array<int, float[]>
* @since 1.0.0
*/
public const KERNEL_GAUSSUAN_BLUR_3 = [
@ -101,7 +101,7 @@ final class Kernel
/**
* Kernel matrix for unsharpening
*
* @var array<int, int[]>
* @var array<int, float[]>
* @since 1.0.0
*/
public const KERNEL_UNSHARP_MASKING = [

View File

@ -27,7 +27,7 @@ class LanguageResult implements \ArrayAccess, \IteratorAggregate, \JsonSerializa
/**
* Match threshold
*
* @var int
* @var float
* @since 1.0.0
*/
private const THRESHOLD = .025;

View File

@ -549,7 +549,7 @@ final class FileLogger implements LoggerInterface
while (($line = \fgetcsv($this->fp, 0, ';')) !== false && $current <= $id) {
++$current;
if ($current < $id || $line === null) {
if ($current < $id) {
continue;
}

View File

@ -49,8 +49,7 @@ final class GrahamScan
return $points;
}
$min = 1;
$points = \array_merge([null], $points);
$min = 1;
for ($i = 2; $i < $n; ++$i) {
if ($points[$i]['y'] < $points[$min]['y']

View File

@ -24,8 +24,8 @@ use phpOMS\Math\Matrix\Exception\InvalidDimensionException;
* @link https://jingga.app
* @since 1.0.0
*
* @phpstan-implements \ArrayAccess<string, mixed>
* @phpstan-implements \Iterator<string, mixed>
* @phpstan-implements \ArrayAccess<int, int|float>
* @phpstan-implements \Iterator<int, int|float>
*/
class Matrix implements \ArrayAccess, \Iterator
{
@ -867,7 +867,7 @@ class Matrix implements \ArrayAccess, \Iterator
/**
* {@inheritdoc}
*/
public function current() : int
public function current() : int|float
{
$row = (int) ($this->position / $this->m);

View File

@ -74,10 +74,6 @@ final class Numbers
$n = (string) $n;
$split = \str_split($n);
if ($split === false) {
return false; // @codeCoverageIgnore
}
foreach ($split as $place => $value) {
if (\substr_count($n, (string) $place) != $value) {
return false;
@ -143,7 +139,7 @@ final class Numbers
}
$exponent = ($number / $max) * $exp;
$mapped = (exp($exponent) - 1) / (exp($exp) - 1) * 100;
$mapped = (\exp($exponent) - 1) / (\exp($exp) - 1) * 100;
return $mapped;
}
@ -151,8 +147,8 @@ final class Numbers
/**
* Remap numbers between 0 and X to 0 and 100
*
* @param int $number Number to remap
* @param int $max Max possible number
* @param int $number Number to remap
* @param int $max Max possible number
*
* @return float
*
@ -164,6 +160,6 @@ final class Numbers
$number = $max;
}
return (log($number + 1) / log($max + 1)) * 100;
return (\log($number + 1) / \log($max + 1)) * 100;
}
}

View File

@ -104,26 +104,18 @@ final class Prime
$a = \mt_rand(2, $n - 1);
$x = \bcpowmod((string) $a, (string) $d, (string) $n);
if ($x === false) {
return false;
}
if ($x == 1 || $x == $n - 1) {
continue;
}
for ($j = 1; $j < $s; ++$j) {
if ($x === null) {
return false;
}
$mul = \bcmul($x, $x);
/*if ($mul === null) {
return false;
}*/
$x = \bcmod($mul, (string) $n);
if ($x == 1 || $x === null) {
if ($x == 1) {
return false;
}
@ -153,10 +145,6 @@ final class Prime
$range = \range(2, $n);
$primes = \array_combine($range, $range);
if ($primes === false) {
return []; // @codeCoverageIgnore
}
while ($number * $number < $n) {
for ($i = $number; $i <= $n; $i += $number) {
if ($i === $number) {

View File

@ -81,7 +81,7 @@ final class Average
* @var float[]
* @since 1.0.0
*/
public const MAH13 = [-0.019, -0.028, 0, 0.66, 0.147, 0.214, 0.240, 0.214, 0.147, 0.66, 0, -0.028, -0.019];
public const MAH13 = [-0.019, -0.028, 0.0, 0.66, 0.147, 0.214, 0.240, 0.214, 0.147, 0.66, 0.0, -0.028, -0.019];
/**
* Moving average weights

View File

@ -33,7 +33,7 @@ use phpOMS\Uri\HttpUri;
* @SuppressWarnings(PHPMD.Superglobals)
*
* @property HttpHeader $header
* @property HttpUri $uri
* @property HttpUri $uri
*/
final class HttpRequest extends RequestAbstract
{

View File

@ -146,7 +146,7 @@ final class Rest
\curl_close($curl);
$raw = \substr(\is_bool($result) ? '' : $result, $len === false ? 0 : $len);
$raw = \substr(\is_bool($result) ? '' : $result, $len);
if (\stripos(\implode('', $response->header->get('Content-Type')), MimeType::M_JSON) !== false) {
$temp = \json_decode($raw, true);
if (!\is_array($temp)) {

View File

@ -251,11 +251,9 @@ abstract class RequestAbstract implements MessageInterface
{
$key = \mb_strtolower($key);
$timestamp = empty($this->data[$key] ?? null)
return empty($this->data[$key] ?? null)
? null
: (int) \strtotime((string) $this->data[$key]);
return $timestamp === false ? null : $timestamp;
}
/**
@ -299,9 +297,6 @@ abstract class RequestAbstract implements MessageInterface
/* @phpstan-ignore-next-line */
$list = \explode($delim, (string) $this->data[$key]);
if ($list === false) {
return []; // @codeCoverageIgnore
}
foreach ($list as $i => $e) {
$list[$i] = \trim($e);

View File

@ -241,10 +241,6 @@ abstract class ResponseAbstract implements \JsonSerializable, MessageInterface
/* @phpstan-ignore-next-line */
$list = \explode($delim, $this->data[$key]);
if ($list === false) {
return []; // @codeCoverageIgnore
}
foreach ($list as $i => $e) {
$list[$i] = \trim($e);
}

View File

@ -112,9 +112,9 @@ final class ModuleInfo
/**
* Set data
*
* @param string $path Value path
* @param mixed $data Scalar or array of data to set
* @param string $delim Delimiter of path
* @param string $path Value path
* @param mixed $data Scalar or array of data to set
* @param non-empty-string $delim Delimiter of path
*
* @return void
*

View File

@ -115,6 +115,15 @@ final class Guard
return true;
}
/**
* Checks if a file is "safe"
*
* @param string $path File path
*
* @return bool
*
* @since 1.0.0
*/
public static function isSafeFile(string $path) : bool
{
if (!\str_ends_with($path, '.exe') && !self::isSafeNoneExecutable($path)) {
@ -131,21 +140,34 @@ final class Guard
return true;
}
/**
* Checks if a xml file is "safe"
*
* @param string $path File path
*
* @return bool
*
* @since 1.0.0
*/
public static function isSafeXml(string $path) : bool
{
$maxEntityDepth = 7;
$xml = \file_get_contents($path);
$xml = \file_get_contents($path);
if ($xml === false) {
return true;
}
// Detect injections
$injectionPatterns = [
'/<!ENTITY\s+%(\w+)\s+"(.+)">/',
'/<!ENTITY\s+%(\w+)\s+SYSTEM\s+"(.+)">/',
'/<!ENTITY\s+(\w+)\s+"(.+)">/',
'/<!DOCTYPE\s+(.+)\s+SYSTEM\s+"(.+)">/'
'/<!DOCTYPE\s+(.+)\s+SYSTEM\s+"(.+)">/',
];
foreach ($injectionPatterns as $pattern) {
if (\preg_match($pattern, $xml) !== false) {
if (\preg_match($pattern, $xml) === 1) {
return false;
}
}
@ -156,7 +178,7 @@ final class Guard
$reader->setParserProperty(\XMLReader::SUBST_ENTITIES, true);
$foundBillionLaughsAttack = false;
$entityCount = 0;
$entityCount = 0;
while ($reader->read()) {
if ($reader->nodeType === \XMLReader::ENTITY_REF) {
@ -172,6 +194,15 @@ final class Guard
return !$foundBillionLaughsAttack;
}
/**
* Checks if a CSV file is "safe"
*
* @param string $path File path
*
* @return bool
*
* @since 1.0.0
*/
public static function isSafeCsv(string $path) : bool
{
$input = \fopen($path, 'r');
@ -198,6 +229,15 @@ final class Guard
return true;
}
/**
* Checks if a file that shouldn't be executable is not executable
*
* @param string $path File path
*
* @return bool
*
* @since 1.0.0
*/
public static function isSafeNoneExecutable(string $path) : bool
{
$input = \fopen($path, 'r');

View File

@ -64,21 +64,30 @@ class Address extends Location
return \array_merge(
parent::toArray(),
[
'id' => $this->id,
'id' => $this->id,
'name' => $this->name,
'fao' => $this->fao,
]
);
}
/**
* Create object from array
*
* @param array{id:int, name:string, fao:string, type:int, postal:string, city:string, country:string, address:string, state:string, lat:float, lon:float} $address Address data
*
* @return self
*
* @since 1.0.0
*/
public static function fromJson(array $address) : self
{
$new = new self();
$new->from($address);
$new->id = $address['id'];
$new->id = $address['id'];
$new->name = $address['name'];
$new->fao = $address['fao'];
$new->fao = $address['fao'];
return $new;
}

View File

@ -179,11 +179,10 @@ class FloatInt implements SerializableInterface
$left = \substr($value, 0, -self::MAX_DECIMALS);
/** @var string $left */
$left = $left === false ? '0' : $left;
$left = $left === '' ? '0' : $left;
$right = \substr($value, -self::MAX_DECIMALS);
if ($right === false) {
if ($right === '') {
throw new \Exception(); // @codeCoverageIgnore
}
@ -212,12 +211,10 @@ class FloatInt implements SerializableInterface
: (string) \round($this->value, -self::MAX_DECIMALS + $decimals);
$left = \substr($value, 0, -self::MAX_DECIMALS);
/** @var string $left */
$left = $left === false ? '0' : $left;
$left = $left === '' ? '0' : $left;
$right = \substr($value, -self::MAX_DECIMALS);
if ($right === false) {
if ($right === '') {
throw new \Exception(); // @codeCoverageIgnore
}
@ -380,6 +377,15 @@ class FloatInt implements SerializableInterface
return \json_encode($this->getInt());
}
/**
* Create object from string serialization
*
* @param string $json Json representation
*
* @return self
*
* @since 1.0.0
*/
public static function fromJson(string $json) : self
{
return new self((int) $json);

View File

@ -128,9 +128,7 @@ class Iban implements SerializableInterface
return '';
}
$sequence = \substr($this->iban, $start, $end - $start + 1);
return $sequence === false ? '' : $sequence;
return \substr($this->iban, $start, $end - $start + 1);
}
/**
@ -142,9 +140,7 @@ class Iban implements SerializableInterface
*/
public function getCountry() : string
{
$country = \substr($this->iban, 0, 2);
return $country === false ? '?' : $country;
return \substr($this->iban, 0, 2);
}
/**

View File

@ -157,8 +157,8 @@ class Location implements \JsonSerializable, SerializableInterface
public function toArray() : array
{
return [
'id' => $this->id,
'type' => $this->type,
'id' => $this->id,
'type' => $this->type,
'postal' => $this->postal,
'city' => $this->city,
'country' => $this->country,
@ -169,17 +169,26 @@ class Location implements \JsonSerializable, SerializableInterface
];
}
/**
* Fill object from array
*
* @param array{id:int, type:int, postal:string, city:string, country:string, address:string, state:string, lat:float, lon:float} $location Location data
*
* @return void
*
* @since 1.0.0
*/
public function from(array $location) : void
{
$this->id = $location['id'];
$this->type = $location['type'];
$this->postal = $location['postal'];
$this->city = $location['city'];
$this->id = $location['id'];
$this->type = $location['type'];
$this->postal = $location['postal'];
$this->city = $location['city'];
$this->country = $location['country'];
$this->address = $location['address'];
$this->state = $location['state'];
$this->lat = $location['lat'];
$this->lon = $location['lon'];
$this->state = $location['state'];
$this->lat = $location['lat'];
$this->lon = $location['lon'];
}
/**

View File

@ -1152,7 +1152,7 @@ class Graph
? $edge->node2
: $edge->node1;
if ($colors[$adj->getId()] === -1) {
if ($colors[$adj->getId()] === 0) {
$colors[$adj->getId()] = 1 - $colors[$node->getId()];
$stack[] = $adj;
} elseif ($colors[$adj->getId()] === $colors[$node->getId()]) {

View File

@ -339,7 +339,7 @@ class Directory extends FileAbstract implements DirectoryInterface
$changed = new \DateTime();
$time = \ftp_mdtm($con, $path);
$changed->setTimestamp($time === false ? 0 : $time);
$changed->setTimestamp($time);
return $changed;
}

View File

@ -268,7 +268,7 @@ class File extends FileAbstract implements FileInterface
$changed = new \DateTime();
$time = \ftp_mdtm($con, $path);
$changed->setTimestamp($time === false ? 0 : $time);
$changed->setTimestamp($time);
return $changed;
}

View File

@ -224,8 +224,8 @@ abstract class FileAbstract implements FtpContainerInterface
$mtime = \ftp_mdtm($this->con, $this->path);
$ctime = \ftp_mdtm($this->con, $this->path);
$this->createdAt = (new \DateTimeImmutable())->setTimestamp($mtime === false ? 0 : $mtime);
$this->changedAt->setTimestamp($ctime === false ? 0 : $ctime);
$this->createdAt = (new \DateTimeImmutable())->setTimestamp($mtime);
$this->changedAt->setTimestamp($ctime);
$this->owner = '';
$this->permission = 0;

View File

@ -24,6 +24,19 @@ namespace phpOMS\System\File;
*/
final class SearchUtils
{
/**
* Find text in file.
*
* All keywords must be found within a certain distance to the first and last find.
*
* @param string $path File path
* @param array $keywords Keywords to find
* @param int $distance Distance
*
* @return array<int, array{start:int, end:int, distance:int}>
*
* @since 1.0.0
*/
public static function findInFile(string $path, array $keywords, int $distance = 500) : array
{
$fp = \fopen($path, "r");
@ -35,14 +48,9 @@ final class SearchUtils
$globalPos = 0;
while (!\feof($fp)) {
$line = \fgets($fp);
while (($line = \fgets($fp)) !== false) {
foreach ($keywords as $keyword) {
$pos = \stripos($line, $keyword);
if ($pos === false) {
continue;
}
while ($pos !== false) {
$positions[$keyword][] = $globalPos + $pos;
@ -60,30 +68,22 @@ final class SearchUtils
return [];
}
$start = \reset($keywords);
$start = \reset($keywords);
$distances = [];
foreach ($positions[$start] as $pos) {
if ($pos < 0) {
continue;
}
$distance = [
'start' => $pos,
'end' => $pos,
'start' => $pos,
'end' => $pos,
'distance' => 0,
];
foreach ($positions as $keyword => $found) {
$closestStart = null;
$closestEnd = null;
$inBetween = null;
$closestEnd = null;
$inBetween = null;
foreach ($found as $pos2) {
if ($pos2 < 0) {
continue 2;
}
if ($pos2 >= $distance['start'] && $pos2 <= $distance['end']) {
$inBetween = $pos2;
@ -110,18 +110,14 @@ final class SearchUtils
continue; // Perfect
} elseif ($closestStart < $distance['start']
&& (\abs($closestStart - $distance['start']) <= \abs($closestEnd - $distance['end']) || $closestEnd > $distance['end'])) {
$distance['start'] = \min($distance['start'], $closestStart);
$distance['start'] = \min($distance['start'], $closestStart ?? 0);
} else {
$distance['end'] = \max($distance['end'], $closestEnd);
$distance['end'] = \max($distance['end'], $closestEnd ?? 0);
}
}
$distance['distance'] = $distance['end'] - $distance['start'];
$distances[] = $distance;
}
if (empty($distances)) {
return [];
$distances[] = $distance;
}
\uasort($distances, function (array $a, array $b) {
@ -131,11 +127,25 @@ final class SearchUtils
return $distances;
}
/**
* Create a text extract from a file from a position and a start and end needle
*
* This allows to return for example text extracts from a html file starting with <p> and ending with </p>
*
* @param string $path File path
* @param int $pos Anchor point for the text extract (e.g. found through stripos or findInFile)
* @param string $start Start needle
* @param string $end End needle
*
* @return string
*
* @since 1.0.0
*/
public static function getTextExtract(string $path, int $pos, string $start, string $end) : string
{
$fp = \fopen($path, "r");
if ($fp === false) {
return [];
return '';
}
$startPos = -1;
@ -155,7 +165,10 @@ final class SearchUtils
}
}
if ($startPos < 0 || $endPos < 0) {
if ($startPos === false || $endPos === false
|| $startPos < 0 || $endPos < 0
|| $startPos > $endPos
) {
\fclose($fp);
return '';
}
@ -165,6 +178,6 @@ final class SearchUtils
\fclose($fp);
return $extract;
return $extract === false ? '' : $extract;
}
}

View File

@ -44,8 +44,6 @@ final class UnhandledHandler
'line' => $e->getLine(),
'file' => $e->getFile(),
]);
$_SERVER = [];
}
/**

View File

@ -193,12 +193,7 @@ final class Argument implements UriInterface
return;
}
$result = \explode(' ', $uri);
if ($result === false) {
return;
}
$this->query = $result;
$this->query = \explode(' ', $uri);
$this->queryString = $uri;
}

View File

@ -206,7 +206,7 @@ final class HttpUri implements UriInterface
if (StringUtils::endsWith($this->path, '.php')) {
$path = \substr($this->path, 0, -4);
if ($path === false) {
if ($path === '') {
throw new \Exception(); // @codeCoverageIgnore
}

View File

@ -37,9 +37,9 @@ final class ArrayUtils
/**
* Check if needle exists in multidimensional array.
*
* @param string $path Path to element
* @param array $data Array
* @param string $delim Delimiter for path
* @param string $path Path to element
* @param array $data Array
* @param non-empty-string $delim Delimiter for path
*
* @return array
*
@ -54,10 +54,6 @@ final class ArrayUtils
$el = &$data;
$node = null;
if ($nodes === false) {
throw new \Exception(); // @codeCoverageIgnore
}
foreach ($nodes as $node) {
$prevEl = &$el;
@ -92,11 +88,11 @@ final class ArrayUtils
/**
* Set element in array by path
*
* @param string $path Path to element
* @param array $data Array
* @param mixed $value Value to add
* @param string $delim Delimiter for path
* @param bool $overwrite Overwrite if existing
* @param string $path Path to element
* @param array $data Array
* @param mixed $value Value to add
* @param non-empty-string $delim Delimiter for path
* @param bool $overwrite Overwrite if existing
*
* @return array
*
@ -109,10 +105,6 @@ final class ArrayUtils
$pathParts = \explode($delim, \trim($path, $delim));
$current = &$data;
if ($pathParts === false) {
throw new \Exception(); // @codeCoverageIgnore
}
foreach ($pathParts as $key) {
$current = &$current[$key];
}
@ -135,9 +127,9 @@ final class ArrayUtils
/**
* Get element of array by path
*
* @param string $path Path to element
* @param array $data Array
* @param string $delim Delimiter for path
* @param string $path Path to element
* @param array $data Array
* @param non-empty-string $delim Delimiter for path
*
* @return mixed
*
@ -150,10 +142,6 @@ final class ArrayUtils
$pathParts = \explode($delim, \trim($path, $delim));
$current = $data;
if ($pathParts === false) {
throw new \Exception(); // @codeCoverageIgnore
}
foreach ($pathParts as $key) {
if (!isset($current[$key])) {
return null;

View File

@ -88,6 +88,11 @@ final class Dictionary
while (\count($count) > 1) {
$row1 = \array_shift($count);
$row2 = \array_shift($count);
if ($row1 == null || $row2 === null) {
break;
}
$count[] = [$row1[0] + $row2[0], [$row1, $row2]];
\sort($count);

View File

@ -85,10 +85,6 @@ final class Huffman
$splittedBinaryString = \str_split('1' . $binary . '1', 8);
$binary = '';
if ($splittedBinaryString === false) {
return $binary; // @codeCoverageIgnore
}
foreach ($splittedBinaryString as $i => $c) {
while (\strlen($c) < 8) {
$c .= '0';
@ -136,9 +132,6 @@ final class Huffman
}
$decbin = \substr($decbin, $pos + 1);
if ($decbin === false) {
throw new \Exception(); // @codeCoverageIgnore
}
}
if ($i + 1 === $rawLength) {
@ -149,9 +142,6 @@ final class Huffman
}
$decbin = \substr($decbin, 0, $pos);
if ($decbin === false) {
throw new \Exception(); // @codeCoverageIgnore
}
}
$binary .= $decbin;

View File

@ -702,7 +702,7 @@ class Repository
\preg_match('/^[0-9]*/', $line, $matches);
$author = \substr($line, \strlen($matches[0]) + 1);
$contributor = new Author($author === false ? '' : $author);
$contributor = new Author($author);
$contributor->setCommitCount($this->getCommitsCount($start, $end)[$contributor->name]);
$addremove = $this->getAdditionsRemovalsByContributor($contributor, $start, $end);
@ -863,9 +863,6 @@ class Repository
$author = \count($author) < 2 ? ['none', 'none'] : \explode('<', \trim($author[1] ?? ''));
$date = \substr($lines[2] ?? '', 6);
if ($date === false) {
$date = 'now';
}
$commit = new Commit($matches[0]);
$commit->setAuthor(new Author(\trim($author[0] ?? ''), \rtrim($author[1] ?? '', '>')));

View File

@ -40,7 +40,7 @@ final class CsvDatabaseMapper implements IODatabaseMapper
/**
* Constructor.
*
* @param ConnectionAbstract $con Database connection
* @param ConnectionAbstract $con Database connection
*
* @since 1.0.0
*/
@ -75,6 +75,10 @@ final class CsvDatabaseMapper implements IODatabaseMapper
$title = \strtr(\trim($title), ' ', '_');
$title = \preg_replace('/[^a-zA-Z0-9_]/', '', $title);
if ($title === null) {
return '';
}
return \strtr($title, ' ', '_');
}, $titles);
@ -130,6 +134,10 @@ final class CsvDatabaseMapper implements IODatabaseMapper
$title = \strtr(\trim($title), ' ', '_');
$title = \preg_replace('/[^a-zA-Z0-9_]/', '', $title);
if ($title === null) {
return '';
}
return \strtr($title, ' ', '_');
}, $titles);
@ -240,6 +248,10 @@ final class CsvDatabaseMapper implements IODatabaseMapper
$title = \strtr(\trim($title), ' ', '_');
$title = \preg_replace('/[^a-zA-Z0-9_]/', '', $title);
if ($title === null) {
return '';
}
return \strtr($title, ' ', '_');
}, $titles);

View File

@ -41,13 +41,13 @@ final class SpreadsheetDatabaseMapper implements IODatabaseMapper
/**
* Constructor.
*
* @param ConnectionAbstract $con Database connection
* @param ConnectionAbstract $con Database connection
*
* @since 1.0.0
*/
public function __construct(ConnectionAbstract $con)
{
$this->con = $con;
$this->con = $con;
}
/**
@ -78,8 +78,17 @@ final class SpreadsheetDatabaseMapper implements IODatabaseMapper
// get column titles
$column = 1;
while (!empty($value = $workSheet->getCell(StringUtils::intToAlphabet($column) . 1)->getCalculatedValue())) {
if (!\is_string($value)) {
continue;
}
$value = \strtr(\trim($value), ' ', '_');
$value = \preg_replace('/[^a-zA-Z0-9_]/', '', $value);
if ($value === null) {
continue;
}
$titles[] = $value;
++$column;
@ -140,8 +149,12 @@ final class SpreadsheetDatabaseMapper implements IODatabaseMapper
// get column titles
$column = 1;
while (!empty($value = $workSheet->getCell(StringUtils::intToAlphabet($column) . 1)->getCalculatedValue())) {
$value = \strtr(\trim($value), ' ', '_');
$value = \preg_replace('/[^a-zA-Z0-9_]/', '', $value);
if (!\is_string($value)) {
continue;
}
$value = \strtr(\trim($value), ' ', '_');
$value = \preg_replace('/[^a-zA-Z0-9_]/', '', $value);
$titles[] = $value;
++$column;
@ -278,8 +291,12 @@ final class SpreadsheetDatabaseMapper implements IODatabaseMapper
// get column titles
$column = 1;
while (!empty($value = $workSheet->getCell(StringUtils::intToAlphabet($column) . 1)->getCalculatedValue())) {
$value = \strtr(\trim($value), ' ', '_');
$value = \preg_replace('/[^a-zA-Z0-9_]/', '', $value);
if (!\is_string($value)) {
continue;
}
$value = \strtr(\trim($value), ' ', '_');
$value = \preg_replace('/[^a-zA-Z0-9_]/', '', $value);
$titles[] = $value;
++$column;

View File

@ -42,8 +42,7 @@ final class Gz implements ArchiveInterface
public static function pack(string | array $source, string $destination, bool $overwrite = false) : bool
{
$destination = \strtr($destination, '\\', '/');
if ($destination === false
|| \is_array($source)
if (\is_array($source)
|| (!$overwrite && \is_file($destination))
|| !\is_file($source)
) {

View File

@ -150,7 +150,7 @@ final class ImageUtils
$dst = \imagecreatetruecolor($width, $height);
if ($src === null || $src === false || $dst === null || $dst === false) {
if ($src === false || $dst === false) {
throw new \InvalidArgumentException();
}
@ -166,6 +166,12 @@ final class ImageUtils
\imagesavealpha($dst, true);
}
if ($src === null) {
\imagedestroy($dst);
return;
}
\imagecopyresampled($dst, $src, 0, 0, 0, 0, $width, $height, $imageDim[0], $imageDim[1]);
if (\stripos($srcPath, '.jpg') || \stripos($srcPath, '.jpeg')) {

View File

@ -414,14 +414,14 @@ class Markdown
*/
public function clean() : void
{
$this->definitionData = [];
$this->contentsListArray = [];
$this->contentsListString = '';
$this->firstHeadLevel = 0;
$this->anchorDuplicates = [];
$this->footnoteCount = 0;
$this->definitionData = [];
$this->contentsListArray = [];
$this->contentsListString = '';
$this->firstHeadLevel = 0;
$this->anchorDuplicates = [];
$this->footnoteCount = 0;
$this->currentAbbreviation = '';
$this->currentMeaning = '';
$this->currentMeaning = '';
}
/**
@ -851,8 +851,12 @@ class Markdown
return null;
}
$link = $this->inlineLinkParent($excerpt);
$remainder = $link !== null ? \substr($excerpt['text'], $link['extent']) : '';
$link = $this->inlineLinkParent($excerpt);
if ($link === null) {
return null;
}
$remainder = \substr($excerpt['text'], $link['extent']);
if (\preg_match('/^[ ]*{(' . $this->regexAttribute . '+)}/', $remainder, $matches)) {
$link['extent'] += \strlen($matches[0]);
@ -1980,9 +1984,12 @@ class Markdown
}
// Get the text of the heading
$text = $block['element']['handler']['argument'];
/*
if (isset($block['element']['handler']['argument'])) {
$text = $block['element']['handler']['argument'];
}
*/
// Get the heading level. Levels are h1, h2, ..., h6
$level = $block['element']['name'];
@ -2054,9 +2061,11 @@ class Markdown
if ($name !== 'ul') {
$markerWithoutWhitespace = \substr($markerWithoutWhitespace, -1);
/*
if ($markerWithoutWhitespace === false) {
$markerWithoutWhitespace = $matches[1];
}
*/
}
$block = [
@ -3567,7 +3576,7 @@ class Markdown
foreach ($this->definitionData['Abbreviation'] as $abbreviation => $meaning) {
$this->currentAbbreviation = $abbreviation;
$this->currentMeaning = $meaning;
$this->currentMeaning = $meaning;
$inline['element'] = $this->elementApplyRecursiveDepthFirst(
'insertAbbreviation',
@ -3728,7 +3737,7 @@ class Markdown
// http://stackoverflow.com/q/11309194/200145
// $elementMarkup = \mb_convert_encoding($elementMarkup, 'HTML-ENTITIES', 'UTF-8'); // Deprecated
$elementMarkup = \mb_encode_numericentity($elementMarkup, [0x80, 0x10FFFF, 0, ~0], 'UTF-8' );
$elementMarkup = \mb_encode_numericentity($elementMarkup, [0x80, 0x10FFFF, 0, ~0], 'UTF-8');
// http://stackoverflow.com/q/4879946/200145
$dom->loadHTML($elementMarkup);

View File

@ -139,7 +139,7 @@ final class PdfParser
if ($files === false) {
\unlink($out);
return $text === false ? '' : $text;
return $text;
}
foreach ($files as $file) {

View File

@ -50,7 +50,7 @@ final class XmlParser
$doc->formatOutput = true;
$xml = \file_get_contents($path);
if ($xml === false || $xml === null) {
if ($xml === false) {
return '';
}

View File

@ -242,15 +242,13 @@ final class StringUtils
$splitOld = empty($delim) ? \str_split($old) : \explode($delim, $old);
$splitNew = empty($delim) ? \str_split($new) : \explode($delim, $new);
if ($splitOld === false
|| (empty($old) && !empty($new))
if ((empty($old) && !empty($new))
|| (!empty($delim) && \count($splitOld) === 1 && $splitOld[0] === '')
) {
return '<ins>' . $new . '</ins>';
}
if ($splitNew === false
|| (!empty($old) && empty($new))
if ((!empty($old) && empty($new))
|| (!empty($delim) && \count($splitNew) === 1 && $splitNew[0] === '')
) {
return '<del>' . $old . '</del>';

View File

@ -35,13 +35,8 @@ final class Iban extends ValidatorAbstract
return false;
}
$value = \str_replace(' ', '', \strtolower($value));
$temp = \substr($value, 0, 2);
if ($temp === false) {
return false; // @codeCoverageIgnore
}
$value = \str_replace(' ', '', \strtolower($value));
$temp = \substr($value, 0, 2);
$enumName = '_' . \strtoupper($temp);
if (!IbanEnum::isValidName($enumName)) {

View File

@ -249,10 +249,6 @@ class View extends ViewAbstract
}
$this->module = \substr($this->template, $start, $end - $start);
if ($this->module === false) {
$this->module = '0'; // @codeCoverageIgnore
}
}
/**
@ -285,10 +281,6 @@ class View extends ViewAbstract
}
$this->theme = \substr($this->template, $start, $end - $start);
if ($this->theme === false) {
$this->theme = '0'; // @codeCoverageIgnore
}
}
/**

View File

@ -12,7 +12,7 @@
},
"creator": {
"name": "Jingga",
"website": "jingga.app"
"website": "https://jingga.app"
},
"directory": "Admin",
"providing": {

View File

@ -12,7 +12,7 @@
},
"creator": {
"name": "Jingga",
"website": "jingga.app"
"website": "https://jingga.app"
},
"directory": "Admin",
"providing": {

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
},
"creator": {
"name": "Jingga",
"website": "jingga.app"
"website": "https://jingga.app"
},
"description": "The backend application.",
"directory": "{APPNAME}",

View File

@ -12,7 +12,7 @@
},
"creator": {
"name": "Jingga",
"website": "jingga.app"
"website": "https://jingga.app"
},
"description": "Testmodule module.",
"directory": "Testmodule",

View File

@ -12,7 +12,7 @@
},
"creator": {
"name": "Jingga",
"website": "jingga.app"
"website": "https://jingga.app"
},
"directory": "Admin",
"dependencies": [],

View File

@ -12,7 +12,7 @@
},
"creator": {
"name": "Jingga",
"website": "jingga.app"
"website": "https://jingga.app"
},
"tooMuch": 1,
"description": "Tasks module.",

View File

@ -11,7 +11,7 @@
},
"creator": {
"name": "Jingga",
"website": "jingga.app"
"website": "https://jingga.app"
},
"description": "Tasks module.",
"directory": "Tasks",

View File

@ -12,7 +12,7 @@
},
"creator": {
"name": "Jingga",
"website": "jingga.app"
"website": "https://jingga.app"
},
"description": "Tasks module.",
"directory": "Tasks",

View File

@ -12,7 +12,7 @@
},
"creator": {
"name": "Jingga",
"website": "jingga.app"
"website": "https://jingga.app"
},
"description": "Tasks module.",
"directory": "Tasks",

View File

@ -1,4 +1,4 @@
<?php
<?php declare(strict_types=1);
return [
'db' => [
@ -296,4 +296,4 @@ return [
],
'apis' => [
],
];
];