diff --git a/Account/Account.php b/Account/Account.php index 33f9ae6ec..597ea510c 100644 --- a/Account/Account.php +++ b/Account/Account.php @@ -292,7 +292,7 @@ class Account implements ArrayableInterface, \JsonSerializable /** * Get permissions. * - * @return array + * @return PermissionAbstract[] * * @since 1.0.0 */ @@ -603,7 +603,7 @@ class Account implements ArrayableInterface, \JsonSerializable */ public function __toString() : string { - return json_encode($this->toArray()); + return \json_encode($this->toArray()); } /** @@ -630,7 +630,7 @@ class Account implements ArrayableInterface, \JsonSerializable /** * Json serialize. * - * @return array + * @return array * * @since 1.0.0 */ diff --git a/Account/Group.php b/Account/Group.php index 1a8f874b4..8bcd3e429 100644 --- a/Account/Group.php +++ b/Account/Group.php @@ -189,7 +189,7 @@ class Group implements ArrayableInterface, \JsonSerializable */ public function __toString() : string { - return json_encode($this->toArray()); + return \json_encode($this->toArray()); } /** @@ -209,7 +209,7 @@ class Group implements ArrayableInterface, \JsonSerializable /** * Json serialize. * - * @return array + * @return array * * @since 1.0.0 */ diff --git a/Autoloader.php b/Autoloader.php index 08e8506db..9ee328ee4 100644 --- a/Autoloader.php +++ b/Autoloader.php @@ -77,8 +77,8 @@ final class Autoloader */ public static function defaultAutoloader(string $class) : void { - $class = ltrim($class, '\\'); - $class = str_replace(['_', '\\'], '/', $class); + $class = \ltrim($class, '\\'); + $class = \str_replace(['_', '\\'], '/', $class); foreach (self::$paths as $path) { if (file_exists($file = $path . $class . '.php')) { @@ -102,8 +102,8 @@ final class Autoloader */ public static function exists(string $class) : bool { - $class = ltrim($class, '\\'); - $class = str_replace(['_', '\\'], '/', $class); + $class = \ltrim($class, '\\'); + $class = \str_replace(['_', '\\'], '/', $class); foreach (self::$paths as $path) { if (file_exists($file = $path . $class . '.php')) { diff --git a/Config/SettingsAbstract.php b/Config/SettingsAbstract.php index d26c8356c..042805f76 100644 --- a/Config/SettingsAbstract.php +++ b/Config/SettingsAbstract.php @@ -77,7 +77,7 @@ abstract class SettingsAbstract implements OptionsInterface /** * Get option by key. * - * @param string|string[] $columns Column values for filtering + * @param string|string[]|int|int[] $columns Column values for filtering * * @return mixed Option value * diff --git a/DataStorage/Cache/Connection/FileCache.php b/DataStorage/Cache/Connection/FileCache.php index 550d3a57c..7ad8ccadf 100644 --- a/DataStorage/Cache/Connection/FileCache.php +++ b/DataStorage/Cache/Connection/FileCache.php @@ -219,7 +219,7 @@ class FileCache extends ConnectionAbstract if ($type === CacheValueType::_INT || $type === CacheValueType::_FLOAT || $type === CacheValueType::_STRING || $type === CacheValueType::_BOOL) { return (string) $value; } elseif ($type === CacheValueType::_ARRAY) { - return json_encode($value); + return \json_encode($value); } elseif ($type === CacheValueType::_SERIALIZABLE) { return get_class($value) . self::DELIM . $value->serialize(); } elseif ($type === CacheValueType::_JSONSERIALIZABLE) { @@ -315,7 +315,7 @@ class FileCache extends ConnectionAbstract $value = substr($raw, $expireEnd + 1); break; case CacheValueType::_ARRAY: - $value = json_decode(substr($raw, $expireEnd + 1)); + $value = \json_decode(substr($raw, $expireEnd + 1)); break; case CacheValueType::_NULL: $value = null; @@ -353,7 +353,7 @@ class FileCache extends ConnectionAbstract if ($expire >= 0) { $created = Directory::created(File::sanitize($key, self::SANITIZE))->getTimestamp(); $now = time(); - $raw = file_get_contents($path); + $raw = \file_get_contents($path); $expireStart = strpos($raw, self::DELIM); $expireEnd = strpos($raw, self::DELIM, $expireStart + 1); $cacheExpire = substr($raw, $expireStart + 1, $expireEnd - ($expireStart + 1)); diff --git a/DataStorage/Database/Connection/MysqlConnection.php b/DataStorage/Database/Connection/MysqlConnection.php index 3e41ba8ab..a05fc19b3 100644 --- a/DataStorage/Database/Connection/MysqlConnection.php +++ b/DataStorage/Database/Connection/MysqlConnection.php @@ -59,7 +59,7 @@ final class MysqlConnection extends ConnectionAbstract $this->dbdata = isset($dbdata) ? $dbdata : $this->dbdata; if (!isset($this->dbdata['db'], $this->dbdata['host'], $this->dbdata['port'], $this->dbdata['database'], $this->dbdata['login'], $this->dbdata['password'])) { - throw new InvalidConnectionConfigException(json_encode($this->dbdata)); + throw new InvalidConnectionConfigException(\json_encode($this->dbdata)); } $this->close(); diff --git a/DataStorage/Database/Connection/PostgresConnection.php b/DataStorage/Database/Connection/PostgresConnection.php index 447829736..33fa94d48 100644 --- a/DataStorage/Database/Connection/PostgresConnection.php +++ b/DataStorage/Database/Connection/PostgresConnection.php @@ -58,7 +58,7 @@ final class PostgresConnection extends ConnectionAbstract $this->dbdata = isset($dbdata) ? $dbdata : $this->dbdata; if (!isset($this->dbdata['db'], $this->dbdata['host'], $this->dbdata['port'], $this->dbdata['database'], $this->dbdata['login'], $this->dbdata['password'])) { - throw new InvalidConnectionConfigException(json_encode($this->dbdata)); + throw new InvalidConnectionConfigException(\json_encode($this->dbdata)); } $this->close(); diff --git a/DataStorage/Database/DataMapperAbstract.php b/DataStorage/Database/DataMapperAbstract.php index 0894da0a1..df7b51ad7 100644 --- a/DataStorage/Database/DataMapperAbstract.php +++ b/DataStorage/Database/DataMapperAbstract.php @@ -14,7 +14,7 @@ declare(strict_types=1); namespace phpOMS\DataStorage\Database; -use phpOMS\DataStorage\Database\Connection\ConnectionAbstract; +use phpOMS\DataStorage\DataStorageConnectionInterface; use phpOMS\DataStorage\Database\Query\Builder; use phpOMS\DataStorage\DataMapperInterface; use phpOMS\Message\RequestAbstract; @@ -37,7 +37,7 @@ class DataMapperAbstract implements DataMapperInterface /** * Database connection. * - * @var ConnectionAbstract + * @var DataStorageConnectionInterface * @since 1.0.0 */ protected static $db = null; @@ -77,7 +77,7 @@ class DataMapperAbstract implements DataMapperInterface /** * Columns. * - * @var array + * @var array> * @since 1.0.0 */ protected static $columns = []; @@ -195,13 +195,13 @@ class DataMapperAbstract implements DataMapperInterface /** * Set database connection. * - * @param ConnectionAbstract $con Database connection + * @param DataStorageConnectionInterface $con Database connection * * @return void * * @since 1.0.0 */ - public static function setConnection(ConnectionAbstract $con) : void + public static function setConnection(DataStorageConnectionInterface $con) : void { self::$db = $con; } @@ -402,7 +402,7 @@ class DataMapperAbstract implements DataMapperInterface $query->prefix(self::$db->getPrefix())->into(static::$table); foreach (static::$columns as $key => $column) { - $propertyName = stripos($column['internal'], '/') !== false ? explode('/', $column['internal'])[0] : $column['internal']; + $propertyName = \stripos($column['internal'], '/') !== false ? explode('/', $column['internal'])[0] : $column['internal']; if (isset(static::$hasMany[$propertyName]) || isset(static::$hasOne[$propertyName])) { continue; } @@ -426,7 +426,7 @@ class DataMapperAbstract implements DataMapperInterface } elseif ($column['name'] !== static::$primaryField) { $tValue = $property->getValue($obj); if (stripos($column['internal'], '/') !== false) { - $path = explode('/', $column['internal']); + $path = \explode('/', $column['internal']); array_shift($path); $path = implode('/', $path); @@ -476,7 +476,7 @@ class DataMapperAbstract implements DataMapperInterface $path = $column['internal']; if (stripos($column['internal'], '/') !== false) { - $path = explode('/', $column['internal']); + $path = \explode('/', $column['internal']); array_shift($path); $path = implode('/', $path); @@ -890,11 +890,11 @@ class DataMapperAbstract implements DataMapperInterface } elseif ($type === 'DateTime') { return $value->format('Y-m-d H:i:s'); } elseif ($type === 'Json' || $type === 'jsonSerializable') { - return json_encode($value); + return \json_encode($value); } elseif ($type === 'Serializable') { return $value->serialize(); } elseif ($value instanceof \JsonSerializable) { - return json_encode($value->jsonSerialize()); + return \json_encode($value->jsonSerialize()); } elseif (is_object($value) && method_exists($value, 'getId')) { return $value->getId(); } @@ -1118,7 +1118,7 @@ class DataMapperAbstract implements DataMapperInterface ->where(static::$table . '.' . static::$primaryField, '=', $objId); foreach (static::$columns as $key => $column) { - $propertyName = stripos($column['internal'], '/') !== false ? explode('/', $column['internal'])[0] : $column['internal']; + $propertyName = \stripos($column['internal'], '/') !== false ? explode('/', $column['internal'])[0] : $column['internal']; if (isset(static::$hasMany[$propertyName]) || isset(static::$hasOne[$propertyName]) || $column['internal'] === static::$primaryField @@ -1147,7 +1147,7 @@ class DataMapperAbstract implements DataMapperInterface } elseif ($column['name'] !== static::$primaryField) { $tValue = $property->getValue($obj); if (stripos($column['internal'], '/') !== false) { - $path = explode('/', $column['internal']); + $path = \explode('/', $column['internal']); array_shift($path); $path = implode('/', $path); @@ -1480,10 +1480,10 @@ class DataMapperAbstract implements DataMapperInterface public static function populate(array $result, $obj = null) { $class = static::class; - $class = str_replace('Mapper', '', $class); + $class = \str_replace('Mapper', '', $class); if (empty($result)) { - $parts = explode('\\', $class); + $parts = \explode('\\', $class); $name = $parts[$c = (count($parts) - 1)]; $parts[$c] = 'Null' . $name; $class = implode('\\', $parts); @@ -1779,7 +1779,7 @@ class DataMapperAbstract implements DataMapperInterface if (stripos(static::$columns[$column]['internal'], '/') !== false) { $hasPath = true; - $path = explode('/', static::$columns[$column]['internal']); + $path = \explode('/', static::$columns[$column]['internal']); $refProp = $refClass->getProperty($path[0]); if (!($accessible = $refProp->isPublic())) { @@ -1797,7 +1797,7 @@ class DataMapperAbstract implements DataMapperInterface } } - if (in_array(static::$columns[$column]['type'], ['string', 'int', 'float', 'bool'])) { + if (\in_array(static::$columns[$column]['type'], ['string', 'int', 'float', 'bool'])) { // todo: what is this or condition for? seems to be wrong if obj null then it doesn't work anyways if ($value !== null || $refProp->getValue($obj) !== null) { settype($value, static::$columns[$column]['type']); @@ -1820,7 +1820,7 @@ class DataMapperAbstract implements DataMapperInterface $value = ArrayUtils::setArray($path, $aValue, $value, '/', true); } - $refProp->setValue($obj, json_decode($value, true)); + $refProp->setValue($obj, \json_decode($value, true)); } elseif (static::$columns[$column]['type'] === 'Serializable') { $member = $refProp->getValue($obj); $member->unserialize($value); @@ -1852,18 +1852,18 @@ class DataMapperAbstract implements DataMapperInterface if (isset(static::$columns[$column]['internal'])) { $path = static::$columns[$column]['internal']; if (stripos($path, '/') !== false) { - $path = explode('/', $path); + $path = \explode('/', $path); array_shift($path); $path = implode('/', $path); } - if (in_array(static::$columns[$column]['type'], ['string', 'int', 'float', 'bool'])) { + if (\in_array(static::$columns[$column]['type'], ['string', 'int', 'float', 'bool'])) { settype($value, static::$columns[$column]['type']); } elseif (static::$columns[$column]['type'] === 'DateTime') { $value = new \DateTime($value ?? ''); } elseif (static::$columns[$column]['type'] === 'Json') { - $value = json_decode($value, true); + $value = \json_decode($value, true); } $obj = ArrayUtils::setArray($path, $obj, $value, '/', true); @@ -1949,8 +1949,8 @@ class DataMapperAbstract implements DataMapperInterface private static function getNullModelObj() { $class = static::class; - $class = str_replace('Mapper', '', $class); - $parts = explode('\\', $class); + $class = \str_replace('Mapper', '', $class); + $parts = \explode('\\', $class); $name = $parts[$c = (count($parts) - 1)]; $parts[$c] = 'Null' . $name; $class = implode('\\', $parts); @@ -1965,7 +1965,7 @@ class DataMapperAbstract implements DataMapperInterface * @param int $relations Load relations * @param int $depth Relation depth * - * @return mixed + * @return array * * @since 1.0.0 */ @@ -2574,7 +2574,7 @@ class DataMapperAbstract implements DataMapperInterface $result = static::getAll(); } elseif ($filter === 'list') { $list = $request->getData('list'); - $result = static::get(json_decode($list, true)); + $result = static::get(\json_decode($list, true)); } else { $limit = (int) ($request->getData('limit') ?? 1); $from = $request->getData('from') === null ? null : new \DateTime((string) $request->getData('from')); diff --git a/DataStorage/Database/GrammarAbstract.php b/DataStorage/Database/GrammarAbstract.php index a02be1092..ecd7c91c0 100644 --- a/DataStorage/Database/GrammarAbstract.php +++ b/DataStorage/Database/GrammarAbstract.php @@ -245,7 +245,7 @@ abstract class GrammarAbstract } // todo: move remaining * test also here not just if .* but also if * (should be done in else?) - if (count($split = explode('.', $system)) === 2) { + if (count($split = \explode('.', $system)) === 2) { $system = $split[1] === '*' ? $split[1] : $this->compileSystem($split[1]); return $this->compileSystem($prefix . $split[0]) . '.' . $system; diff --git a/DataStorage/Database/Query/Builder.php b/DataStorage/Database/Query/Builder.php index 1cae96965..ad37a3625 100644 --- a/DataStorage/Database/Query/Builder.php +++ b/DataStorage/Database/Query/Builder.php @@ -38,7 +38,7 @@ final class Builder extends BuilderAbstract /** * Columns. * - * @var array + * @var array> * @since 1.0.0 */ public $selects = []; @@ -46,7 +46,7 @@ final class Builder extends BuilderAbstract /** * Columns. * - * @var array + * @var array> * @since 1.0.0 */ public $updates = []; @@ -486,7 +486,7 @@ final class Builder extends BuilderAbstract */ public function where($columns, $operator = null, $values = null, $boolean = 'and') : Builder { - if ($operator !== null && !is_array($operator) && !in_array(strtolower($operator), self::OPERATORS)) { + if ($operator !== null && !is_array($operator) && !\in_array(strtolower($operator), self::OPERATORS)) { throw new \InvalidArgumentException('Unknown operator.'); } @@ -499,7 +499,7 @@ final class Builder extends BuilderAbstract $i = 0; foreach ($columns as $key => $column) { - if (isset($operator[$i]) && !in_array(strtolower($operator[$i]), self::OPERATORS)) { + if (isset($operator[$i]) && !\in_array(strtolower($operator[$i]), self::OPERATORS)) { throw new \InvalidArgumentException('Unknown operator.'); } diff --git a/DataStorage/Session/HttpSession.php b/DataStorage/Session/HttpSession.php index 4eabb1397..2d66dc3a2 100644 --- a/DataStorage/Session/HttpSession.php +++ b/DataStorage/Session/HttpSession.php @@ -80,29 +80,29 @@ class HttpSession implements SessionInterface throw new LockException('HttpSession'); } - if (session_id()) { - session_write_close(); + if (\session_id()) { + \session_write_close(); } - if (!is_bool($sid)) { - session_id($sid); + if (!\is_bool($sid)) { + \session_id($sid); } $this->inactivityInterval = $inactivityInterval; if (session_status() !== PHP_SESSION_ACTIVE && !headers_sent()) { - session_set_cookie_params($liftetime, '/', '', false, true); - session_start(); + \session_set_cookie_params($liftetime, '/', '', false, true); + \session_start(); } - if ($this->inactivityInterval > 0 && ($this->inactivityInterval + ($_SESSION['lastActivity'] ?? 0) < time())) { + if ($this->inactivityInterval > 0 && ($this->inactivityInterval + ($_SESSION['lastActivity'] ?? 0) < \time())) { $this->destroy(); } $this->sessionData = $_SESSION; $_SESSION = null; - $this->sessionData['lastActivity'] = time(); - $this->sid = session_id(); + $this->sessionData['lastActivity'] = \time(); + $this->sid = \session_id(); $this->setCsrfProtection(); } @@ -175,7 +175,7 @@ class HttpSession implements SessionInterface { if (!self::$isLocked) { $_SESSION = $this->sessionData; - session_write_close(); + \session_write_close(); } } @@ -218,9 +218,9 @@ class HttpSession implements SessionInterface */ private function destroy() : void { - session_destroy(); + \session_destroy(); $this->sessionData = []; - session_start(); + \session_start(); } /** diff --git a/DataStorage/Web/Builder.php b/DataStorage/Web/Builder.php index 3455ff376..268029182 100644 --- a/DataStorage/Web/Builder.php +++ b/DataStorage/Web/Builder.php @@ -11,7 +11,7 @@ * @link http://website.orange-management.de */ declare(strict_types=1); -namespace phpOMS\Utils\Crawler; +namespace phpOMS\DataStorage\Web; use phpOMs\DataStorage\Database\Query\Builder as DatabaseQueryBuilder; use phpOMS\Localization\Localization; @@ -26,7 +26,7 @@ use phpOMS\Uri\Http; * @link http://website.orange-management.de * @since 1.0.0 */ -class Builder extends DatabaseQueryBuilder +class Builder { private function download($uri) diff --git a/Dispatcher/Dispatcher.php b/Dispatcher/Dispatcher.php index 8cdfaf961..3db81f3ad 100644 --- a/Dispatcher/Dispatcher.php +++ b/Dispatcher/Dispatcher.php @@ -103,9 +103,9 @@ final class Dispatcher private function dispatchString(string $controller, array $data = null) : array { $views = []; - $dispatch = explode(':', $controller); + $dispatch = \explode(':', $controller); - if (!file_exists($path = __DIR__ . '/../../' . str_replace('\\', '/', $dispatch[0]) . '.php')) { + if (!\file_exists($path = __DIR__ . '/../../' . \str_replace('\\', '/', $dispatch[0]) . '.php')) { throw new PathException($path); } @@ -174,7 +174,7 @@ final class Dispatcher if (!isset($this->controllers[$controller])) { // If module controller use module manager for initialization if (strpos('\Modules\Controller', $controller) === 0) { - $split = explode('\\', $controller); + $split = \explode('\\', $controller); $this->controllers[$controller] = $this->app->moduleManager->get($split[2]); } else { $this->controllers[$controller] = new $controller($this->app); diff --git a/Math/Optimization/TSP/City.php b/Localization/Defaults/City.php similarity index 51% rename from Math/Optimization/TSP/City.php rename to Localization/Defaults/City.php index a99b3f43f..a868da69f 100644 --- a/Math/Optimization/TSP/City.php +++ b/Localization/Defaults/City.php @@ -4,7 +4,7 @@ * * PHP Version 7.2 * - * @package TBD + * @package phpOMS\Localization\Defaults * @copyright Dennis Eichhorn * @license OMS License 1.0 * @version 1.0.0 @@ -12,22 +12,44 @@ */ declare(strict_types=1); -namespace phpOMS\Math\Optimization\TSP; - -use phpOMS\Math\Geometry\Shape\D3\Sphere; +namespace phpOMS\Localization\Defaults; /** * City class. * - * @package Framework + * @package phpOMS\Localization\Defaults * @license OMS License 1.0 * @link http://website.orange-management.de * @since 1.0.0 */ -class City +final class City { /** - * City name + * City id. + * + * @var int + * @since 1.0.0 + */ + private $id = 0; + + /** + * Country code. + * + * @var string + * @since 1.0.0 + */ + private $countryCode = ''; + + /** + * State code. + * + * @var string + * @since 1.0.0 + */ + private $state = ''; + + /** + * City name. * * @var string * @since 1.0.0 @@ -35,15 +57,15 @@ class City private $name = ''; /** - * City longitude + * Postal code. * - * @var float + * @var int * @since 1.0.0 */ - private $long = 0.0; + private $postal = 0; /** - * City latitude + * Latitude. * * @var float * @since 1.0.0 @@ -51,37 +73,15 @@ class City private $lat = 0.0; /** - * Constructor. + * Longitude. * - * @param float $lat Latitude - * @param float $long Longitude - * @param string $name City name - * - * @since 1.0.0 + * @var float + * @since 1.0.0 */ - public function __construct(float $lat = 0, float $long = 0, string $name = '') - { - $this->long = $long; - $this->lat = $lat; - $this->name = $name; - } + private $long = 0.0; /** - * Is equals to. - * - * @param City $city City - * - * @return bool - * - * @since 1.0.0 - */ - public function equals(City $city) : bool - { - return $this->name === $city->getName() && $this->lat === $city->getLatitude() && $this->long === $city->getLatitude(); - } - - /** - * Get name. + * Get city name * * @return string * @@ -93,39 +93,61 @@ class City } /** - * Get latitude. + * Get country code + * + * @return string + * + * @since 1.0.0 + */ + public function getCountryCode() : string + { + return $this->countryCode; + } + + /** + * Get city state + * + * @return string + * + * @since 1.0.0 + */ + public function getState() : string + { + return $this->state; + } + + /** + * Get city postal + * + * @return int + * + * @since 1.0.0 + */ + public function getPostal() : int + { + return $this->postal; + } + + /** + * Get city latitude * * @return float * * @since 1.0.0 */ - public function getLatitude() : float + public function getLat() : float { return $this->lat; } /** - * Distance to city in meter - * - * @param City $city City + * Get city longitude * * @return float * * @since 1.0.0 */ - public function getDistanceTo(City $city) : float - { - return Sphere::distance2PointsOnSphere($this->lat, $this->long, $city->getLatitude(), $city->getLongitude()); - } - - /** - * Get longitude. - * - * @return float - * - * @since 1.0.0 - */ - public function getLongitude() : float + public function getLong() : float { return $this->long; } diff --git a/Localization/Defaults/CityMapper.php b/Localization/Defaults/CityMapper.php new file mode 100644 index 000000000..e0d0337f4 --- /dev/null +++ b/Localization/Defaults/CityMapper.php @@ -0,0 +1,64 @@ +> + * @since 1.0.0 + */ + protected static $columns = [ + 'city_id' => ['name' => 'city_id', 'type' => 'int', 'internal' => 'id'], + 'city_city' => ['name' => 'city_city', 'type' => 'string', 'internal' => 'name'], + 'city_country' => ['name' => 'city_country', 'type' => 'string', 'internal' => 'countryCode'], + 'city_state' => ['name' => 'city_state', 'type' => 'string', 'internal' => 'state'], + 'city_postal' => ['name' => 'city_postal', 'type' => 'int', 'internal' => 'postal'], + 'city_lat' => ['name' => 'city_lat', 'type' => 'float', 'internal' => 'lat'], + 'city_long' => ['name' => 'city_long', 'type' => 'float', 'internal' => 'long'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + protected static $table = 'city'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + protected static $primaryField = 'city_id'; +} diff --git a/Localization/Defaults/Country.php b/Localization/Defaults/Country.php new file mode 100644 index 000000000..7d2c5209e --- /dev/null +++ b/Localization/Defaults/Country.php @@ -0,0 +1,134 @@ +name; + } + + /** + * Get country code + * + * @return string + * + * @since 1.0.0 + */ + public function getCode2() : string + { + return $this->code2; + } + + /** + * Get country code + * + * @return string + * + * @since 1.0.0 + */ + public function getCode3() : string + { + return $this->code3; + } + + /** + * Get country numeric + * + * @return int + * + * @since 1.0.0 + */ + public function getNumeric() : int + { + return $this->numeric; + } + + /** + * Get country subdevision + * + * @return string + * + * @since 1.0.0 + */ + public function getSubdevision() : string + { + return $this->subdevision; + } +} diff --git a/Localization/Defaults/CountryMapper.php b/Localization/Defaults/CountryMapper.php new file mode 100644 index 000000000..5f5f3c5e8 --- /dev/null +++ b/Localization/Defaults/CountryMapper.php @@ -0,0 +1,63 @@ +> + * @since 1.0.0 + */ + protected static $columns = [ + 'country_id' => ['name' => 'country_id', 'type' => 'int', 'internal' => 'id'], + 'country_name' => ['name' => 'country_name', 'type' => 'string', 'internal' => 'name'], + 'country_code2' => ['name' => 'country_code2', 'type' => 'string', 'internal' => 'code2'], + 'country_code3' => ['name' => 'country_code3', 'type' => 'string', 'internal' => 'code3'], + 'country_numeric' => ['name' => 'country_numeric', 'type' => 'int', 'internal' => 'numeric'], + 'country_subdevision' => ['name' => 'country_subdevision', 'type' => 'float', 'internal' => 'subdevision'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + protected static $table = 'country'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + protected static $primaryField = 'country_id'; +} diff --git a/Localization/Defaults/Currency.php b/Localization/Defaults/Currency.php new file mode 100644 index 000000000..225d3c00e --- /dev/null +++ b/Localization/Defaults/Currency.php @@ -0,0 +1,134 @@ +name; + } + + /** + * Get currency code + * + * @return string + * + * @since 1.0.0 + */ + public function getCode() : string + { + return $this->code; + } + + /** + * Get currency code + * + * @return int + * + * @since 1.0.0 + */ + public function getNumber() : int + { + return $this->number; + } + + /** + * Get currency decimals + * + * @return int + * + * @since 1.0.0 + */ + public function getDecimals() : int + { + return $this->decimals; + } + + /** + * Get currency countries + * + * @return string + * + * @since 1.0.0 + */ + public function getCountries() : string + { + return $this->countries; + } +} diff --git a/Localization/Defaults/CurrencyMapper.php b/Localization/Defaults/CurrencyMapper.php new file mode 100644 index 000000000..93f45c6e1 --- /dev/null +++ b/Localization/Defaults/CurrencyMapper.php @@ -0,0 +1,63 @@ +> + * @since 1.0.0 + */ + protected static $columns = [ + 'currency_id' => ['name' => 'currency_id', 'type' => 'int', 'internal' => 'id'], + 'currency_name' => ['name' => 'currency_name', 'type' => 'string', 'internal' => 'name'], + 'currency_code' => ['name' => 'currency_code', 'type' => 'string', 'internal' => 'code'], + 'currency_number' => ['name' => 'currency_number', 'type' => 'int', 'internal' => 'number'], + 'currency_decimal' => ['name' => 'currency_decimal', 'type' => 'int', 'internal' => 'decimal'], + 'currency_countries' => ['name' => 'currency_countries', 'type' => 'string', 'internal' => 'countries'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + protected static $table = 'currency'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + protected static $primaryField = 'currency_id'; +} diff --git a/Localization/Defaults/Iban.php b/Localization/Defaults/Iban.php new file mode 100644 index 000000000..27e6f6979 --- /dev/null +++ b/Localization/Defaults/Iban.php @@ -0,0 +1,114 @@ +country; + } + + /** + * Get iban chars + * + * @return string + * + * @since 1.0.0 + */ + public function getChars() : string + { + return $this->chars; + } + + /** + * Get iban bban + * + * @return string + * + * @since 1.0.0 + */ + public function getBban() : string + { + return $this->bban; + } + + /** + * Get iban fields + * + * @return string + * + * @since 1.0.0 + */ + public function getFields() : string + { + return $this->fields; + } +} diff --git a/Localization/Defaults/IbanMapper.php b/Localization/Defaults/IbanMapper.php new file mode 100644 index 000000000..886827542 --- /dev/null +++ b/Localization/Defaults/IbanMapper.php @@ -0,0 +1,62 @@ +> + * @since 1.0.0 + */ + protected static $columns = [ + 'iban_id' => ['name' => 'iban_id', 'type' => 'int', 'internal' => 'id'], + 'iban_country' => ['name' => 'iban_country', 'type' => 'string', 'internal' => 'country'], + 'iban_chars' => ['name' => 'iban_chars', 'type' => 'string', 'internal' => 'chars'], + 'iban_bban' => ['name' => 'iban_bban', 'type' => 'string', 'internal' => 'bban'], + 'iban_fields' => ['name' => 'iban_fields', 'type' => 'string', 'internal' => 'fields'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + protected static $table = 'iban'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + protected static $primaryField = 'iban_id'; +} diff --git a/Localization/Defaults/Language.php b/Localization/Defaults/Language.php new file mode 100644 index 000000000..e87a3f358 --- /dev/null +++ b/Localization/Defaults/Language.php @@ -0,0 +1,114 @@ +name; + } + + /** + * Get language native + * + * @return string + * + * @since 1.0.0 + */ + public function getNative() : string + { + return $this->native; + } + + /** + * Get language code + * + * @return string + * + * @since 1.0.0 + */ + public function getCode2() : string + { + return $this->code2; + } + + /** + * Get language code + * + * @return string + * + * @since 1.0.0 + */ + public function getCode3() : string + { + return $this->code3; + } +} diff --git a/Localization/Defaults/LanguageMapper.php b/Localization/Defaults/LanguageMapper.php new file mode 100644 index 000000000..359dc941f --- /dev/null +++ b/Localization/Defaults/LanguageMapper.php @@ -0,0 +1,62 @@ +> + * @since 1.0.0 + */ + protected static $columns = [ + 'language_id' => ['name' => 'language_id', 'type' => 'int', 'internal' => 'id'], + 'language_name' => ['name' => 'language_name', 'type' => 'string', 'internal' => 'name'], + 'language_native' => ['name' => 'language_native', 'type' => 'string', 'internal' => 'native'], + 'language_639_2T' => ['name' => 'language_639_2T', 'type' => 'string', 'internal' => 'code2'], + 'language_639_3' => ['name' => 'language_639_3', 'type' => 'string', 'internal' => 'code3'], + ]; + + /** + * Primary table. + * + * @var string + * @since 1.0.0 + */ + protected static $table = 'language'; + + /** + * Primary field name. + * + * @var string + * @since 1.0.0 + */ + protected static $primaryField = 'language_id'; +} diff --git a/Localization/Default/en_US.json b/Localization/Defaults/en_US.json similarity index 100% rename from Localization/Default/en_US.json rename to Localization/Defaults/en_US.json diff --git a/Localization/Default/Location/localization.sqlite b/Localization/Defaults/localization.sqlite similarity index 99% rename from Localization/Default/Location/localization.sqlite rename to Localization/Defaults/localization.sqlite index b2cdedb9c..9f7cab4d4 100644 Binary files a/Localization/Default/Location/localization.sqlite and b/Localization/Defaults/localization.sqlite differ diff --git a/Localization/Money.php b/Localization/Money.php index f09878f33..d3534fc8e 100644 --- a/Localization/Money.php +++ b/Localization/Money.php @@ -106,9 +106,9 @@ final class Money implements \Serializable */ public static function toInt(string $value, string $thousands = ',', string $decimal = '.') : int { - $split = explode($decimal, $value); + $split = \explode($decimal, $value); $left = $split[0]; - $left = str_replace($thousands, '', $left); + $left = \str_replace($thousands, '', $left); $right = ''; if (count($split) > 1) { diff --git a/Log/FileLogger.php b/Log/FileLogger.php index ef3fce48b..34e2aeed1 100644 --- a/Log/FileLogger.php +++ b/Log/FileLogger.php @@ -119,7 +119,7 @@ final class FileLogger implements LoggerInterface */ private function createFile() : void { - if (!$this->created && !file_exists($this->path)) { + if (!$this->created && !\file_exists($this->path)) { File::create($this->path); $this->created = true; } @@ -186,7 +186,7 @@ final class FileLogger implements LoggerInterface return false; } - $mtime = explode(' ', microtime()); + $mtime = \explode(' ', microtime()); $mtime = $mtime[1] + $mtime[0]; self::$timings[$id] = ['start' => $mtime]; @@ -205,7 +205,7 @@ final class FileLogger implements LoggerInterface */ public static function endTimeLog($id = '') : float { - $mtime = explode(' ', microtime()); + $mtime = \explode(' ', microtime()); $mtime = $mtime[1] + $mtime[0]; self::$timings[$id]['end'] = $mtime; @@ -241,7 +241,7 @@ final class FileLogger implements LoggerInterface } } - $backtrace = json_encode($backtrace); + $backtrace = \json_encode($backtrace); $replace['{backtrace}'] = $backtrace; $replace['{datetime}'] = sprintf('%--19s', (new \DateTime('NOW'))->format('Y-m-d H:i:s')); @@ -382,7 +382,7 @@ final class FileLogger implements LoggerInterface { $levels = []; - if (!file_exists($this->path)) { + if (!\file_exists($this->path)) { return $levels; } @@ -418,7 +418,7 @@ final class FileLogger implements LoggerInterface { $connection = []; - if (!file_exists($this->path)) { + if (!\file_exists($this->path)) { return $connection; } @@ -457,7 +457,7 @@ final class FileLogger implements LoggerInterface $logs = []; $id = 0; - if (!file_exists($this->path)) { + if (!\file_exists($this->path)) { return $logs; } @@ -506,7 +506,7 @@ final class FileLogger implements LoggerInterface $log = []; $current = 0; - if (!file_exists($this->path)) { + if (!\file_exists($this->path)) { return $log; } diff --git a/Math/Geometry/Shape/D2/Triangle.php b/Math/Geometry/Shape/D2/Triangle.php index 003683718..d1dff54fb 100644 --- a/Math/Geometry/Shape/D2/Triangle.php +++ b/Math/Geometry/Shape/D2/Triangle.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace phpOMS\Math\Geometry\Shape\D2; +use phpOMS\Math\Functions\Functions; + /** * Triangle shape. * @@ -76,4 +78,23 @@ final class Triangle implements D2ShapeInterface { return 2 * $area / $b; } + + /** + * Calculate the hypothenuse + * + * @param mixed ...$vec Vector of values + * + * @return float + * + * @since 1.0.0 + */ + public static function getHypot(...$vec) : float + { + $hypot = 0.0; + foreach ($vec as $val) { + $hypot += $val * $val; + } + + return \sqrt($hypot); + } } diff --git a/Math/Matrix/CholeskyDecomposition.php b/Math/Matrix/CholeskyDecomposition.php index 3de6933b6..8b19164e4 100644 --- a/Math/Matrix/CholeskyDecomposition.php +++ b/Math/Matrix/CholeskyDecomposition.php @@ -18,6 +18,8 @@ use phpOMS\Math\Matrix\Exception\InvalidDimensionException; /** * Cholesky decomposition + * + * A is syymetric, positive definite then A = L*L' * * @package phpOMS\Math\Matrix * @license OMS License 1.0 diff --git a/Math/Matrix/EigenvalueDecomposition.php b/Math/Matrix/EigenvalueDecomposition.php index 12281785e..9a32d4910 100644 --- a/Math/Matrix/EigenvalueDecomposition.php +++ b/Math/Matrix/EigenvalueDecomposition.php @@ -14,14 +14,347 @@ declare(strict_types=1); namespace phpOMS\Math\Matrix; +use phpOMS\Math\Geometry\Shape\D2\Triangle; + /** * Eigenvalue decomposition + * + * A symmetric then A = V*D*V' + * A not symmetric then (potentially) A = V*D*inverse(V) * * @package phpOMS\Math\Matrix * @license OMS License 1.0 * @link http://website.orange-management.de * @since 1.0.0 */ -final class EigenValueDecomposition +final class EigenvalueDecomposition { + /** + * Dimension m + * + * @var int + * @since 1.0.0 + */ + private $m = 0; + + /** + * Is symmetric + * + * @var bool + * @since 1.0.0 + */ + private $isSymmetric = true; + + /** + * A square matrix. + * + * @var array + * @since 1.0.0 + */ + private $A = []; + + /** + * Eigenvectors + * + * @var array + * @since 1.0.0 + */ + private $V = []; + + /** + * Eigenvalues + * + * @var array + * @since 1.0.0 + */ + private $D = []; + + /** + * Eigenvalues + * + * @var array + * @since 1.0.0 + */ + private $E = []; + + /** + * Hessenberg form + * + * @var array + * @since 1.0.0 + */ + private $H = []; + + /** + * Non-symmetric storage + * + * @var array + * @since 1.0.0 + */ + private $ort = []; + + /** + * Constructor. + * + * @param Matrix $M Matrix + * + * @since 1.0.0 + */ + public function __construct(Matrix $M) + { + $this->m = $M->getM(); + $this->A = $M->toArray(); + } + + /** + * Housholder tridiagonal form reduction. + * + * @return void + * + * @since 1.0.0 + */ + private function tred2() : void + { + for ($j = 0; $j < $this->m; ++$j) { + $this->D[$j] = $this->V[$this->m - 1][$j]; + } + + for ($i = $this->m - 1; $i > 0; --$i) { + $scale = 0.0; + $h = 0.0; + + for ($k = 0; $k < $i; ++$k) { + $scale += \abs($this->D[$k]); + } + + if ($scale === 0.0) { + $this->E[$i] = $this->D[$i - 1]; + for ($j = 0; $j > $i; ++$j) { + $this->D[$j] = $this->V[$i - 1][$j]; + $this->V[$i][$j] = 0.0; + $this->V[$j][$i] = 0.0; + } + } else { + for ($k = 0; $k < $i; ++$k) { + $this->D[$k] /= $scale; + $h += $this->D[$k] * $this->D[$k]; + } + + $f = $this->D[$i - 1]; + $g = \sqrt($h); + + if ($f > 0) { + $g = -$g; + } + + $this->E[$i] = $scale * $g; + $h -= $f * $g; + $this->D[$i - 1] = $f - $g; + + for ($j = 0; $j < $i; ++$j) { + $this->E[$j] = 0.0; + } + + for ($j = 0; $j < $i; ++$j) { + $f = $this->D[$j]; + $this->V[$j][$i] = $f; + $g = $this->E[$j] + $this->V[$j][$j] * $f; + + for ($k = $j + 1; $k <= $i - 1; ++$k) { + $g += $this->V[$k][$j] * $this->D[$k]; + $this->E[$k] += $this->V[$k][$j] * $f; + } + + $this->E[$j] = $g; + } + + $f = 0.0; + for ($j = 0; $j < $i; ++$j) { + $this->E[$j] /= $h; + $f += $this->E[$j] * $this->D[$j]; + } + + $hh = $f / ($h + $h); + for ($j = 0; $j < $i; ++$j) { + $this->E[$j] -= $hh * $this->D[$j]; + } + + for ($j = 0; $j < $i; ++$j) { + $f = $this->D[$j]; + $g = $this->E[$j]; + + for ($k = $j; $k <= $i - 1; ++$k) { + $this->V[$k][$j] -= ($f * $this->E[$k] + $g * $this->D[$k]); + } + + $this->D[$j] = $this->V[$i - 1][$j]; + $this->V[$i][$j] = 0.0; + } + } + + $this->D[$i] = $h; + } + + for ($i = 0; $i < $this->m - 1; ++$i) { + $this->V[$this->m - 1][$i] = $this->V[$i][$i]; + $this->V[$i][$i] = 1.0; + $h = $this->D[$i + 1]; + + if ($h !== 0.0) { + for ($k = 0; $k <= $i; ++$k) { + $this->D[$k] = $this->V[$k][$i + 1] / $h; + } + + for ($j = 0; $j <= $i; ++$j) { + $g = 0.0; + for ($k = 0; $k <= $i; ++$k) { + $g += $this->V[$k][$i + 1] * $this->V[$k][$j]; + } + + for ($k = 0; $k <= $i; ++$k) { + $this->V[$k][$j] -= $g * $this->D[$k]; + } + } + } + + for ($k = 0; $k <= $i; ++$k) { + $this->V[$k][$i + 1] = 0.0; + } + } + + for ($j = 0; $j < $this->m; ++$j) { + $this->D[$j] = $this->V[$this->m - 1][$j]; + $this->V[$this->m - 1][$j] = 0.0; + } + + $this->V[$this->m - 1][$j] = 1.0; + $this->E[0] = 0.0; + } + + /** + * Symmetric tridiagonal QL + * + * @return void + * + * @since 1.0.0 + */ + private function tql2() : void + { + for ($i = 1; $i < $this->m; ++$i) { + $this->E[$i - 1] = $this->E[$i]; + } + + $this->E[$this->m - 1] = 0.0; + + $f = 0.0; + $tst1 = 0.0; + $eps = 0.00001; + + for ($l = 0; $l < $this->m; ++$l) { + $tst1 = \max($tst1, \abs($this->D[$l]) + \abs($this->E[$l])); + $m = $l; + + while ($m < $this->m) { + if (\abs($this->E[$m]) <= $eps * $tst1) { + break; + } + + ++$m; + } + + if ($m > $l) { + $iter = 0; + + do { + $iter = $iter + 1; + + $g = $this->D[$l]; + $p = ($this->D[$l + 1] - $g) / (2.0 * $this->E[$l]); + $r = Triangle::getHypot($p, 1); + + if ($p > 0) { + $r = -$r; + } + + $this->D[$l] = $this->E[$l] / ($p + $r); + $this->D[$l + 1] = $this->E[$l] * ($p + $r); + $dl1 = $this->D[$l + 1]; + $h = $g - $this->D[$l]; + + for ($i = $l + 2; $i < $this->m; ++$i) { + $this->D[$i] -= $h; + } + + $f += $h; + $p = $this->D[$m]; + $c = 1.0; + $c2 = 1.0; + $c3 = 1.0; + $el1 = $this->E[$l + 1]; + $s = 0.0; + $s2 = 0.0; + + for ($i = $m - 1; $i >= $l; --$i) { + $c3 = $c2; + $c2 = $c; + $s2 = $s; + $g = $c * $this->E[$i]; + $h = $c * $p; + $r = Triangle::getHypot($p, $this->E[$i]); + $this->E[$i + 1] = $s * $r; + $s = $this->E[$i] / $r; + $c = $p / $r; + $p = $c * $this->D[$i] - $s * $g; + $this->D[$i + 1] = $h + $s * ($c * $g + $s * $this->D[$i]); + + for ($k = 0; $k < $this->m; ++$k) { + $h = $this->V[$k][$i + 1]; + $this->V[$k][$i + 1] = $s * $this->V[$k][$i] + $c * $h; + $this->V[$k][$i] = $c * $this->V[$k][$i] - $s * $h; + } + } + + $p = -$s * $s2 * $c3 * $el1 * $this->E[$l] / $dl1; + $this->E[$l] = $s * $p; + $this->D[$l] = $c * $p; + } while (\abs($this->E[$l]) > $eps * $tst1); + } + + $this->D[$l] += $f; + $this->E[$l] = 0.0; + } + + for ($i = 0; $i < $this->m - 1; ++$i) { + $k = $i; + $p = $this->D[$i]; + + for ($j = $i + 1; $j < $this->m; ++$j) { + if ($this->D[$j] < $p) { + $k = $j; + $p = $this->D[$j]; + } + } + + if ($k !== $i) { + $this->D[$k] = $this->D[$i]; + $this->D[$i] = $p; + + for ($j = 0; $j < $this->m; ++$j) { + $p = $this->V[$j][$i]; + $this->V[$j][$i] = $this->V[$j][$k]; + $this->V[$j][$k] = $p; + } + } + } + } + + private function orthes() : void + { + + } + + public function isSymmetric() : bool + { + return $this->isSymmetric; + } } diff --git a/Math/Matrix/LUDecomposition.php b/Math/Matrix/LUDecomposition.php index 59ceaa9dd..9a3dbe97f 100644 --- a/Math/Matrix/LUDecomposition.php +++ b/Math/Matrix/LUDecomposition.php @@ -18,6 +18,8 @@ use phpOMS\Math\Matrix\Exception\InvalidDimensionException; /** * LU decomposition + * + * A(piv,:) = L*U * * @package phpOMS\Math\Matrix * @license OMS License 1.0 @@ -253,8 +255,7 @@ final class LUDecomposition } $n = $B->getN(); - $X = $B->getMatrix($this->piv, 0, $n - 1); - // todo: fix get extract + $X = $B->getSubMatrixByRows($this->piv, 0, $n - 1)->toArray(); // Solve L*Y = B(piv,:) for ($k = 0; $k < $this->n; ++$k) { diff --git a/Math/Matrix/Matrix.php b/Math/Matrix/Matrix.php index e5f982c6a..504fbc4be 100644 --- a/Math/Matrix/Matrix.php +++ b/Math/Matrix/Matrix.php @@ -137,7 +137,7 @@ class Matrix implements \ArrayAccess, \Iterator /** * Get matrix array. * - * @return array + * @return array> * * @since 1.0.0 */ @@ -146,10 +146,121 @@ class Matrix implements \ArrayAccess, \Iterator return $this->matrix; } + /** + * Get sub matrix array. + * + * @param int $iRow Start row + * @param int $lRow End row + * @param int $iCol Start col + * @param int $lCol End col + * + * @return Matrix + * + * @since 1.0.0 + */ + public function getSubMatrix(int $iRow, int $lRow, int $iCol, int $lCol) : Matrix + { + $X = [[]]; + for ($i = $iRow; $i <= $lRow; ++$i) { + for ($j = $iCol; $j <= $lCol; ++$j) { + $X[$i - $iRow][$j - $iCol] = $this->matrix[$i][$j]; + } + } + + $matrix = new self(); + $matrix->setMatrix($X); + + return $matrix; + } + + /** + * Get sub matrix array. + * + * @param array $rows Row indices + * @param array $cols Row indices + * + * @return Matrix + * + * @since 1.0.0 + */ + public function getSubMatrixByColumnsRows(array $rows, array $cols) : Matrix + { + $X = [[]]; + $rlength = count($rows); + $clength = count($cols); + + for ($i = 0; $i <= $rlength; ++$i) { + for ($j = 0; $j <= $clength; ++$j) { + $X[$i][$j] = $this->matrix[$rows[$i]][$cols[$j]]; + } + } + + $matrix = new self(); + $matrix->setMatrix($X); + + return $matrix; + } + + /** + * Get sub matrix array. + * + * @param int $iRow Start row + * @param int $lRow End row + * @param array $cols Row indices + * + * @return Matrix + * + * @since 1.0.0 + */ + public function getSubMatrixByColumns(int $iRow, int $lRow, array $cols) : Matrix + { + $X = [[]]; + $length = count($cols); + + for ($i = $iRow; $i <= $lRow; ++$i) { + for ($j = 0; $j <= $length; ++$j) { + $X[$i - $iRow][$j] = $this->matrix[$i][$cols[$j]]; + } + } + + $matrix = new self(); + $matrix->setMatrix($X); + + return $matrix; + } + + /** + * Get sub matrix array. + * + * @param array $rows Row indices + * @param int $iCol Start col + * @param int $lCol End col + * + * @return Matrix + * + * @since 1.0.0 + */ + public function getSubMatrixByRows(array $rows, int $iCol, int $lCol) : Matrix + { + $X = [[]]; + $length = count($rows); + + for ($i = 0; $i < $length; ++$i) { + for ($j = $iCol; $j <= $lCol; ++$j) { + $X[$i][$j - $iCol] = $this->matrix[$rows[$i]][$j]; + } + } + + $matrix = new self(); + $matrix->setMatrix($X); + + return $matrix; + } + /** * Get matrix array. * - * @return array + * @return array> * * @since 1.0.0 */ @@ -158,6 +269,18 @@ class Matrix implements \ArrayAccess, \Iterator return $this->matrix; } + /** + * Is symmetric. + * + * @return bool + * + * @since 1.0.0 + */ + public function isSymmetric() : bool + { + return (new EigenvalueDecomposition($this))->isSymmetric(); + } + /** * Get matrix rank. * @@ -574,7 +697,7 @@ class Matrix implements \ArrayAccess, \Iterator /** * Solve matrix * - * @param Matix $B Matrix/Vector b + * @param Matrix $B Matrix/Vector b * * @return Matrix * diff --git a/Math/Matrix/QRDecomposition.php b/Math/Matrix/QRDecomposition.php index 8677ee381..ae2e1557c 100644 --- a/Math/Matrix/QRDecomposition.php +++ b/Math/Matrix/QRDecomposition.php @@ -14,8 +14,13 @@ declare(strict_types=1); namespace phpOMS\Math\Matrix; +use phpOMS\Math\Matrix\Exception\InvalidDimensionException; +use phpOMS\Math\Geometry\Shape\D2\Triangle; + /** * QR decomposition + * + * For every matrix A = Q*R * * @package phpOMS\Math\Matrix * @license OMS License 1.0 @@ -24,26 +29,58 @@ namespace phpOMS\Math\Matrix; */ final class QRDecomposition { + /** + * QR matrix. + * + * @var array[] + * @since 1.0.0 + */ private $QR = []; + /** + * Dimension m + * + * @var int + * @since 1.0.0 + */ private $m = 0; + + /** + * Dimension n + * + * @var int + * @since 1.0.0 + */ private $n = 0; + /** + * R diagonal + * + * @var array + * @since 1.0.0 + */ private $Rdiag = []; + /** + * Constructor. + * + * @param Matrix $M Matrix + * + * @since 1.0.0 + */ public function __construct(Matrix $M) { // Initialize. $this->QR = $M->toArray(); - $this->m = $M->getRowDimension(); - $this->n = $M->getColumnDimension(); + $this->m = $M->getM(); + $this->n = $M->getN(); // Main loop. for ($k = 0; $k < $this->n; ++$k) { // Compute 2-norm of k-th column without under/overflow. $nrm = 0.0; for ($i = $k; $i < $this->m; ++$i) { - $nrm = hypo($nrm, $this->QR[$i][$k]); + $nrm = Triangle::getHypot($nrm, $this->QR[$i][$k]); } if ($nrm != 0.0) { @@ -57,6 +94,7 @@ final class QRDecomposition } $this->QR[$k][$k] += 1.0; + // Apply transformation to remaining columns. for ($j = $k + 1; $j < $this->n; ++$j) { $s = 0.0; @@ -75,6 +113,13 @@ final class QRDecomposition } } + /** + * Matrix has full rank + * + * @return bool + * + * @since 1.0.0 + */ public function isFullRank() : bool { for ($j = 0; $j < $this->n; ++$j) { @@ -86,6 +131,13 @@ final class QRDecomposition return true; } + /** + * Get H matrix + * + * @return Matrix + * + * @since 1.0.0 + */ public function getH() : Matrix { $H = [[]]; @@ -101,11 +153,18 @@ final class QRDecomposition } $matrix = new Matrix(); - $matrix->setArray($H); + $matrix->setMatrix($H); return $matrix; } + /** + * Get R matrix + * + * @return Matrix + * + * @since 1.0.0 + */ public function getR() : Matrix { $R = [[]]; @@ -123,11 +182,18 @@ final class QRDecomposition } $matrix = new Matrix(); - $matrix->setArray($R); + $matrix->setMatrix($R); return $matrix; } + /** + * Get Q matrix + * + * @return Matrix + * + * @since 1.0.0 + */ public function getQ() : Matrix { $Q = [[]]; @@ -144,6 +210,7 @@ final class QRDecomposition for ($i = $k; $i < $this->m; ++$i) { $s += $this->QR[$i][$k] * $Q[$i][$j]; } + $s = -$s / $this->QR[$k][$k]; for ($i = $k; $i < $this->m; ++$i) { $Q[$i][$j] += $s * $this->QR[$i][$k]; @@ -153,21 +220,33 @@ final class QRDecomposition } $matrix = new Matrix(); - $matrix->setArray($Q); + $matrix->setMatrix($Q); return $matrix; } + /** + * Solve Ax = b + * + * @param Matrix $B Matrix + * + * @return Matrix + * + * @since 1.0.0 + */ public function solve(Matrix $B) : Matrix { - if ($B->getRowDimension() !== $this->m) { + if ($B->getM() !== $this->m) { + throw new InvalidDimensionException($B->getM()); } if (!$this->isFullRank()) { + throw new \Exception('Rank'); } - $nx = $B->getColumnDimension(); - $X = $B->getArrayCopy(); + $nx = $B->getN(); + $X = $B->toArray(); + // Compute Y = transpose(Q)*B for ($k = 0; $k < $this->n; ++$k) { for ($j = 0; $j < $nx; ++$j) { @@ -175,17 +254,20 @@ final class QRDecomposition for ($i = $k; $i < $this->m; ++$i) { $s += $this->QR[$i][$k] * $X[$i][$j]; } + $s = -$s / $this->QR[$k][$k]; for ($i = $k; $i < $this->m; ++$i) { $X[$i][$j] += $s * $this->QR[$i][$k]; } } } + // Solve R*X = Y; for ($k = $this->n - 1; $k >= 0; --$k) { for ($j = 0; $j < $nx; ++$j) { $X[$k][$j] /= $this->Rdiag[$k]; } + for ($i = 0; $i < $k; ++$i) { for ($j = 0; $j < $nx; ++$j) { $X[$i][$j] -= $X[$k][$j] * $this->QR[$i][$k]; @@ -194,8 +276,8 @@ final class QRDecomposition } $matrix = new Matrix(); - $matrix->setArray($X); + $matrix->setMatrix($X); - return $matrix; + return $matrix->getSubMatrix(0, $this->n - 1, 0, $nx - 1); } } diff --git a/Math/Optimization/AssignmentProblem.php b/Math/Optimization/AssignmentProblem.php deleted file mode 100644 index 8b1378917..000000000 --- a/Math/Optimization/AssignmentProblem.php +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Math/Optimization/GeneticAlgorithmInterface.php b/Math/Optimization/GeneticAlgorithmInterface.php deleted file mode 100644 index 3087df302..000000000 --- a/Math/Optimization/GeneticAlgorithmInterface.php +++ /dev/null @@ -1,30 +0,0 @@ -getEdges(); - - foreach ($graphArray as $edge) { - array_push($vertices, $edge[0], $edge[1]); - $neighbours[$edge[0]][] = ["end" => $edge[1], "cost" => $edge[2]]; - $neighbours[$edge[1]][] = ["end" => $edge[0], "cost" => $edge[2]]; - } - - $vertices = array_unique($vertices); - - $dist = []; - $previous = []; - foreach ($vertices as $vertex) { - $dist[$vertex] = INF; - $previous[$vertex] = null; - } - - $dist[$source] = 0; - $Q = $vertices; - - while (count($Q) > 0) { - - // TODO - Find faster way to get minimum - $min = INF; - - foreach ($Q as $vertex) { - if ($dist[$vertex] < $min) { - $min = $dist[$vertex]; - $u = $vertex; - } - } - - $Q = array_diff($Q, [$u]); - - if ($dist[$u] == INF || $u == $target) { - break; - } - - if (isset($neighbours[$u])) { - foreach ($neighbours[$u] as $arr) { - $alt = $dist[$u] + $arr["cost"]; - - if ($alt < $dist[$arr["end"]]) { - $dist[$arr["end"]] = $alt; - $previous[$arr["end"]] = $u; - } - } - } - } - - $path = []; - $u = $target; - - while (isset($previous[$u])) { - array_unshift($path, $u); - $u = $previous[$u]; - } - - array_unshift($path, $u); - - return $path; - } -} diff --git a/Math/Optimization/Graph/EdgeInterface.php b/Math/Optimization/Graph/EdgeInterface.php deleted file mode 100644 index ee7e34468..000000000 --- a/Math/Optimization/Graph/EdgeInterface.php +++ /dev/null @@ -1,76 +0,0 @@ -cityPool = $pool; - - if ($this->cityPool->count() > self::LIMIT) { - throw new \Exception('Overflow'); - } - } - - /** - * Calculate best routes. - * - * @param int $limit Amount of best routes - * - * @return Population - * - * @since 1.0.0 - */ - public function getSolution(int $limit = 1) : Population - { - $population = new Population($this->cityPool, $limit, true); - $cities = $this->cityPool->getCities(); - - $this->bruteForce($cities, new Tour($this->cityPool, false), $population); - - return $population; - } - - /** - * Bruteforce best solutions. - * - * @param array $cities Cities - * @param Tour $tour Current (potential) optimal tour - * @param Population $population Population of tours - * - * @return Population - * - * @since 1.0.0 - */ - private function bruteForce(array $cities, Tour $tour, Population $population) - { - if (empty($cities)) { - $population->addTour($tour); - } - - $count = count($cities); - for ($i = 0; $i < $count; ++$i) { - $extended = clone $tour; - $extended->addCity($cities[$i]); - unset($cities[$i]); - - if ($population->getUnfittest()->getFitness() > $extended->getFitness()) { - continue; - } - - $this->bruteForce($cities, $extended, $population); - } - } -} diff --git a/Math/Optimization/TSP/CityPool.php b/Math/Optimization/TSP/CityPool.php deleted file mode 100644 index ddfc64f86..000000000 --- a/Math/Optimization/TSP/CityPool.php +++ /dev/null @@ -1,118 +0,0 @@ -cities = $cities; - } - - /** - * Add city. - * - * @param City $city City - * - * @return void - * - * @since 1.0.0 - */ - public function addCity(City $city) : void - { - $this->cities[$city->getName() . $city->getLatitude() . $city->getLongitude()] = $city; - } - - /** - * Get city. - * - * @param int $index City index - * - * @return City - * - * @since 1.0.0 - */ - public function getCity(int $index) : City - { - return array_values($this->cities)[$index]; - } - - /** - * Get cities. - * - * @return array - * - * @since 1.0.0 - */ - public function getCities() : array - { - return $this->cities; - } - - /** - * Has city. - * - * @param City $city City - * - * @return bool - * - * @since 1.0.0 - */ - public function hasCity(City $city) : bool - { - foreach ($this->cities as $c) { - if ($c->equals($city)) { - return true; - } - } - - return false; - } - - /** - * Count cities - * - * @return int - * - * @since 1.0.0 - */ - public function count() : int - { - return count($this->cities); - } -} diff --git a/Math/Optimization/TSP/GA.php b/Math/Optimization/TSP/GA.php deleted file mode 100644 index ff85ee681..000000000 --- a/Math/Optimization/TSP/GA.php +++ /dev/null @@ -1,195 +0,0 @@ -cityPool = $pool; - } - - /** - * Evolve population. - * - * @param Population $population Population to eveolve - * - * @return Population - * - * @since 1.0.0 - */ - public function evolvePopulation(Population $population) : Population - { - $shift = self::ELITISM ? 1 : 0; - $newPopulation = new Population($this->cityPool, $count = $population->count(), false); - - $newPopulation->add($population->getFittest()); - - for ($i = $shift; $i < $count; ++$i) { - $parent1 = $this->tournamentSelection($population); - $parent2 = $this->tournamentSelection($population); - $child = $this->crossover($parent1, $parent2); - - $newPopulation->set($i, $child); - } - - $count2 = $newPopulation->count(); - - for ($i = $shift; $i < $count2; ++$i) { - $this->mutate($newPopulation->get($i)); - } - - return $newPopulation; - } - - /** - * Find fittest - * - * @param Population $population Population to evaluate - * - * @return Tour - * - * @since 1.0.0 - */ - private function tournamentSelection(Population $population) : Tour - { - $tournament = new Population($this->cityPool, self::TOURNAMENT, false); - $populationSize = $population->count() - 1; - - for ($i = 0; $i < self::TOURNAMENT; ++$i) { - $tournament->add($population->get(mt_rand(0, $populationSize))); - } - - return $tournament->getFittest(); - } - - /** - * Crossover tours - * - * @param Tour $tour1 Tour 1 - * @param Tour $tour2 Tour 2 - * - * @return Tour - * - * @since 1.0.0 - */ - public function crossover(Tour $tour1, Tour $tour2) : Tour - { - $child = new Tour($this->cityPool, false); - - $start = mt_rand(0, $tour1->count() - 1); - $end = mt_rand(0, $tour1->count() - 1); - - $count = $child->count(); /* $tour1->count() ???!!!! */ - - for ($i = 0; $i < $count; ++$i) { - if ($start < $end && $i > $start && $i < $end) { - $child->setCity($i, $tour1->getCity($i)); - } elseif ($start > $end && !($i < $start && $i > $end)) { - $child->setCity($i, $tour1->getCity($i)); - } - } - - $count = $tour2->count(); - - for ($i = 0; $i < $count; ++$i) { - if (!$child->hasCity($tour2->getCity($i))) { - for ($j = 0; $j < $child->count(); ++$j) { - if ($child->getCity($j) === null) { - $child->setCity($j, $tour2->getCity($i)); - break; - } - } - } - } - - return $child; - } - - /** - * Mutate tour - * - * @param Tour $tour Tour to mutate - * - * @return void - * - * @since 1.0.0 - */ - private function mutate(Tour $tour) - { - $count = $tour->count(); - - for ($pos1 = 0; $pos1 < $count; $pos1++) { - if (mt_rand(0, 1000) < self::MUTATION) { - $pos2 = mt_rand(0, $tour->count() - 1); - - /* Could be same pos! */ - $city1 = $tour->getCity($pos1); - $city2 = $tour->getCity($pos2); - - /* swapping */ - $tour->setCity($pos1, $city2); - $tour->setCity($pos2, $city1); - } - } - } -} diff --git a/Math/Optimization/TSP/Population.php b/Math/Optimization/TSP/Population.php deleted file mode 100644 index 448b5fb2c..000000000 --- a/Math/Optimization/TSP/Population.php +++ /dev/null @@ -1,165 +0,0 @@ -tours[] = new Tour($pool, true); - } - } - } - - /** - * Insert Tour at position. - * - * @param int $index Position to insert at - * @param Tour $tour Tour to insert - * - * @return void - * - * @since 1.0.0 - */ - public function insertAt(int $index, Tour $tour) : void - { - $this->tours = array_slice($this->tours, 0, $index) + [$tour] + array_slice($this->tours, $index); - } - - /** - * Set tour at position - * - * @param int $index Position to set/replace - * @param Tour $tour Tour to set - * - * @return void - * - * @since 1.0.0 - */ - public function set(int $index, Tour $tour) : void - { - $this->tours[$index] = $tour; - asort($this->tours); - } - - /** - * Add tour - * - * @param Tour $tour Tour to add - * - * @return void - * - * @since 1.0.0 - */ - public function add(Tour $tour) : void - { - $this->tours[] = $tour; - } - - /** - * Get tour - * - * @param int $index Index of tour - * - * @return null|Tour - * - * @since 1.0.0 - */ - public function get(int $index) - { - return $this->tours[$index] ?? null; - } - - /** - * Get fittest tour - * - * @return Tour - * - * @since 1.0.0 - */ - public function getFittest() : Tour - { - $fittest = $this->tours[0]; - $count = count($this->tours); - - for ($i = 1; $i < $count; ++$i) { - if ($fittest->getFitness() <= $this->tours[$i]->getFitness()) { - $fittest = $this->tours[$i]; - } - } - - return $fittest; - } - - /** - * Get unfittest tour - * - * @return Tour - * - * @since 1.0.0 - */ - public function getUnfittest() : Tour - { - $unfittest = $this->tours[0]; - $count = count($this->tours); - - for ($i = 1; $i < $count; ++$i) { - if ($unfittest->getFitness() >= $this->tours[$i]->getFitness()) { - $unfittest = $this->tours[$i]; - } - } - - return $unfittest; - } - - /** - * Get tour count - * - * @return int - * - * @since 1.0.0 - */ - public function count() : int - { - return count($this->tours); - } -} diff --git a/Math/Optimization/TSP/Tour.php b/Math/Optimization/TSP/Tour.php deleted file mode 100644 index 7b065e556..000000000 --- a/Math/Optimization/TSP/Tour.php +++ /dev/null @@ -1,200 +0,0 @@ -cityPool = $pool; - - if ($initialize) { - $this->cities = $this->cityPool->getCities(); - shuffle($this->cities); - } - } - - /** - * Get city. - * - * @param int $index Index - * - * @return null|City - * - * @since 1.0.0 - */ - public function getCity($index) - { - return array_values($this->cities)[$index] ?? null; - } - - /** - * Get fitness. - * - * @return float - * - * @since 1.0.0 - */ - public function getFitness() : float - { - if ($this->fitness === 0.0 && ($distance = $this->getDistance()) !== 0.0) { - $this->fitness = 1 / $distance; - } - - return $this->fitness; - } - - /** - * Get tour distance - * - * @return float - * - * @since 1.0.0 - */ - public function getDistance() : float - { - if ($this->distance === 0.0) { - $distance = 0.0; - - $count = count($this->cities); - - for ($i = 0; $i < $count; ++$i) { - $dest = ($i + 1 < $count) ? $this->cities[$i + 1] : $this->cities[0]; - - $distance += $this->cities[$i]->getDistanceTo($dest); - } - - $this->distance = $distance; - } - - return $this->distance; - } - - /** - * Add city to tour. - * - * @param City $city City - * - * @return void - * - * @since 1.0.0 - */ - public function addCity(City $city) : void - { - $this->cities[] = $city; - - $this->fitness = 0.0; - $this->distance = 0.0; - } - - /** - * Set city - * - * @param int $index Index to set/replace - * @param City $city City - * - * @return void - * - * @since 1.0.0 - */ - public function setCity(int $index, City $city) : void - { - $this->cities[$index] = $city; - asort($this->cities); - - $this->fitness = 0.0; - $this->distance = 0.0; - } - - /** - * Has city. - * - * @param City $city City - * - * @return bool - * - * @since 1.0.0 - */ - public function hasCity(City $city) : bool - { - foreach ($this->cities as $c) { - if ($c->equals($city)) { - return true; - } - } - - return false; - } - - /** - * Get city count - * - * @return int - * - * @since 1.0.0 - */ - public function count() : int - { - return count($this->cities); - } -} diff --git a/Math/Optimization/TransportationProblem.php b/Math/Optimization/TransportationProblem.php deleted file mode 100644 index 8b1378917..000000000 --- a/Math/Optimization/TransportationProblem.php +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Math/Parser/Evaluator.php b/Math/Parser/Evaluator.php index a057bf5e0..2aab74418 100644 --- a/Math/Parser/Evaluator.php +++ b/Math/Parser/Evaluator.php @@ -41,10 +41,10 @@ class Evaluator public static function evaluate(string $formula, array $vars) : float { // todo: do i need array_values here? - $formula = str_replace(array_keys($vars), array_values($vars), $formula); + $formula = \str_replace(array_keys($vars), array_values($vars), $formula); // todo: this is horrible in case things like mod etc. need to be supported - if (preg_match('#[^0-9\+\-\*\/\(\)]#', $formula)) { + if (\preg_match('#[^0-9\+\-\*\/\(\)]#', $formula)) { throw new \Exception('Bad elements'); } diff --git a/Math/Stochastic/Distribution/PoissonDistribution.php b/Math/Stochastic/Distribution/PoissonDistribution.php index 1c7b2e747..438982080 100644 --- a/Math/Stochastic/Distribution/PoissonDistribution.php +++ b/Math/Stochastic/Distribution/PoissonDistribution.php @@ -15,6 +15,7 @@ declare(strict_types=1); namespace phpOMS\Math\Stochastic\Distribution; use phpOMS\Math\Functions\Functions; +use phpOMS\Math\Functions\Gamma; /** * Well known functions class. @@ -40,7 +41,7 @@ class PoissonDistribution */ public static function getPmf(int $k, float $lambda) : float { - return exp($k * log($lambda) - $lambda - log(Functions::getGammaInteger($k + 1))); + return exp($k * log($lambda) - $lambda - log(Gamma::getGammaInteger($k + 1))); } /** diff --git a/Message/Http/Header.php b/Message/Http/Header.php index 8851c23e1..84a5d3a7e 100644 --- a/Message/Http/Header.php +++ b/Message/Http/Header.php @@ -150,7 +150,7 @@ final class Header extends HeaderAbstract $headers = []; foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_') { - $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; + $headers[\str_replace(' ', '-', ucwords(strtolower(\str_replace('_', ' ', substr($name, 5)))))] = $value; } } diff --git a/Message/Http/Request.php b/Message/Http/Request.php index 693eb4c1a..df55e2ea7 100644 --- a/Message/Http/Request.php +++ b/Message/Http/Request.php @@ -126,7 +126,7 @@ final class Request extends RequestAbstract if (isset($_SERVER['CONTENT_TYPE'])) { if (strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) { - if (($json = json_decode(($input = file_get_contents('php://input')), true)) === false || $json === null) { + if (($json = \json_decode(($input = \file_get_contents('php://input')), true)) === false || $json === null) { throw new \Exception('Is not valid json ' . $input); } @@ -153,8 +153,8 @@ final class Request extends RequestAbstract return 'EN'; } - $lang = explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']); - $lang = explode('-', $lang[0]); + $lang = \explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']); + $lang = \explode('-', $lang[0]); return $lang[0]; } @@ -252,7 +252,7 @@ final class Request extends RequestAbstract // TODO: maybe replace this with smart media queries... checked gets handled in reverse!!! $useragent = $_SERVER['HTTP_USER_AGENT'] ?? ''; - if (preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i', $useragent) || preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', $useragent)) { + if (\preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i', $useragent) || \preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i', $useragent)) { return true; } @@ -388,7 +388,7 @@ final class Request extends RequestAbstract */ public function getBody() : string { - return file_get_contents('php://input'); + return \file_get_contents('php://input'); } /** diff --git a/Message/Http/Response.php b/Message/Http/Response.php index 91bfe56b7..55458efb7 100644 --- a/Message/Http/Response.php +++ b/Message/Http/Response.php @@ -106,7 +106,7 @@ final class Response extends ResponseAbstract implements RenderableInterface foreach ($types as $type) { if (stripos($type, MimeType::M_JSON) !== false) { - return json_encode($this->jsonSerialize()); + return \json_encode($this->jsonSerialize()); } } @@ -132,7 +132,7 @@ final class Response extends ResponseAbstract implements RenderableInterface } elseif (is_string($response) || is_numeric($response)) { $render .= $response; } elseif (is_array($response)) { - $render .= json_encode($response); + $render .= \json_encode($response); // TODO: remove this. This should never happen since then someone forgot to set the correct header. it should be json header! } else { throw new \Exception('Wrong response type'); diff --git a/Model/Html/Meta.php b/Model/Html/Meta.php index 4f7fbcd75..10ec2d500 100644 --- a/Model/Html/Meta.php +++ b/Model/Html/Meta.php @@ -71,7 +71,7 @@ class Meta implements RenderableInterface */ public function addKeyword(string $keyword) : void { - if (!in_array($keyword, $this->keywords)) { + if (!\in_array($keyword, $this->keywords)) { $this->keywords[] = $keyword; } } diff --git a/Module/InfoManager.php b/Module/InfoManager.php index 35c8ecc69..1518f2cb2 100644 --- a/Module/InfoManager.php +++ b/Module/InfoManager.php @@ -81,11 +81,11 @@ final class InfoManager */ public function load() : void { - if (!file_exists($this->path)) { + if (!\file_exists($this->path)) { throw new PathException($this->path); } - $this->info = json_decode(file_get_contents($this->path), true); + $this->info = \json_decode(file_get_contents($this->path), true); } /** @@ -97,11 +97,11 @@ final class InfoManager */ public function update() : void { - if (!file_exists($this->path)) { + if (!\file_exists($this->path)) { throw new PathException($this->path); } - file_put_contents($this->path, json_encode($this->info, JSON_PRETTY_PRINT)); + \file_put_contents($this->path, \json_encode($this->info, JSON_PRETTY_PRINT)); } /** diff --git a/Module/InstallerAbstract.php b/Module/InstallerAbstract.php index fe3ceb7ff..4a347780e 100644 --- a/Module/InstallerAbstract.php +++ b/Module/InstallerAbstract.php @@ -68,7 +68,7 @@ class InstallerAbstract $load = $info->getLoad(); foreach ($load as $val) { foreach ($val['pid'] as $pid) { - $sth->bindValue(':pid', sha1(str_replace('/', '', $pid)), \PDO::PARAM_STR); + $sth->bindValue(':pid', sha1(\str_replace('/', '', $pid)), \PDO::PARAM_STR); $sth->bindValue(':type', $val['type'], \PDO::PARAM_INT); $sth->bindValue(':from', $val['from'], \PDO::PARAM_STR); $sth->bindValue(':for', $val['for'], \PDO::PARAM_STR); @@ -148,7 +148,7 @@ class InstallerAbstract */ private static function initRoutes(InfoManager $info) : void { - $directories = new Directory(dirname($info->getPath()) . '/Admin/Routes'); + $directories = new Directory(\dirname($info->getPath()) . '/Admin/Routes'); foreach ($directories as $key => $subdir) { if ($subdir instanceof Directory) { @@ -173,15 +173,15 @@ class InstallerAbstract */ private static function installRoutes(string $destRoutePath, string $srcRoutePath) : void { - if (!file_exists($destRoutePath)) { - file_put_contents($destRoutePath, 'getPath()) . '/Admin/Hooks'); + $directories = new Directory(\dirname($info->getPath()) . '/Admin/Hooks'); foreach ($directories as $key => $subdir) { if ($subdir instanceof Directory) { @@ -237,15 +237,15 @@ class InstallerAbstract */ private static function installHooks(string $destHookPath, string $srcHookPath) : void { - if (!file_exists($destHookPath)) { - file_put_contents($destHookPath, 'getActiveModules(false)); + return \in_array($module, $this->getActiveModules(false)); } /** @@ -241,12 +241,12 @@ final class ModuleManager for ($i = 0; $i < $c; ++$i) { $path = $this->modulePath . '/' . $files[$i] . '/info.json'; - if (!file_exists($path)) { + if (!\file_exists($path)) { continue; // throw new PathException($path); } - $json = json_decode(file_get_contents($path), true); + $json = \json_decode(file_get_contents($path), true); $this->all[$json['name']['internal']] = $json; } } @@ -472,7 +472,7 @@ final class ModuleManager return false; } - if (!file_exists($this->modulePath . '/' . $module . '/Admin/Installer.php')) { + if (!\file_exists($this->modulePath . '/' . $module . '/Admin/Installer.php')) { // todo download; return false; } diff --git a/Module/PackageManager.php b/Module/PackageManager.php index 039149644..b336ec7b6 100644 --- a/Module/PackageManager.php +++ b/Module/PackageManager.php @@ -105,11 +105,11 @@ final class PackageManager */ public function load() : void { - if (!file_exists($this->extractPath)) { + if (!\file_exists($this->extractPath)) { throw new PathException($this->extractPath); } - $this->info = json_decode(file_get_contents($this->extractPath . '/info.json'), true); + $this->info = \json_decode(file_get_contents($this->extractPath . '/info.json'), true); } /** @@ -141,7 +141,7 @@ final class PackageManager continue; } - \sodium_crypto_generichash_update($state, file_get_contents($this->extractPath . '/package/' . $file)); + \sodium_crypto_generichash_update($state, \file_get_contents($this->extractPath . '/package/' . $file)); } return \sodium_crypto_generichash_final(); diff --git a/Router/Router.php b/Router/Router.php index f1afc3111..5e58ec9bb 100644 --- a/Router/Router.php +++ b/Router/Router.php @@ -137,6 +137,6 @@ final class Router */ private function match(string $route, int $routeVerb, string $uri, int $remoteVerb = RouteVerb::GET) : bool { - return (bool) preg_match('~^' . $route . '$~', $uri) && ($routeVerb === RouteVerb::ANY || $remoteVerb === RouteVerb::ANY || ($remoteVerb & $routeVerb) === $remoteVerb); + return (bool) \preg_match('~^' . $route . '$~', $uri) && ($routeVerb === RouteVerb::ANY || $remoteVerb === RouteVerb::ANY || ($remoteVerb & $routeVerb) === $remoteVerb); } } diff --git a/Security/PhpCode.php b/Security/PhpCode.php index 5b1fa21bf..716246bd9 100644 --- a/Security/PhpCode.php +++ b/Security/PhpCode.php @@ -76,7 +76,7 @@ final class PhpCode */ public static function normalizeSource(string $source) : string { - return str_replace(["\n", "\r\n", "\r", "\t"], ['', '', '', ' '], $source); + return \str_replace(["\n", "\r\n", "\r", "\t"], ['', '', '', ' '], $source); } /** @@ -90,7 +90,7 @@ final class PhpCode */ public static function hasUnicode(string $source) : bool { - return (bool) preg_match('/[^\x00-\x7f]/', $source); + return (bool) \preg_match('/[^\x00-\x7f]/', $source); } /** @@ -105,11 +105,11 @@ final class PhpCode public static function isDisabled(array $functions) : bool { $disabled = ini_get('disable_functions'); - $disabled = str_replace(' ', '', $disabled); - $disabled = explode(',', $disabled); + $disabled = \str_replace(' ', '', $disabled); + $disabled = \explode(',', $disabled); foreach ($functions as $function) { - if (!in_array($function, $disabled)) { + if (!\in_array($function, $disabled)) { return false; } } @@ -129,7 +129,7 @@ final class PhpCode public static function hasDeprecatedFunction(string $source) : bool { foreach (self::$deprecatedFunctions as $function) { - if (preg_match('/' . $function . '\s*\(/', $source) === 1) { + if (\preg_match('/' . $function . '\s*\(/', $source) === 1) { return true; } } diff --git a/Socket/Client/Client.php b/Socket/Client/Client.php index fbc22db50..69ba36cc5 100644 --- a/Socket/Client/Client.php +++ b/Socket/Client/Client.php @@ -98,7 +98,7 @@ class Client extends SocketAbstract $data = trim($data); if (!empty($data)) { - $data = explode(' ', $data); + $data = \explode(' ', $data); $this->commands->trigger($data[0], 0, $data); } } diff --git a/Socket/Server/Server.php b/Socket/Server/Server.php index 6fc999619..74bc4bfca 100644 --- a/Socket/Server/Server.php +++ b/Socket/Server/Server.php @@ -130,27 +130,27 @@ class Server extends SocketAbstract // todo: different handshake for normal tcp connection return true; - if (preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $headers, $match)) { + if (\preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $headers, $match)) { $version = $match[1]; } else { return false; } if ($version == 13) { - if (preg_match("/GET (.*) HTTP/", $headers, $match)) { + if (\preg_match("/GET (.*) HTTP/", $headers, $match)) { $root = $match[1]; } - if (preg_match("/Host: (.*)\r\n/", $headers, $match)) { + if (\preg_match("/Host: (.*)\r\n/", $headers, $match)) { $host = $match[1]; } - if (preg_match("/Origin: (.*)\r\n/", $headers, $match)) { + if (\preg_match("/Origin: (.*)\r\n/", $headers, $match)) { $origin = $match[1]; } $key = ''; - if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match)) { + if (\preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match)) { $key = $match[1]; } diff --git a/Stdlib/Base/Enum.php b/Stdlib/Base/Enum.php index 9276a8559..71e877623 100644 --- a/Stdlib/Base/Enum.php +++ b/Stdlib/Base/Enum.php @@ -42,7 +42,7 @@ abstract class Enum { $constants = self::getConstants(); - return in_array($value, $constants, true); + return \in_array($value, $constants, true); } /** diff --git a/Stdlib/Base/EnumArray.php b/Stdlib/Base/EnumArray.php index 65db79838..30f7c04af 100644 --- a/Stdlib/Base/EnumArray.php +++ b/Stdlib/Base/EnumArray.php @@ -73,7 +73,7 @@ abstract class EnumArray { $constants = self::getConstants(); - return in_array($value, $constants, true); + return \in_array($value, $constants, true); } /** diff --git a/Stdlib/Base/Iban.php b/Stdlib/Base/Iban.php index c48b0f767..44d68beb5 100644 --- a/Stdlib/Base/Iban.php +++ b/Stdlib/Base/Iban.php @@ -75,7 +75,7 @@ class Iban implements \Serializable */ public static function normalize(string $iban) : string { - return strtoupper(str_replace(' ', '', $iban)); + return strtoupper(\str_replace(' ', '', $iban)); } /** @@ -114,9 +114,9 @@ class Iban implements \Serializable private function getSequence(string $sequence) : string { $country = $this->getCountry(); - $layout = str_replace(' ', '', IbanEnum::getByName('C_' . $country)); + $layout = \str_replace(' ', '', IbanEnum::getByName('C_' . $country)); - $start = stripos($layout, $sequence); + $start = \stripos($layout, $sequence); $end = strrpos($layout, $sequence); if ($start === false) { diff --git a/Stdlib/Base/Location.php b/Stdlib/Base/Location.php index 8ea4b4a29..f30934767 100644 --- a/Stdlib/Base/Location.php +++ b/Stdlib/Base/Location.php @@ -297,7 +297,7 @@ class Location implements \JsonSerializable, \Serializable */ public function serialize() : string { - return json_encode($this->jsonSerialize()); + return \json_encode($this->jsonSerialize()); } /** diff --git a/Stdlib/Base/SmartDateTime.php b/Stdlib/Base/SmartDateTime.php index ccbebda5c..12acb3f2e 100644 --- a/Stdlib/Base/SmartDateTime.php +++ b/Stdlib/Base/SmartDateTime.php @@ -240,7 +240,7 @@ class SmartDateTime extends \DateTime * * @param int $weekStartsWith Day of the week start (0 = Sunday) * - * @return array + * @return \DateTime[] * * @since 1.0.0 */ diff --git a/Stdlib/Map/MultiMap.php b/Stdlib/Map/MultiMap.php index 3a68b58b3..470604544 100644 --- a/Stdlib/Map/MultiMap.php +++ b/Stdlib/Map/MultiMap.php @@ -130,7 +130,7 @@ class MultiMap implements \Countable /* garbage collect values */ foreach ($this->values as $valueKey => $value) { - if (!in_array($valueKey, $this->keys)) { + if (!\in_array($valueKey, $this->keys)) { unset($this->values[$valueKey]); } } diff --git a/Stdlib/Queue/PriorityQueue.php b/Stdlib/Queue/PriorityQueue.php index 6d95f6a8d..96029929f 100644 --- a/Stdlib/Queue/PriorityQueue.php +++ b/Stdlib/Queue/PriorityQueue.php @@ -184,7 +184,7 @@ class PriorityQueue implements \Countable, \Serializable */ public function serialize() : string { - return json_encode($this->queue); + return \json_encode($this->queue); } /** @@ -198,7 +198,7 @@ class PriorityQueue implements \Countable, \Serializable */ public function unserialize($data) { - $this->queue = json_decode($data); + $this->queue = \json_decode($data); $this->count = count($this->queue); } } diff --git a/System/File/FileUtils.php b/System/File/FileUtils.php index cf144848d..c61690791 100644 --- a/System/File/FileUtils.php +++ b/System/File/FileUtils.php @@ -58,23 +58,23 @@ final class FileUtils { $extension = strtolower($extension); - if (in_array($extension, self::CODE_EXTENSION)) { + if (\in_array($extension, self::CODE_EXTENSION)) { return ExtensionType::CODE; - } elseif (in_array($extension, self::TEXT_EXTENSION)) { + } elseif (\in_array($extension, self::TEXT_EXTENSION)) { return ExtensionType::TEXT; - } elseif (in_array($extension, self::PRESENTATION_EXTENSION)) { + } elseif (\in_array($extension, self::PRESENTATION_EXTENSION)) { return ExtensionType::PRESENTATION; - } elseif (in_array($extension, self::PDF_EXTENSION)) { + } elseif (\in_array($extension, self::PDF_EXTENSION)) { return ExtensionType::PDF; - } elseif (in_array($extension, self::ARCHIVE_EXTENSION)) { + } elseif (\in_array($extension, self::ARCHIVE_EXTENSION)) { return ExtensionType::ARCHIVE; - } elseif (in_array($extension, self::AUDIO_EXTENSION)) { + } elseif (\in_array($extension, self::AUDIO_EXTENSION)) { return ExtensionType::AUDIO; - } elseif (in_array($extension, self::VIDEO_EXTENSION)) { + } elseif (\in_array($extension, self::VIDEO_EXTENSION)) { return ExtensionType::VIDEO; - } elseif (in_array($extension, self::IMAGE_EXTENSION)) { + } elseif (\in_array($extension, self::IMAGE_EXTENSION)) { return ExtensionType::IMAGE; - } elseif (in_array($extension, self::SPREADSHEET_EXTENSION)) { + } elseif (\in_array($extension, self::SPREADSHEET_EXTENSION)) { return ExtensionType::SPREADSHEET; } @@ -92,11 +92,11 @@ final class FileUtils */ public static function absolute(string $origPath) : string { - if (!file_exists($origPath)) { + if (!\file_exists($origPath)) { $startsWithSlash = strpos($origPath, '/') === 0 ? '/' : ''; $path = []; - $parts = explode('/', $origPath); + $parts = \explode('/', $origPath); foreach ($parts as $part) { if (empty($part) || $part === '.') { diff --git a/System/File/Ftp/Directory.php b/System/File/Ftp/Directory.php index 593df739b..3407f244c 100644 --- a/System/File/Ftp/Directory.php +++ b/System/File/Ftp/Directory.php @@ -48,17 +48,17 @@ class Directory extends FileAbstract implements DirectoryInterface { $list = ftp_nlist($con, LocalFile::parent($path)); - return in_array(LocalFile::name($path), $list); + return \in_array(LocalFile::name($path), $list); } public static function ftpCreate($con, string $path, int $permission, bool $recursive) { - $parts = explode('/', $path); + $parts = \explode('/', $path); ftp_chdir($con, '/' . $parts[0]); foreach ($parts as $part) { if (self::ftpExists($con, $part)) { - ftp_mkdir($con, $part); + ftp_\mkdir($con, $part); ftp_chdir($con, $part); ftp_chmod($con, $permission, $part); } diff --git a/System/File/Ftp/File.php b/System/File/Ftp/File.php index 261d8c038..3acc14a7b 100644 --- a/System/File/Ftp/File.php +++ b/System/File/Ftp/File.php @@ -62,19 +62,19 @@ class File extends FileAbstract implements FileInterface public static function ftpConnect(Http $http) { - $con = ftp_connect($http->getBase() . $http->getPath(), $http->getPort()); + $con = \ftp_connect($http->getBase() . $http->getPath(), $http->getPort()); - ftp_login($con, $http->getUser(), $http->getPass()); - ftp_chdir($con, $http->getPath()); // todo: is this required ? + \ftp_login($con, $http->getUser(), $http->getPass()); + \ftp_chdir($con, $http->getPath()); // todo: is this required ? return $con; } public static function ftpExists($con, string $path) { - $list = ftp_nlist($con, LocalFile::dirpath($path)); + $list = \ftp_nlist($con, LocalFile::dirpath($path)); - return in_array(LocalFile::basename($path), $list); + return \in_array(LocalFile::basename($path), $list); } /** @@ -85,7 +85,7 @@ class File extends FileAbstract implements FileInterface $http = new Http($path); $con = self::ftpConnect($http); - if (ftp_pwd($con) !== $http->getPath()) { + if (\ftp_pwd($con) !== $http->getPath()) { return false; } @@ -97,23 +97,23 @@ class File extends FileAbstract implements FileInterface || (!$exists && ContentPutMode::hasFlag($mode, ContentPutMode::CREATE)) ) { if (ContentPutMode::hasFlag($mode, ContentPutMode::APPEND) && $exists) { - file_put_contents($path, file_get_contents($path) . $content, 0, stream_context_create(['ftp' => ['overwrite' => true]])); + \file_put_contents($path, \file_get_contents($path) . $content, 0, \stream_context_create(['ftp' => ['overwrite' => true]])); } elseif (ContentPutMode::hasFlag($mode, ContentPutMode::PREPEND) && $exists) { - file_put_contents($path, $content . file_get_contents($path), 0, stream_context_create(['ftp' => ['overwrite' => true]])); + \file_put_contents($path, $content . \file_get_contents($path), 0, \stream_context_create(['ftp' => ['overwrite' => true]])); } else { - if (!Directory::ftpExists($con, dirname($path))) { - Directory::ftpCreate($con, dirname($path), 0755, true); + if (!Directory::ftpExists($con, \dirname($path))) { + Directory::ftpCreate($con, \dirname($path), 0755, true); } - file_put_contents($path, $content, 0, stream_context_create(['ftp' => ['overwrite' => true]])); + \file_put_contents($path, $content, 0, \stream_context_create(['ftp' => ['overwrite' => true]])); } - ftp_close($con); + \ftp_close($con); return true; } - ftp_close($con); + \ftp_close($con); return false; } @@ -123,17 +123,17 @@ class File extends FileAbstract implements FileInterface */ public static function get(string $path) : string { - $temp = fopen('php://temp', 'r+'); + $temp = \fopen('php://temp', 'r+'); $http = new Http($path); $content = ''; $con = self::ftpConnect($http); - if (ftp_chdir($con, File::dirpath($path)) && ftp_fget($con, $temp, $path, FTP_BINARY, 0)) { - rewind($temp); - $content = stream_get_contents($temp); + if (\ftp_chdir($con, File::dirpath($path)) && \ftp_fget($con, $temp, $path, FTP_BINARY, 0)) { + \rewind($temp); + $content = \stream_get_contents($temp); } - fclose($temp); + \fclose($temp); return $content; } @@ -211,7 +211,7 @@ class File extends FileAbstract implements FileInterface $changed->setTimestamp(ftp_mdtm($con, $http->getPath())); - fclose($con); + \fclose($con); return $changed; } @@ -228,9 +228,9 @@ class File extends FileAbstract implements FileInterface throw new PathException($path); } - $size = ftp_size($con, $http->getPath()); + $size = \ftp_size($con, $http->getPath()); - fclose($con); + \fclose($con); return $size; } @@ -244,7 +244,7 @@ class File extends FileAbstract implements FileInterface $con = self::ftpConnect($http); $owner = self::parseFtpFileData($con, $path)['user'] ?? ''; - fclose($con); + \fclose($con); return (int) $owner; } @@ -258,7 +258,7 @@ class File extends FileAbstract implements FileInterface $con = self::ftpConnect($http); $permission = (int) self::parseFtpFileData($con, $path)['permission'] ?? 0; - fclose($con); + \fclose($con); return $permission; } @@ -267,10 +267,10 @@ class File extends FileAbstract implements FileInterface { $items = []; - if (is_array($files = ftp_rawlist($con, LocalFile::dirpath($path)))) { + if (\is_array($files = \ftp_rawlist($con, LocalFile::dirpath($path)))) { foreach ($files as $fileData) { - if (strpos($fileData, self::name($path)) !== false) { - $chunks = preg_split("/\s+/", $fileData); + if (\strpos($fileData, self::name($path)) !== false) { + $chunks = \preg_split("/\s+/", $fileData); $items['permission'] = $chunks[0]; $items['user'] = $chunks[2]; @@ -342,17 +342,17 @@ class File extends FileAbstract implements FileInterface } if ($overwrite || !self::exists($to)) { - if (!Directory::exists(dirname($to))) { - Directory::create(dirname($to), 0755, true); + if (!Directory::exists(\dirname($to))) { + Directory::create(\dirname($to), 0755, true); } - $rename = ftp_rename($con, $from, $to); - fclose($con); + $rename = \ftp_rename($con, $from, $to); + \fclose($con); return $rename; } - fclose($con); + \fclose($con); return false; } @@ -369,8 +369,8 @@ class File extends FileAbstract implements FileInterface return false; } - ftp_delete($con, $path); - fclose($con); + \ftp_delete($con, $path); + \fclose($con); return true; } diff --git a/System/File/Ftp/FtpStorage.php b/System/File/Ftp/FtpStorage.php index 6af890e31..428b9a132 100644 --- a/System/File/Ftp/FtpStorage.php +++ b/System/File/Ftp/FtpStorage.php @@ -48,7 +48,7 @@ class FtpStorage extends StorageAbstract protected static function getClassType(string $path) : string { - return is_dir($path) || (!is_file($path) && stripos($path, '.') === false) ? Directory::class : File::class; + return \is_dir($path) || (!is_file($path) && \stripos($path, '.') === false) ? Directory::class : File::class; } /** @@ -80,7 +80,7 @@ class FtpStorage extends StorageAbstract */ public static function create(string $path) : bool { - return stripos($path, '.') === false ? Directory::create($path, 0755, true) : File::create($path); + return \stripos($path, '.') === false ? Directory::create($path, 0755, true) : File::create($path); } /** diff --git a/System/File/Local/Directory.php b/System/File/Local/Directory.php index 4d8cbaa35..86e01c01f 100644 --- a/System/File/Local/Directory.php +++ b/System/File/Local/Directory.php @@ -57,7 +57,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public function __construct(string $path, string $filter = '*') { - $this->filter = ltrim($filter, '\\/'); + $this->filter = \ltrim($filter, '\\/'); parent::__construct($path); if (file_exists($this->path)) { @@ -71,18 +71,18 @@ final class Directory extends FileAbstract implements DirectoryInterface * @param string $path Path * @param string $filter Filter * - * @return array + * @return string[] * * @since 1.0.0 */ public static function list(string $path, string $filter = '*') : array { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } $list = []; - $path = rtrim($path, '\\/'); + $path = \rtrim($path, '\\/'); $iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST); @@ -92,7 +92,7 @@ final class Directory extends FileAbstract implements DirectoryInterface } foreach ($iterator as $item) { - $list[] = str_replace('\\', '/', $iterator->getSubPathname()); + $list[] = \str_replace('\\', '/', $iterator->getSubPathname()); } return $list; @@ -105,23 +105,23 @@ final class Directory extends FileAbstract implements DirectoryInterface * @param string $extension Extension * @param string $exclude Pattern to exclude * - * @return array + * @return string[] * * @since 1.0.0 */ public static function listByExtension(string $path, string $extension = '', string $exclude = '') : array { $list = []; - $path = rtrim($path, '\\/'); + $path = \rtrim($path, '\\/'); foreach ($iterator = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST) as $item ) { if ((empty($extension) || $item->getExtension() === $extension) - && (empty($exclude) || (!(bool) preg_match('/' . $exclude . '/', $iterator->getSubPathname()))) + && (empty($exclude) || (!(bool) \preg_match('/' . $exclude . '/', $iterator->getSubPathname()))) ) { - $list[] = str_replace('\\', '/', $iterator->getSubPathname()); + $list[] = \str_replace('\\', '/', $iterator->getSubPathname()); } } @@ -135,9 +135,9 @@ final class Directory extends FileAbstract implements DirectoryInterface { parent::index(); - foreach (glob($this->path . DIRECTORY_SEPARATOR . $this->filter) as $filename) { + foreach (\glob($this->path . DIRECTORY_SEPARATOR . $this->filter) as $filename) { if (!StringUtils::endsWith(trim($filename), '.')) { - $file = is_dir($filename) ? new self($filename) : new File($filename); + $file = \is_dir($filename) ? new self($filename) : new File($filename); $this->addNode($file); } @@ -161,12 +161,12 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function size(string $dir, bool $recursive = true) : int { - if (!file_exists($dir) || !is_readable($dir)) { + if (!\file_exists($dir) || !\is_readable($dir)) { throw new PathException($dir); } $countSize = 0; - $directories = scandir($dir); + $directories = \scandir($dir); foreach ($directories as $key => $filename) { if ($filename === ".." || $filename === ".") { @@ -174,10 +174,10 @@ final class Directory extends FileAbstract implements DirectoryInterface } $path = $dir . "/" . $filename; - if (is_dir($path) && $recursive) { + if (\is_dir($path) && $recursive) { $countSize += self::size($path, $recursive); - } elseif (is_file($path)) { - $countSize += filesize($path); + } elseif (\is_file($path)) { + $countSize += \filesize($path); } } @@ -189,22 +189,22 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function count(string $path, bool $recursive = true, array $ignore = []) : int { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } $size = 0; - $files = scandir($path); + $files = \scandir($path); $ignore[] = '.'; $ignore[] = '..'; foreach ($files as $t) { - if (in_array($t, $ignore)) { + if (\in_array($t, $ignore)) { continue; } - if (is_dir(rtrim($path, '/') . '/' . $t)) { + if (\is_dir(\rtrim($path, '/') . '/' . $t)) { if ($recursive) { - $size += self::count(rtrim($path, '/') . '/' . $t, true, $ignore); + $size += self::count(\rtrim($path, '/') . '/' . $t, true, $ignore); } } else { $size++; @@ -219,21 +219,21 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function delete(string $path) : bool { - $files = scandir($path); + $files = \scandir($path); /* Removing . and .. */ unset($files[1]); unset($files[0]); foreach ($files as $file) { - if (is_dir($path . '/' . $file)) { + if (\is_dir($path . '/' . $file)) { self::delete($path . '/' . $file); } else { - unlink($path . '/' . $file); + \unlink($path . '/' . $file); } } - rmdir($path); + \rmdir($path); return true; } @@ -243,10 +243,10 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function parent(string $path) : string { - $path = explode('/', str_replace('\\', '/', $path)); - array_pop($path); + $path = \explode('/', \str_replace('\\', '/', $path)); + \array_pop($path); - return implode('/', $path); + return \implode('/', $path); } /** @@ -255,12 +255,12 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function created(string $path) : \DateTime { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } $created = new \DateTime('now'); - $created->setTimestamp(filemtime($path)); + $created->setTimestamp(\filemtime($path)); return $created; } @@ -270,12 +270,12 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function changed(string $path) : \DateTime { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } $changed = new \DateTime(); - $changed->setTimestamp(filectime($path)); + $changed->setTimestamp(\filectime($path)); return $changed; } @@ -285,11 +285,11 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function owner(string $path) : int { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } - return fileowner($path); + return \fileowner($path); } /** @@ -297,11 +297,11 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function permission(string $path) : int { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } - return fileperms($path); + return \fileperms($path); } /** @@ -313,9 +313,9 @@ final class Directory extends FileAbstract implements DirectoryInterface throw new PathException($from); } - if (!file_exists($to)) { + if (!\file_exists($to)) { self::create($to, 0755, true); - } elseif ($overwrite && file_exists($to)) { + } elseif ($overwrite && \file_exists($to)) { self::delete($to); } else { return false; @@ -326,9 +326,9 @@ final class Directory extends FileAbstract implements DirectoryInterface \RecursiveIteratorIterator::SELF_FIRST) as $item ) { if ($item->isDir()) { - mkdir($to . '/' . $iterator->getSubPathname()); + \mkdir($to . '/' . $iterator->getSubPathname()); } else { - copy($from . '/' . $iterator->getSubPathname(), $to . '/' . $iterator->getSubPathname()); + \copy($from . '/' . $iterator->getSubPathname(), $to . '/' . $iterator->getSubPathname()); } } @@ -344,9 +344,9 @@ final class Directory extends FileAbstract implements DirectoryInterface throw new PathException($from); } - if (!$overwrite && file_exists($to)) { + if (!$overwrite && \file_exists($to)) { return false; - } elseif ($overwrite && file_exists($to)) { + } elseif ($overwrite && \file_exists($to)) { self::delete($to); } @@ -354,7 +354,7 @@ final class Directory extends FileAbstract implements DirectoryInterface self::create(self::parent($to), 0755, true); } - rename($from, $to); + \rename($from, $to); return true; } @@ -364,7 +364,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function exists(string $path) : bool { - return file_exists($path); + return \file_exists($path); } /** @@ -372,7 +372,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function sanitize(string $path, string $replace = '') : string { - return preg_replace('[^\w\s\d\.\-_~,;:\[\]\(\]\/]', $replace, $path); + return \preg_replace('[^\w\s\d\.\-_~,;:\[\]\(\]\/]', $replace, $path); } /** @@ -398,12 +398,12 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function create(string $path, int $permission = 0755, bool $recursive = false) : bool { - if (!file_exists($path)) { - if (!$recursive && !file_exists(self::parent($path))) { + if (!\file_exists($path)) { + if (!$recursive && !\file_exists(self::parent($path))) { return false; } - mkdir($path, $permission, $recursive); + \mkdir($path, $permission, $recursive); return true; } @@ -435,7 +435,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public function rewind() { - reset($this->nodes); + \reset($this->nodes); } /** @@ -443,7 +443,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public function current() { - return current($this->nodes); + return \current($this->nodes); } /** @@ -451,7 +451,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public function key() { - return key($this->nodes); + return \key($this->nodes); } /** @@ -459,7 +459,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public function next() { - return next($this->nodes); + return \next($this->nodes); } /** @@ -467,7 +467,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public function valid() { - $key = key($this->nodes); + $key = \key($this->nodes); return ($key !== null && $key !== false); } @@ -507,7 +507,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function name(string $path) : string { - return basename($path); + return \basename($path); } /** @@ -515,7 +515,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function dirname(string $path) : string { - return basename($path); + return \basename($path); } /** @@ -531,7 +531,7 @@ final class Directory extends FileAbstract implements DirectoryInterface */ public static function basename(string $path) : string { - return basename($path); + return \basename($path); } /** diff --git a/System/File/Local/File.php b/System/File/Local/File.php index 7abd73c8c..d1965feea 100644 --- a/System/File/Local/File.php +++ b/System/File/Local/File.php @@ -44,7 +44,7 @@ final class File extends FileAbstract implements FileInterface parent::__construct($path); $this->count = 1; - if (file_exists($this->path)) { + if (\file_exists($this->path)) { $this->index(); } } @@ -56,7 +56,7 @@ final class File extends FileAbstract implements FileInterface { parent::index(); - $this->size = filesize($this->path); + $this->size = \filesize($this->path); } /** @@ -64,7 +64,7 @@ final class File extends FileAbstract implements FileInterface */ public static function put(string $path, string $content, int $mode = ContentPutMode::REPLACE | ContentPutMode::CREATE) : bool { - $exists = file_exists($path); + $exists = \file_exists($path); if ((ContentPutMode::hasFlag($mode, ContentPutMode::APPEND) && $exists) || (ContentPutMode::hasFlag($mode, ContentPutMode::PREPEND) && $exists) @@ -72,15 +72,15 @@ final class File extends FileAbstract implements FileInterface || (!$exists && ContentPutMode::hasFlag($mode, ContentPutMode::CREATE)) ) { if (ContentPutMode::hasFlag($mode, ContentPutMode::APPEND) && $exists) { - file_put_contents($path, file_get_contents($path) . $content); + \file_put_contents($path, \file_get_contents($path) . $content); } elseif (ContentPutMode::hasFlag($mode, ContentPutMode::PREPEND) && $exists) { - file_put_contents($path, $content . file_get_contents($path)); + \file_put_contents($path, $content . \file_get_contents($path)); } else { - if (!Directory::exists(dirname($path))) { - Directory::create(dirname($path), 0755, true); + if (!Directory::exists(\dirname($path))) { + Directory::create(\dirname($path), 0755, true); } - file_put_contents($path, $content); + \file_put_contents($path, $content); } return true; @@ -94,11 +94,11 @@ final class File extends FileAbstract implements FileInterface */ public static function get(string $path) : string { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } - return file_get_contents($path); + return \file_get_contents($path); } /** @@ -138,7 +138,7 @@ final class File extends FileAbstract implements FileInterface */ public static function exists(string $path) : bool { - return file_exists($path); + return \file_exists($path); } /** @@ -146,7 +146,7 @@ final class File extends FileAbstract implements FileInterface */ public static function parent(string $path) : string { - return Directory::parent(dirname($path)); + return Directory::parent(\dirname($path)); } /** @@ -154,7 +154,7 @@ final class File extends FileAbstract implements FileInterface */ public static function sanitize(string $path, string $replace = '') : string { - return preg_replace('/[^\w\s\d\.\-_~,;\/\[\]\(\]]/', $replace, $path); + return \preg_replace('/[^\w\s\d\.\-_~,;\/\[\]\(\]]/', $replace, $path); } /** @@ -162,11 +162,11 @@ final class File extends FileAbstract implements FileInterface */ public static function created(string $path) : \DateTime { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } - return self::createFileTime(filemtime($path)); + return self::createFileTime(\filemtime($path)); } /** @@ -174,11 +174,11 @@ final class File extends FileAbstract implements FileInterface */ public static function changed(string $path) : \DateTime { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } - return self::createFileTime(filemtime($path)); + return self::createFileTime(\filemtime($path)); } /** @@ -203,7 +203,7 @@ final class File extends FileAbstract implements FileInterface */ public static function size(string $path, bool $recursive = true) : int { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } @@ -215,11 +215,11 @@ final class File extends FileAbstract implements FileInterface */ public static function owner(string $path) : int { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } - return fileowner($path); + return \fileowner($path); } /** @@ -227,11 +227,11 @@ final class File extends FileAbstract implements FileInterface */ public static function permission(string $path) : int { - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } - return fileperms($path); + return \fileperms($path); } /** @@ -245,7 +245,7 @@ final class File extends FileAbstract implements FileInterface */ public static function dirname(string $path) : string { - return basename(dirname($path)); + return basename(\dirname($path)); } /** @@ -271,12 +271,12 @@ final class File extends FileAbstract implements FileInterface throw new PathException($from); } - if ($overwrite || !file_exists($to)) { - if (!Directory::exists(dirname($to))) { - Directory::create(dirname($to), 0755, true); + if ($overwrite || !\file_exists($to)) { + if (!Directory::exists(\dirname($to))) { + Directory::create(\dirname($to), 0755, true); } - if ($overwrite && file_exists($to)) { + if ($overwrite && \file_exists($to)) { unlink($to); } @@ -307,7 +307,7 @@ final class File extends FileAbstract implements FileInterface */ public static function delete(string $path) : bool { - if (!file_exists($path)) { + if (!\file_exists($path)) { return false; } @@ -325,7 +325,7 @@ final class File extends FileAbstract implements FileInterface */ public function getDirName() : string { - return basename(dirname($this->path)); + return basename(\dirname($this->path)); } /** @@ -353,16 +353,16 @@ final class File extends FileAbstract implements FileInterface */ public static function create(string $path) : bool { - if (!file_exists($path)) { - if (!Directory::exists(dirname($path))) { - Directory::create(dirname($path), 0755, true); + if (!\file_exists($path)) { + if (!Directory::exists(\dirname($path))) { + Directory::create(\dirname($path), 0755, true); } - if (!is_writable(dirname($path))) { + if (!is_writable(\dirname($path))) { return false; } - touch($path); + \touch($path); return true; } @@ -375,7 +375,7 @@ final class File extends FileAbstract implements FileInterface */ public function getContent() : string { - return file_get_contents($this->path); + return \file_get_contents($this->path); } /** @@ -407,7 +407,7 @@ final class File extends FileAbstract implements FileInterface */ public function getName() : string { - return explode('.', $this->name)[0]; + return \explode('.', $this->name)[0]; } /** @@ -415,7 +415,7 @@ final class File extends FileAbstract implements FileInterface */ public function getExtension() : string { - $extension = explode('.', $this->name); + $extension = \explode('.', $this->name); return $extension[1] ?? ''; } @@ -465,7 +465,7 @@ final class File extends FileAbstract implements FileInterface */ public static function name(string $path) : string { - return explode('.', basename($path))[0]; + return \explode('.', \basename($path))[0]; } /** @@ -473,7 +473,7 @@ final class File extends FileAbstract implements FileInterface */ public static function basename(string $path) : string { - return basename($path); + return \basename($path); } /** @@ -481,7 +481,7 @@ final class File extends FileAbstract implements FileInterface */ public static function extension(string $path) : string { - $extension = explode('.', basename($path)); + $extension = \explode('.', \basename($path)); return $extension[1] ?? ''; } diff --git a/System/File/Local/LocalStorage.php b/System/File/Local/LocalStorage.php index 0a03b2c48..fc3860de9 100644 --- a/System/File/Local/LocalStorage.php +++ b/System/File/Local/LocalStorage.php @@ -64,7 +64,7 @@ class LocalStorage extends StorageAbstract */ protected static function getClassType(string $path) : string { - return is_dir($path) || (!is_file($path) && stripos($path, '.') === false) ? Directory::class : File::class; + return \is_dir($path) || (!is_file($path) && \stripos($path, '.') === false) ? Directory::class : File::class; } /** @@ -72,7 +72,7 @@ class LocalStorage extends StorageAbstract */ public static function put(string $path, string $content, int $mode = 0) : bool { - if (is_dir($path)) { + if (\is_dir($path)) { throw new PathException($path); } @@ -84,7 +84,7 @@ class LocalStorage extends StorageAbstract */ public static function get(string $path) : string { - if (is_dir($path)) { + if (\is_dir($path)) { throw new PathException($path); } @@ -96,7 +96,7 @@ class LocalStorage extends StorageAbstract */ public static function list(string $path, string $filter = '*') : array { - if (is_file($path)) { + if (\is_file($path)) { throw new PathException($path); } @@ -108,7 +108,7 @@ class LocalStorage extends StorageAbstract */ public static function create(string $path) : bool { - return stripos($path, '.') === false ? Directory::create($path, 0755, true) : File::create($path); + return \stripos($path, '.') === false ? Directory::create($path, 0755, true) : File::create($path); } /** @@ -116,7 +116,7 @@ class LocalStorage extends StorageAbstract */ public static function set(string $path, string $content) : bool { - if (is_dir($path)) { + if (\is_dir($path)) { throw new PathException($path); } @@ -128,7 +128,7 @@ class LocalStorage extends StorageAbstract */ public static function append(string $path, string $content) : bool { - if (is_dir($path)) { + if (\is_dir($path)) { throw new PathException($path); } @@ -140,7 +140,7 @@ class LocalStorage extends StorageAbstract */ public static function prepend(string $path, string $content) : bool { - if (is_dir($path)) { + if (\is_dir($path)) { throw new PathException($path); } @@ -152,7 +152,7 @@ class LocalStorage extends StorageAbstract */ public static function extension(string $path) : string { - if (is_dir($path)) { + if (\is_dir($path)) { throw new PathException($path); } diff --git a/System/SystemUtils.php b/System/SystemUtils.php index c0383fe92..ce40b5a34 100644 --- a/System/SystemUtils.php +++ b/System/SystemUtils.php @@ -58,7 +58,7 @@ final class SystemUtils while ($line = fgets($fh)) { $pieces = []; - if (preg_match('/^MemTotal:\s+(\d+)\skB$/', $line, $pieces)) { + if (\preg_match('/^MemTotal:\s+(\d+)\skB$/', $line, $pieces)) { $mem = $pieces[1] * 1024; break; } @@ -84,8 +84,8 @@ final class SystemUtils if (stristr(PHP_OS, 'LINUX')) { $free = shell_exec('free'); $free = (string) trim($free); - $freeArr = explode("\n", $free); - $mem = explode(" ", $freeArr[1]); + $freeArr = \explode("\n", $free); + $mem = \explode(" ", $freeArr[1]); $mem = array_values(array_filter($mem)); $memUsage = $mem[2] / $mem[1] * 100; } diff --git a/UnhandledHandler.php b/UnhandledHandler.php index 1511188b9..defda347f 100644 --- a/UnhandledHandler.php +++ b/UnhandledHandler.php @@ -28,7 +28,7 @@ final class UnhandledHandler /** * Exception handler. * - * @param mixed $e Exception + * @param \Throwable $e Exception * * @return void * diff --git a/Uri/UriFactory.php b/Uri/UriFactory.php index cdb06cbd4..ccfc01fab 100644 --- a/Uri/UriFactory.php +++ b/Uri/UriFactory.php @@ -157,7 +157,7 @@ final class UriFactory $success = false; foreach (self::$uri as $key => $value) { - if (((bool) preg_match('~^' . $pattern . '$~', $key))) { + if (((bool) \preg_match('~^' . $pattern . '$~', $key))) { unset(self::$uri[$key]); $success = true; } @@ -179,16 +179,16 @@ final class UriFactory */ private static function unique(string $url) : string { - $parts = explode('?', $url); + $parts = \explode('?', $url); if (count($parts) >= 2) { $full = $parts[1]; - $pars = explode('&', $full); + $pars = \explode('&', $full); $comps = []; $length = count($pars); for ($i = 0; $i < $length; ++$i) { - $spl = explode('=', $pars[$i]); + $spl = \explode('=', $pars[$i]); if (isset($spl[1])) { $comps[$spl[0]] = $spl[1]; @@ -200,7 +200,7 @@ final class UriFactory $pars[] = $key . '=' . $value; } - $url = $parts[0] . (empty($pars) ? '' : '?' . implode('&', $pars)); + $url = $parts[0] . (empty($pars) ? '' : '?' . \implode('&', $pars)); } return $url; @@ -227,15 +227,15 @@ final class UriFactory */ public static function build(string $uri, array $toMatch = []) : string { - $parsed = preg_replace_callback('(\{[\/#\?%@\.\$][a-zA-Z0-9\-]*\})', function ($match) use ($toMatch) { - $match = substr($match[0], 1, strlen($match[0]) - 2); + $parsed = \preg_replace_callback('(\{[\/#\?%@\.\$][a-zA-Z0-9\-]*\})', function ($match) use ($toMatch) { + $match = \substr($match[0], 1, \strlen($match[0]) - 2); return $toMatch[$match] ?? self::$uri[$match] ?? $match; }, $uri); // todo: maybe don't do this and adjust unique?! - if (strpos($parsed, '?')) { - str_replace('&', '?', $parsed); + if (\strpos($parsed, '?')) { + \str_replace('&', '?', $parsed); } return self::unique($parsed); diff --git a/Utils/ArrayUtils.php b/Utils/ArrayUtils.php index bf77a272a..02733d7e6 100644 --- a/Utils/ArrayUtils.php +++ b/Utils/ArrayUtils.php @@ -48,7 +48,7 @@ final class ArrayUtils */ public static function unsetArray(string $path, array $data, string $delim = '/') : array { - $nodes = explode($delim, trim($path, $delim)); + $nodes = \explode($delim, trim($path, $delim)); $prevEl = null; $el = &$data; @@ -86,7 +86,7 @@ final class ArrayUtils */ public static function setArray(string $path, array $data, $value, string $delim = '/', bool $overwrite = false) : array { - $pathParts = explode($delim, trim($path, $delim)); + $pathParts = \explode($delim, trim($path, $delim)); $current = &$data; foreach ($pathParts as $key) { @@ -121,7 +121,7 @@ final class ArrayUtils */ public static function getArray(string $path, array $data, string $delim = '/') { - $pathParts = explode($delim, trim($path, $delim)); + $pathParts = \explode($delim, trim($path, $delim)); $current = $data; foreach ($pathParts as $key) { @@ -167,7 +167,7 @@ final class ArrayUtils /** * Check if any of the needles are in the array * - * @param mixed $needles Needles for search + * @param array $needles Needles for search * @param array $haystack Haystack for search * * @return bool @@ -177,7 +177,7 @@ final class ArrayUtils public static function anyInArray(array $needles, array $haystack) : bool { foreach ($needles as $needle) { - if (in_array($needle, $haystack)) { + if (\in_array($needle, $haystack)) { return true; } } @@ -188,7 +188,7 @@ final class ArrayUtils /** * Check if all of the needles are in the array * - * @param mixed $needles Needles for search + * @param array $needles Needles for search * @param array $haystack Haystack for search * * @return bool @@ -198,7 +198,7 @@ final class ArrayUtils public static function allInArray(array $needles, array $haystack) : bool { foreach ($needles as $needle) { - if (!in_array($needle, $haystack)) { + if (!\in_array($needle, $haystack)) { return false; } } diff --git a/Utils/Barcode/C128Abstract.php b/Utils/Barcode/C128Abstract.php index 4ef6482ec..14d365967 100644 --- a/Utils/Barcode/C128Abstract.php +++ b/Utils/Barcode/C128Abstract.php @@ -370,7 +370,7 @@ abstract class C128Abstract * * @param string $codeString Code string to render * - * @return array + * @return array * * @since 1.0.0 */ diff --git a/Utils/Barcode/C25.php b/Utils/Barcode/C25.php index e7fd316ab..a5d62c39f 100644 --- a/Utils/Barcode/C25.php +++ b/Utils/Barcode/C25.php @@ -125,8 +125,8 @@ class C25 extends C128Abstract for ($posX = 1; $posX <= $length; $posX += 2) { if (isset($temp[$posX], $temp[($posX + 1)])) { - $temp1 = explode('-', $temp[$posX]); - $temp2 = explode('-', $temp[($posX + 1)]); + $temp1 = \explode('-', $temp[$posX]); + $temp2 = \explode('-', $temp[($posX + 1)]); $count = count($temp1); for ($posY = 0; $posY < $count; $posY++) { diff --git a/Utils/ColorUtils.php b/Utils/ColorUtils.php index ef9b1245d..6917b1c83 100644 --- a/Utils/ColorUtils.php +++ b/Utils/ColorUtils.php @@ -40,7 +40,7 @@ final class ColorUtils * * @param int $rgbInt Value to convert * - * @return array + * @return array * * @since 1.0.0 */ diff --git a/Utils/Compression/LZW.php b/Utils/Compression/LZW.php index 589d60a0f..3e8cee371 100644 --- a/Utils/Compression/LZW.php +++ b/Utils/Compression/LZW.php @@ -65,7 +65,7 @@ class LZW implements CompressionInterface */ public function decompress(string $compressed) : string { - $compressed = explode(',', $compressed); + $compressed = \explode(',', $compressed); $dictionary = []; $entry = ''; $dictSize = 256; diff --git a/Utils/Converter/Ip.php b/Utils/Converter/Ip.php index 0916690ee..a2e686b8b 100644 --- a/Utils/Converter/Ip.php +++ b/Utils/Converter/Ip.php @@ -47,7 +47,7 @@ class Ip */ public static function ip2Float(string $ip) : float { - $split = explode('.', $ip); + $split = \explode('.', $ip); return $split[0] * (256 ** 3) + $split[1] * (256 ** 2) + $split[2] * (256 ** 1) + $split[3]; } diff --git a/Utils/Encoding/Huffman/Dictionary.php b/Utils/Encoding/Huffman/Dictionary.php index 2cbd48dfb..45fdd5446 100644 --- a/Utils/Encoding/Huffman/Dictionary.php +++ b/Utils/Encoding/Huffman/Dictionary.php @@ -80,7 +80,7 @@ final class Dictionary $count = []; while (isset($source[0])) { $count[] = [substr_count($source, $source[0]), $source[0]]; - $source = str_replace($source[0], '', $source); + $source = \str_replace($source[0], '', $source); } sort($count); @@ -144,7 +144,7 @@ final class Dictionary throw new \InvalidArgumentException('Character already exists'); } - if (strlen(str_replace('0', '', str_replace('1', '', $value))) !== 0) { + if (strlen(\str_replace('0', '', \str_replace('1', '', $value))) !== 0) { throw new \InvalidArgumentException('Bad formatting.'); } diff --git a/Utils/Git/Repository.php b/Utils/Git/Repository.php index b86abee43..46117aad5 100644 --- a/Utils/Git/Repository.php +++ b/Utils/Git/Repository.php @@ -95,7 +95,7 @@ class Repository throw new PathException($path); } - if (file_exists($this->path . '/.git') && is_dir($this->path . '/.git')) { + if (file_exists($this->path . '/.git') && \is_dir($this->path . '/.git')) { $this->bare = false; } elseif (is_file($this->path . '/config')) { // Is this a bare repo? $parseIni = parse_ini_file($this->path . '/config'); @@ -171,7 +171,7 @@ class Repository private function run(string $cmd) : array { if (strtolower(substr(PHP_OS, 0, 3)) == 'win') { - $cmd = 'cd ' . escapeshellarg(dirname(Git::getBin())) + $cmd = 'cd ' . escapeshellarg(\dirname(Git::getBin())) . ' && ' . basename(Git::getBin()) . ' -C ' . escapeshellarg($this->path) . ' ' . $cmd; @@ -242,12 +242,12 @@ class Repository */ public function create(string $source = null) : void { - if (!is_dir($this->path) || file_exists($this->path . '/.git')) { + if (!is_dir($this->path) || \file_exists($this->path . '/.git')) { throw new \Exception('Already repository'); } if ($source !== null) { - stripos($source, '//') !== false ? $this->cloneRemote($source) : $this->cloneFrom($source); + \stripos($source, '//') !== false ? $this->cloneRemote($source) : $this->cloneFrom($source); return; } @@ -438,8 +438,8 @@ class Repository { if (empty($this->name)) { $path = $this->getDirectoryPath(); - $path = str_replace('\\', '/', $path); - $path = explode('/', $path); + $path = \str_replace('\\', '/', $path); + $path = \explode('/', $path); $this->name = $path[count($path) - ($this->bare ? 1 : 2)]; } @@ -605,7 +605,7 @@ class Repository */ public function setDescription(string $description) : void { - file_put_contents($this->getDirectoryPath(), $description); + \file_put_contents($this->getDirectoryPath(), $description); } /** @@ -617,7 +617,7 @@ class Repository */ public function getDescription() : string { - return file_get_contents($this->getDirectoryPath() . '/description'); + return \file_get_contents($this->getDirectoryPath() . '/description'); } /** @@ -657,7 +657,7 @@ class Repository continue; } - if (!file_exists($path = $this->getDirectoryPath() . ($this->bare ? '/' : '/../') . $line)) { + if (!\file_exists($path = $this->getDirectoryPath() . ($this->bare ? '/' : '/../') . $line)) { return 0; } @@ -702,7 +702,7 @@ class Repository $contributors = []; foreach ($lines as $line) { - preg_match('/^[0-9]*/', $line, $matches); + \preg_match('/^[0-9]*/', $line, $matches); $contributor = new Author(substr($line, strlen($matches[0]) + 1)); $contributor->setCommitCount($this->getCommitsCount($start, $end)[$contributor->getName()]); @@ -741,7 +741,7 @@ class Repository $commits = []; foreach ($lines as $line) { - preg_match('/^[0-9]*/', $line, $matches); + \preg_match('/^[0-9]*/', $line, $matches); $commits[substr($line, strlen($matches[0]) + 1)] = (int) $matches[0]; } @@ -779,7 +779,7 @@ class Repository ); foreach ($lines as $line) { - $nums = explode(' ', $line); + $nums = \explode(' ', $line); $addremove['added'] += $nums[0]; $addremove['removed'] += $nums[1]; @@ -836,7 +836,7 @@ class Repository $commits = []; for ($i = 0; $i < $count; ++$i) { - $match = preg_match('/[0-9ABCDEFabcdef]{40}/', $lines[$i], $matches); + $match = \preg_match('/[0-9ABCDEFabcdef]{40}/', $lines[$i], $matches); if ($match !== false && $match !== 0) { $commit = $this->getCommit($matches[0]); @@ -868,7 +868,7 @@ class Repository return new Commit(); } - preg_match('/[0-9ABCDEFabcdef]{40}/', $lines[0], $matches); + \preg_match('/[0-9ABCDEFabcdef]{40}/', $lines[0], $matches); if (!isset($matches[0]) || strlen($matches[0]) !== 40) { throw new \Exception('Invalid commit id'); @@ -879,8 +879,8 @@ class Repository } // todo: validate if array values are all initialized - $author = explode(':', $lines[1]); - $author = explode('<', trim($author[1])); + $author = \explode(':', $lines[1]); + $author = \explode('<', trim($author[1])); $date = substr($lines[2], 6); $commit = new Commit($matches[0]); @@ -918,7 +918,7 @@ class Repository return new Commit(); } - preg_match('/[0-9ABCDEFabcdef]{40}/', $lines[0], $matches); + \preg_match('/[0-9ABCDEFabcdef]{40}/', $lines[0], $matches); if (!isset($matches[0]) || strlen($matches[0]) !== 40) { throw new \Exception('Invalid commit id'); diff --git a/Utils/IO/Csv/CsvDatabaseMapper.php b/Utils/IO/Csv/CsvDatabaseMapper.php index d5005ec22..26489fe94 100644 --- a/Utils/IO/Csv/CsvDatabaseMapper.php +++ b/Utils/IO/Csv/CsvDatabaseMapper.php @@ -71,7 +71,7 @@ class CsvDatabaseMapper implements IODatabaseMapper } $query = new Builder($this->db); - $query->insert(...$header)->into(str_replace(' ', '', explode($source, '.'))); + $query->insert(...$header)->into(\str_replace(' ', '', explode($source, '.'))); while (feof($file)) { $c = 0; diff --git a/Utils/IO/Zip/Gz.php b/Utils/IO/Zip/Gz.php index c43168cd5..47e3ea97f 100644 --- a/Utils/IO/Zip/Gz.php +++ b/Utils/IO/Zip/Gz.php @@ -31,8 +31,8 @@ class Gz implements ArchiveInterface */ public static function pack($source, string $destination, bool $overwrite = true) : bool { - $destination = str_replace('\\', '/', realpath($destination)); - if (!$overwrite && file_exists($destination)) { + $destination = \str_replace('\\', '/', realpath($destination)); + if (!$overwrite && \file_exists($destination)) { return false; } @@ -55,7 +55,7 @@ class Gz implements ArchiveInterface */ public static function unpack(string $source, string $destination) : bool { - $destination = str_replace('\\', '/', realpath($destination)); + $destination = \str_replace('\\', '/', realpath($destination)); if (file_exists($destination)) { return false; } diff --git a/Utils/IO/Zip/Tar.php b/Utils/IO/Zip/Tar.php index 457701394..498494215 100644 --- a/Utils/IO/Zip/Tar.php +++ b/Utils/IO/Zip/Tar.php @@ -31,17 +31,17 @@ class Tar implements ArchiveInterface */ public static function pack($sources, string $destination, bool $overwrite = true) : bool { - $destination = str_replace('\\', '/', realpath($destination)); + $destination = \str_replace('\\', '/', realpath($destination)); - if (!$overwrite && file_exists($destination)) { + if (!$overwrite && \file_exists($destination)) { return false; } /** @var array $sources */ foreach ($sources as $source) { - $source = str_replace('\\', '/', realpath($source)); + $source = \str_replace('\\', '/', realpath($source)); - if (!file_exists($source)) { + if (!\file_exists($source)) { continue; } @@ -52,10 +52,10 @@ class Tar implements ArchiveInterface ); foreach ($files as $file) { - $file = str_replace('\\', '/', $file); + $file = \str_replace('\\', '/', $file); /* Ignore . and .. */ - if (in_array(mb_substr($file, mb_strrpos($file, '/') + 1), ['.', '..'])) { + if (\in_array(mb_substr($file, mb_strrpos($file, '/') + 1), ['.', '..'])) { continue; } diff --git a/Utils/IO/Zip/Zip.php b/Utils/IO/Zip/Zip.php index 26c85f9d7..0060cc868 100644 --- a/Utils/IO/Zip/Zip.php +++ b/Utils/IO/Zip/Zip.php @@ -34,9 +34,9 @@ class Zip implements ArchiveInterface */ public static function pack($sources, string $destination, bool $overwrite = true) : bool { - $destination = FileUtils::absolute(str_replace('\\', '/', $destination)); + $destination = FileUtils::absolute(\str_replace('\\', '/', $destination)); - if (!$overwrite && file_exists($destination)) { + if (!$overwrite && \file_exists($destination)) { return false; } @@ -47,9 +47,9 @@ class Zip implements ArchiveInterface /** @var array $sources */ foreach ($sources as $source => $relative) { - $source = str_replace('\\', '/', realpath($source)); + $source = \str_replace('\\', '/', realpath($source)); - if (!file_exists($source)) { + if (!\file_exists($source)) { continue; } @@ -57,16 +57,16 @@ class Zip implements ArchiveInterface $files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($source), \RecursiveIteratorIterator::SELF_FIRST); foreach ($files as $file) { - $file = str_replace('\\', '/', $file); + $file = \str_replace('\\', '/', $file); /* Ignore . and .. */ - if (in_array(mb_substr($file, mb_strrpos($file, '/') + 1), ['.', '..'])) { + if (\in_array(mb_substr($file, mb_strrpos($file, '/') + 1), ['.', '..'])) { continue; } $absolute = realpath($file); - $absolute = str_replace('\\', '/', $absolute); - $dir = str_replace($source . '/', '', $relative . '/' . $absolute); + $absolute = \str_replace('\\', '/', $absolute); + $dir = \str_replace($source . '/', '', $relative . '/' . $absolute); if (is_dir($absolute)) { $zip->addEmptyDir($dir . '/'); @@ -87,11 +87,11 @@ class Zip implements ArchiveInterface */ public static function unpack(string $source, string $destination) : bool { - if (!file_exists($source)) { + if (!\file_exists($source)) { return false; } - $destination = str_replace('\\', '/', $destination); + $destination = \str_replace('\\', '/', $destination); $destination = rtrim($destination, '/'); $zip = new \ZipArchive(); diff --git a/Utils/ImageUtils.php b/Utils/ImageUtils.php index d1e82b3c0..9cd030d7b 100644 --- a/Utils/ImageUtils.php +++ b/Utils/ImageUtils.php @@ -48,8 +48,8 @@ final class ImageUtils */ public static function decodeBase64Image(string $img) : string { - $img = str_replace('data:image/png;base64,', '', $img); - $img = str_replace(' ', '+', $img); + $img = \str_replace('data:image/png;base64,', '', $img); + $img = \str_replace(' ', '+', $img); return base64_decode($img); } diff --git a/Utils/JsonBuilder.php b/Utils/JsonBuilder.php index b1c0aabc9..f96d709bf 100644 --- a/Utils/JsonBuilder.php +++ b/Utils/JsonBuilder.php @@ -80,7 +80,7 @@ final class JsonBuilder implements \Serializable, \JsonSerializable */ public function serialize() : string { - return json_encode($this->json); + return \json_encode($this->json); } /** @@ -88,7 +88,7 @@ final class JsonBuilder implements \Serializable, \JsonSerializable */ public function unserialize($serialized) { - $this->json = json_decode($serialized, true); + $this->json = \json_decode($serialized, true); } /** diff --git a/Utils/Parser/LaTex/Expressions/Product.php b/Utils/Parser/LaTex/Expressions/Product.php deleted file mode 100644 index fd78aecb4..000000000 --- a/Utils/Parser/LaTex/Expressions/Product.php +++ /dev/null @@ -1,19 +0,0 @@ - 0 ? substr($line, $indent) : $line; + $text = $indent > 0 ? \substr($line, $indent) : $line; $lineArray = ['body' => $line, 'indent' => $indent, 'text' => $text]; if (isset($currentBlock['continuable'])) { @@ -288,7 +288,7 @@ class Markdown $currentBlock = $block; continue; - } elseif (in_array($currentBlock['type'], self::$completable)) { + } elseif (\in_array($currentBlock['type'], self::$completable)) { $currentBlock = self::{'block' . $currentBlock['type'] . 'Complete'}($currentBlock); } } @@ -314,7 +314,7 @@ class Markdown $block['identified'] = true; } - if (in_array($blockType, self::$continuable)) { + if (\in_array($blockType, self::$continuable)) { $block['continuable'] = true; } @@ -333,7 +333,7 @@ class Markdown } } - if (isset($currentBlock['continuable']) && in_array($currentBlock['type'], self::$completable)) { + if (isset($currentBlock['continuable']) && \in_array($currentBlock['type'], self::$completable)) { $currentBlock = self::{'block' . $currentBlock['type'] . 'Complete'}($currentBlock); } @@ -381,7 +381,7 @@ class Markdown 'handler' => 'element', 'text' => [ 'name' => 'code', - 'text' => substr($lineArray['body'], 4), + 'text' => \substr($lineArray['body'], 4), ], ], ]; @@ -410,7 +410,7 @@ class Markdown } $block['element']['text']['text'] .= "\n"; - $block['element']['text']['text'] .= substr($lineArray['body'], 4); + $block['element']['text']['text'] .= \substr($lineArray['body'], 4); return $block; } @@ -440,7 +440,7 @@ class Markdown */ protected static function blockFencedCode(array $lineArray) : ?array { - if (!preg_match('/^[' . $lineArray['text'][0] . ']{3,}[ ]*([^`]+)?[ ]*$/', $lineArray['text'], $matches)) { + if (!\preg_match('/^[' . $lineArray['text'][0] . ']{3,}[ ]*([^`]+)?[ ]*$/', $lineArray['text'], $matches)) { return null; } @@ -487,8 +487,8 @@ class Markdown unset($block['interrupted']); } - if (preg_match('/^' . $block['char'] . '{3,}[ ]*$/', $lineArray['text'])) { - $block['element']['text']['text'] = substr($block['element']['text']['text'], 1); + if (\preg_match('/^' . $block['char'] . '{3,}[ ]*$/', $lineArray['text'])) { + $block['element']['text']['text'] = \substr($block['element']['text']['text'], 1); $block['complete'] = true; return $block; @@ -540,7 +540,7 @@ class Markdown return [ 'element' => [ 'name' => 'h' . min(6, $level), - 'text' => trim($lineArray['text'], '# '), + 'text' => \trim($lineArray['text'], '# '), 'handler' => 'line', ], ]; @@ -559,7 +559,7 @@ class Markdown { list($name, $pattern) = $lineArray['text'][0] <= '-' ? ['ul', '[*+-]'] : ['ol', '[0-9]+[.]']; - if (!preg_match('/^(' . $pattern . '[ ]+)(.*)/', $lineArray['text'], $matches)) { + if (!\preg_match('/^(' . $pattern . '[ ]+)(.*)/', $lineArray['text'], $matches)) { return null; } @@ -605,7 +605,7 @@ class Markdown */ protected static function blockListContinue(array $lineArray, array $block) : ?array { - if ($block['indent'] === $lineArray['indent'] && preg_match('/^' . $block['pattern'] . '(?:[ ]+(.*)|$)/', $lineArray['text'], $matches)) { + if ($block['indent'] === $lineArray['indent'] && \preg_match('/^' . $block['pattern'] . '(?:[ ]+(.*)|$)/', $lineArray['text'], $matches)) { if (isset($block['interrupted'])) { $block['li']['text'][] = ''; @@ -632,14 +632,14 @@ class Markdown } if (!isset($block['interrupted'])) { - $block['li']['text'][] = preg_replace('/^[ ]{0,4}/', '', $lineArray['body']); + $block['li']['text'][] = \preg_replace('/^[ ]{0,4}/', '', $lineArray['body']); return $block; } if ($lineArray['indent'] > 0) { $block['li']['text'][] = ''; - $block['li']['text'][] = preg_replace('/^[ ]{0,4}/', '', $lineArray['body']); + $block['li']['text'][] = \preg_replace('/^[ ]{0,4}/', '', $lineArray['body']); unset($block['interrupted']); @@ -660,7 +660,7 @@ class Markdown */ protected static function blockQuote(array $lineArray) : ?array { - if (!preg_match('/^>[ ]?(.*)/', $lineArray['text'], $matches)) { + if (!\preg_match('/^>[ ]?(.*)/', $lineArray['text'], $matches)) { return null; } @@ -685,7 +685,7 @@ class Markdown */ protected static function blockQuoteContinue(array $lineArray, array $block) : ?array { - if ($lineArray['text'][0] === '>' && preg_match('/^>[ ]?(.*)/', $lineArray['text'], $matches)) { + if ($lineArray['text'][0] === '>' && \preg_match('/^>[ ]?(.*)/', $lineArray['text'], $matches)) { if (isset($block['interrupted'])) { $block['element']['text'][] = ''; @@ -717,7 +717,7 @@ class Markdown */ protected static function blockRule(array $lineArray) : ?array { - if (!preg_match('/^([' . $lineArray['text'][0] . '])([ ]*\1){2,}[ ]*$/', $lineArray['text'])) { + if (!\preg_match('/^([' . $lineArray['text'][0] . '])([ ]*\1){2,}[ ]*$/', $lineArray['text'])) { return null; } @@ -764,7 +764,7 @@ class Markdown */ protected static function blockReference(array $lineArray) : ?array { - if (!preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $lineArray['text'], $matches)) { + if (!\preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $lineArray['text'], $matches)) { return null; } @@ -773,7 +773,7 @@ class Markdown 'title' => $matches[3] ?? null, ]; - self::$definitionData['Reference'][strtolower($matches[1])] = $data; + self::$definitionData['Reference'][\strtolower($matches[1])] = $data; return ['hidden' => true]; } @@ -794,15 +794,15 @@ class Markdown return null; } - if (strpos($block['element']['text'], '|') !== false && chop($lineArray['text'], ' -:|') === '') { + if (\strpos($block['element']['text'], '|') !== false && chop($lineArray['text'], ' -:|') === '') { $alignments = []; $divider = $lineArray['text']; - $divider = trim($divider); - $divider = trim($divider, '|'); - $dividerCells = explode('|', $divider); + $divider = \trim($divider); + $divider = \trim($divider, '|'); + $dividerCells = \explode('|', $divider); foreach ($dividerCells as $dividerCell) { - $dividerCell = trim($dividerCell); + $dividerCell = \trim($dividerCell); if ($dividerCell === '') { continue; @@ -823,14 +823,14 @@ class Markdown $headerElements = []; $header = $block['element']['text']; - $header = trim($header); - $header = trim($header, '|'); - $headerCells = explode('|', $header); + $header = \trim($header); + $header = \trim($header, '|'); + $headerCells = \explode('|', $header); foreach ($headerCells as $index => $headerCell) { $headerElement = [ 'name' => 'th', - 'text' => trim($headerCell), + 'text' => \trim($headerCell), 'handler' => 'line', ]; @@ -891,11 +891,11 @@ class Markdown return null; } - if ($lineArray['text'][0] === '|' || strpos($lineArray['text'], '|')) { + if ($lineArray['text'][0] === '|' || \strpos($lineArray['text'], '|')) { $elements = []; $row = $lineArray['text']; - $row = trim($row); - $row = trim($row, '|'); + $row = \trim($row); + $row = \trim($row, '|'); preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches); @@ -903,7 +903,7 @@ class Markdown $element = [ 'name' => 'td', 'handler' => 'line', - 'text' => trim($cell), + 'text' => \trim($cell), ]; if (isset($block['alignments'][$index])) { @@ -958,9 +958,9 @@ class Markdown { $markup = ''; - while ($excerpt = strpbrk($text, self::$inlineMarkerList)) { + while ($excerpt = \strpbrk($text, self::$inlineMarkerList)) { $marker = $excerpt[0]; - $markerPosition = strpos($text, $marker); + $markerPosition = \strpos($text, $marker); $excerptArray = ['text' => $excerpt, 'context' => $text]; foreach (self::$inlineTypes[$marker] as $inlineType) { @@ -978,17 +978,17 @@ class Markdown $inline['position'] = $markerPosition; } - $unmarkedText = substr($text, 0, $inline['position']); + $unmarkedText = \substr($text, 0, $inline['position']); $markup .= self::unmarkedText($unmarkedText); $markup .= isset($inline['markup']) ? $inline['markup'] : self::element($inline['element']); - $text = substr($text, $inline['position'] + $inline['extent']); + $text = \substr($text, $inline['position'] + $inline['extent']); continue 2; } - $unmarkedText = substr($text, 0, $markerPosition + 1); + $unmarkedText = \substr($text, 0, $markerPosition + 1); $markup .= self::unmarkedText($unmarkedText); - $text = substr($text, $markerPosition + 1); + $text = \substr($text, $markerPosition + 1); } $markup .= self::unmarkedText($text); @@ -1009,15 +1009,15 @@ class Markdown { $marker = $excerpt['text'][0]; - if (!preg_match('/^(' . $marker . '+)[ ]*(.+?)[ ]*(? strlen($matches[0]), + 'extent' => \strlen($matches[0]), 'element' => [ 'name' => 'code', - 'text' => preg_replace("/[ ]*\n/", ' ', $matches[2]), + 'text' => \preg_replace("/[ ]*\n/", ' ', $matches[2]), ], ]; } @@ -1033,7 +1033,7 @@ class Markdown */ protected static function inlineEmailTag(array $excerpt) : ?array { - if (strpos($excerpt['text'], '>') === false || !preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $excerpt['text'], $matches)) { + if (\strpos($excerpt['text'], '>') === false || !\preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $excerpt['text'], $matches)) { return null; } @@ -1044,7 +1044,7 @@ class Markdown } return [ - 'extent' => strlen($matches[0]), + 'extent' => \strlen($matches[0]), 'element' => [ 'name' => 'a', 'text' => $matches[1], @@ -1072,18 +1072,18 @@ class Markdown $marker = $excerpt['text'][0]; - if ($excerpt['text'][1] === $marker && isset(self::$strongRegex[$marker]) && preg_match(self::$strongRegex[$marker], $excerpt['text'], $matches)) { + if ($excerpt['text'][1] === $marker && isset(self::$strongRegex[$marker]) && \preg_match(self::$strongRegex[$marker], $excerpt['text'], $matches)) { $emphasis = 'strong'; - } elseif ($excerpt['text'][1] === $marker && isset(self::$underlineRegex[$marker]) && preg_match(self::$underlineRegex[$marker], $excerpt['text'], $matches)) { + } elseif ($excerpt['text'][1] === $marker && isset(self::$underlineRegex[$marker]) && \preg_match(self::$underlineRegex[$marker], $excerpt['text'], $matches)) { $emphasis = 'u'; - } elseif (preg_match(self::$emRegex[$marker], $excerpt['text'], $matches)) { + } elseif (\preg_match(self::$emRegex[$marker], $excerpt['text'], $matches)) { $emphasis = 'em'; } else { return null; } return [ - 'extent' => strlen($matches[0]), + 'extent' => \strlen($matches[0]), 'element' => [ 'name' => $emphasis, 'handler' => 'line', @@ -1103,7 +1103,7 @@ class Markdown */ protected static function inlineEscapeSequence(array $excerpt) : ?array { - if (!isset($excerpt['text'][1]) || !in_array($excerpt['text'][1], self::$specialCharacters)) { + if (!isset($excerpt['text'][1]) || !\in_array($excerpt['text'][1], self::$specialCharacters)) { return null; } @@ -1128,7 +1128,7 @@ class Markdown return null; } - $excerpt['text'] = substr($excerpt['text'], 1); + $excerpt['text'] = \substr($excerpt['text'], 1); $link = self::inlineLink($excerpt); if ($link === null) { @@ -1177,30 +1177,30 @@ class Markdown $extent = 0; $remainder = $excerpt['text']; - if (!preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches)) { + if (!\preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches)) { return null; } $element['text'] = $matches[1]; - $extent += strlen($matches[0]); - $remainder = substr($remainder, $extent); + $extent += \strlen($matches[0]); + $remainder = \substr($remainder, $extent); - if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches)) { + if (\preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches)) { $element['attributes']['href'] = $matches[1]; if (isset($matches[2])) { - $element['attributes']['title'] = substr($matches[2], 1, - 1); + $element['attributes']['title'] = \substr($matches[2], 1, - 1); } - $extent += strlen($matches[0]); + $extent += \strlen($matches[0]); } else { - if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches)) { - $definition = strlen($matches[1]) ? $matches[1] : $element['text']; - $definition = strtolower($definition); + if (\preg_match('/^\s*\[(.*?)\]/', $remainder, $matches)) { + $definition = \strlen($matches[1]) ? $matches[1] : $element['text']; + $definition = \strtolower($definition); - $extent += strlen($matches[0]); + $extent += \strlen($matches[0]); } else { - $definition = strtolower($element['text']); + $definition = \strtolower($element['text']); } if (!isset(self::$definitionData['Reference'][$definition])) { @@ -1230,7 +1230,7 @@ class Markdown */ protected static function inlineSpecialCharacter(array $excerpt) : ?array { - if ($excerpt['text'][0] === '&' && !preg_match('/^&#?\w+;/', $excerpt['text'])) { + if ($excerpt['text'][0] === '&' && !\preg_match('/^&#?\w+;/', $excerpt['text'])) { return [ 'markup' => '&', 'extent' => 1, @@ -1262,12 +1262,12 @@ class Markdown return null; } - if ($excerpt['text'][1] !== '~' || !preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $excerpt['text'], $matches)) { + if ($excerpt['text'][1] !== '~' || !\preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $excerpt['text'], $matches)) { return null; } return [ - 'extent' => strlen($matches[0]), + 'extent' => \strlen($matches[0]), 'element' => [ 'name' => 'del', 'text' => $matches[1], @@ -1291,12 +1291,12 @@ class Markdown return null; } - if (!preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) { + if (!\preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) { return null; } return [ - 'extent' => strlen($matches[0][0]), + 'extent' => \strlen($matches[0][0]), 'position' => $matches[0][1], 'element' => [ 'name' => 'a', @@ -1319,12 +1319,12 @@ class Markdown */ protected static function inlineUrlTag(array $excerpt) : ?array { - if (strpos($excerpt['text'], '>') === false || !preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $excerpt['text'], $matches)) { + if (\strpos($excerpt['text'], '>') === false || !\preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $excerpt['text'], $matches)) { return null; } return [ - 'extent' => strlen($matches[0]), + 'extent' => \strlen($matches[0]), 'element' => [ 'name' => 'a', 'text' => $matches[1], @@ -1346,8 +1346,8 @@ class Markdown */ protected static function unmarkedText(string $text) : string { - $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text); - $text = str_replace(" \n", "\n", $text); + $text = \preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text); + $text = \str_replace(" \n", "\n", $text); return $text; } @@ -1421,13 +1421,13 @@ class Markdown protected static function li(array $lines) : string { $markup = self::lines($lines); - $trimmedMarkup = trim($markup); + $trimmedMarkup = \trim($markup); - if (!in_array('', $lines) && substr($trimmedMarkup, 0, 3) === '

') { + if (!\in_array('', $lines) && \substr($trimmedMarkup, 0, 3) === '

') { $markup = $trimmedMarkup; - $markup = substr($markup, 3); - $position = strpos($markup, '

'); - $markup = substr_replace($markup, '', $position, 4); + $markup = \substr($markup, 3); + $position = \strpos($markup, '

'); + $markup = \substr_replace($markup, '', $position, 4); } return $markup; @@ -1455,7 +1455,7 @@ class Markdown if (!empty($element['attributes'])) { foreach ($element['attributes'] as $att => $val) { - if (!preg_match('/^[a-zA-Z0-9][a-zA-Z0-9-_]*+$/', $att)) { + if (!\preg_match('/^[a-zA-Z0-9][a-zA-Z0-9-_]*+$/', $att)) { unset($element['attributes'][$att]); } elseif (self::striAtStart($att, 'on')) { unset($element['attributes'][$att]); @@ -1484,7 +1484,7 @@ class Markdown } } - $element['attributes'][$attribute] = str_replace(':', '%3A', $element['attributes'][$attribute]); + $element['attributes'][$attribute] = \str_replace(':', '%3A', $element['attributes'][$attribute]); return $element; } @@ -1501,7 +1501,7 @@ class Markdown */ protected static function escape(string $text, bool $allowQuotes = false) : string { - return htmlspecialchars($text, $allowQuotes ? ENT_NOQUOTES : ENT_QUOTES, 'UTF-8'); + return \htmlspecialchars($text, $allowQuotes ? ENT_NOQUOTES : ENT_QUOTES, 'UTF-8'); } /** @@ -1516,12 +1516,12 @@ class Markdown */ protected static function striAtStart(string $string, string $needle) : bool { - $length = strlen($needle); + $length = \strlen($needle); - if ($length > strlen($string)) { + if ($length > \strlen($string)) { return false; } - return strtolower(substr($string, 0, $length)) === strtolower($needle); + return \strtolower(\substr($string, 0, $length)) === \strtolower($needle); } } diff --git a/Utils/Parser/Php/ArrayParser.php b/Utils/Parser/Php/ArrayParser.php index f09c877c3..ae98ed482 100644 --- a/Utils/Parser/Php/ArrayParser.php +++ b/Utils/Parser/Php/ArrayParser.php @@ -42,7 +42,7 @@ class ArrayParser foreach ($arr as $key => $val) { if (is_string($key)) { - $key = '\'' . str_replace('\'', '\\\'', $key) . '\''; + $key = '\'' . \str_replace('\'', '\\\'', $key) . '\''; } $stringify .= str_repeat(' ', $depth * 4) . $key . ' => ' . self::parseVariable($val, $depth + 1) . ',' . "\n"; @@ -66,7 +66,7 @@ class ArrayParser if (is_array($value)) { return ArrayParser::serializeArray($value, $depth); } elseif (is_string($value)) { - return '\'' . str_replace('\'', '\\\'', $value) . '\''; + return '\'' . \str_replace('\'', '\\\'', $value) . '\''; } elseif (is_scalar($value)) { return (string) $value; } elseif ($value === null) { diff --git a/Utils/RnG/Phone.php b/Utils/RnG/Phone.php index 1b696f784..c3ae1bba2 100644 --- a/Utils/RnG/Phone.php +++ b/Utils/RnG/Phone.php @@ -36,12 +36,13 @@ class Phone * * @since 1.0.0 */ - public static function generatePhone($isInt = true, $layout = ['struct' => '+$1 ($2) $3-$4', - 'size' => [null, - [3, 4], - [3, 5], - [3, 8],],], $countries = null) - { + public static function generatePhone( + $isInt = true, + $layout = [ + 'struct' => '+$1 ($2) $3-$4', + 'size' => [null, [3, 4], [3, 5], [3, 8],],], + $countries = null + ) { $numberString = $layout['struct']; if ($isInt) { @@ -49,13 +50,13 @@ class Phone $countries = ['de' => 49, 'us' => 1]; } - $numberString = str_replace('$1', $countries[array_keys($countries)[rand(0, count($countries))]], $numberString); + $numberString = \str_replace('$1', $countries[array_keys($countries)[rand(0, count($countries))]], $numberString); } $numberParts = substr_count($layout['struct'], '$'); for ($i = ($isInt ? 2 : 1); $i < $numberParts; ++$i) { - $numberString = str_replace( + $numberString = \str_replace( '$' . $i, StringUtils::generateString($layout['size'][$i - 1][0], $layout['size'][$i - 1][1], '0123456789'), $numberString ); diff --git a/Utils/RnG/Text.php b/Utils/RnG/Text.php index 16e96304d..706ea8667 100644 --- a/Utils/RnG/Text.php +++ b/Utils/RnG/Text.php @@ -196,7 +196,7 @@ class Text } } - $text = ltrim($text); + $text = \ltrim($text); if ($this->hasParagraphs) { $text = '

' . $text . '

'; diff --git a/Utils/StringUtils.php b/Utils/StringUtils.php index 8c5628be2..50c46f306 100644 --- a/Utils/StringUtils.php +++ b/Utils/StringUtils.php @@ -270,7 +270,7 @@ final class StringUtils if ($charlist === ' ') { return trim($string); } else { - $charlist = str_replace('/', '\/', preg_quote($charlist)); + $charlist = \str_replace('/', '\/', preg_quote($charlist)); return preg_replace('/(^[' . $charlist . ']+)|([ ' . $charlist . ']+$)/us', '', $string); } @@ -291,7 +291,7 @@ final class StringUtils if ($charlist === ' ') { return rtrim($string); } else { - $charlist = str_replace('/', '\/', preg_quote($charlist)); + $charlist = \str_replace('/', '\/', preg_quote($charlist)); return preg_replace('/([' . $charlist . ']+$)/us', '', $string); } @@ -310,9 +310,9 @@ final class StringUtils public static function mb_ltrim(string $string, string $charlist = ' ') : string { if ($charlist === ' ') { - return ltrim($string); + return \ltrim($string); } else { - $charlist = str_replace('/', '\/', preg_quote($charlist)); + $charlist = \str_replace('/', '\/', preg_quote($charlist)); return preg_replace('/(^[' . $charlist . ']+)/us', '', $string); } @@ -375,7 +375,7 @@ final class StringUtils * * @param string $input String to count chars. * - * @return array + * @return array * * @since 1.0.0 */ diff --git a/Utils/TaskSchedule/Cron.php b/Utils/TaskSchedule/Cron.php index 4ce9e3582..37171fee6 100644 --- a/Utils/TaskSchedule/Cron.php +++ b/Utils/TaskSchedule/Cron.php @@ -39,7 +39,7 @@ class Cron extends SchedulerAbstract */ private function run(string $cmd) : string { - $cmd = 'cd ' . escapeshellarg(dirname(self::$bin)) . ' && ' . basename(self::$bin) . ' ' . $cmd; + $cmd = 'cd ' . escapeshellarg(\dirname(self::$bin)) . ' && ' . basename(self::$bin) . ' ' . $cmd; $pipes = []; $desc = [ @@ -75,7 +75,7 @@ class Cron extends SchedulerAbstract */ private function normalize(string $raw) : string { - return str_replace("\r\n", "\n", $raw); + return \str_replace("\r\n", "\n", $raw); } /** @@ -83,7 +83,7 @@ class Cron extends SchedulerAbstract */ public function getAll() : array { - $lines = explode("\n", $this->normalize($this->run('-l'))); + $lines = \explode("\n", $this->normalize($this->run('-l'))); unset($lines[0]); $jobs = []; @@ -101,7 +101,7 @@ class Cron extends SchedulerAbstract */ public function getAllByName(string $name, bool $exact = true) : array { - $lines = explode("\n", $this->normalize($this->run('-l'))); + $lines = \explode("\n", $this->normalize($this->run('-l'))); unset($lines[0]); if ($exact) { @@ -118,7 +118,7 @@ class Cron extends SchedulerAbstract foreach ($lines as $line) { $csv = str_getcsv($line, ' '); - if ($line !== '' && strrpos($line, '#', -strlen($line)) === false && stripos($csv[5], $name) !== false) { + if ($line !== '' && strrpos($line, '#', -strlen($line)) === false && \stripos($csv[5], $name) !== false) { $jobs[] = CronJob::createWith($csv); } } diff --git a/Utils/TaskSchedule/Interval.php b/Utils/TaskSchedule/Interval.php index ef046d2d0..12864ba0c 100644 --- a/Utils/TaskSchedule/Interval.php +++ b/Utils/TaskSchedule/Interval.php @@ -116,7 +116,7 @@ class Interval implements \Serializable */ public function unserialize($serialized) { - $elements = explode(' ', trim($serialized)); + $elements = \explode(' ', trim($serialized)); $this->minute = $this->parseMinute($elements[0]); $this->hour = $this->parseHour($elements[1]); diff --git a/Utils/TaskSchedule/TaskScheduler.php b/Utils/TaskSchedule/TaskScheduler.php index 7b70eac91..6d76c6ba3 100644 --- a/Utils/TaskSchedule/TaskScheduler.php +++ b/Utils/TaskSchedule/TaskScheduler.php @@ -38,7 +38,7 @@ class TaskScheduler extends SchedulerAbstract */ private function run(string $cmd) : string { - $cmd = 'cd ' . escapeshellarg(dirname(self::$bin)) . ' && ' . basename(self::$bin) . ' ' . $cmd; + $cmd = 'cd ' . escapeshellarg(\dirname(self::$bin)) . ' && ' . basename(self::$bin) . ' ' . $cmd; $pipes = []; $desc = [ @@ -74,7 +74,7 @@ class TaskScheduler extends SchedulerAbstract */ private function normalize(string $raw) : string { - return str_replace("\r\n", "\n", $raw); + return \str_replace("\r\n", "\n", $raw); } /** @@ -82,7 +82,7 @@ class TaskScheduler extends SchedulerAbstract */ public function getAll() : array { - $lines = explode("\n", $this->normalize($this->run('/query /v /fo CSV'))); + $lines = \explode("\n", $this->normalize($this->run('/query /v /fo CSV'))); unset($lines[0]); $jobs = []; @@ -99,7 +99,7 @@ class TaskScheduler extends SchedulerAbstract public function getAllByName(string $name, bool $exact = true) : array { if ($exact) { - $lines = explode("\n", $this->normalize($this->run('/query /v /fo CSV /tn ' . escapeshellarg($name)))); + $lines = \explode("\n", $this->normalize($this->run('/query /v /fo CSV /tn ' . escapeshellarg($name)))); unset($lines[0]); $jobs = []; @@ -107,7 +107,7 @@ class TaskScheduler extends SchedulerAbstract $jobs[] = Schedule::createWith(str_getcsv($line)); } } else { - $lines = explode("\n", $this->normalize($this->run('/query /v /fo CSV'))); + $lines = \explode("\n", $this->normalize($this->run('/query /v /fo CSV'))); unset($lines[0]); $jobs = []; diff --git a/Validation/Finance/BIC.php b/Validation/Finance/BIC.php index 6160e0b4d..b61139b65 100644 --- a/Validation/Finance/BIC.php +++ b/Validation/Finance/BIC.php @@ -32,6 +32,6 @@ final class BIC extends ValidatorAbstract */ public static function isValid($value, array $constraints = null) : bool { - return (bool) preg_match('/^[a-z]{6}[0-9a-z]{2}([0-9a-z]{3})?\z/i', $value); + return (bool) \preg_match('/^[a-z]{6}[0-9a-z]{2}([0-9a-z]{3})?\z/i', $value); } } diff --git a/Validation/Finance/Iban.php b/Validation/Finance/Iban.php index d4e3ba549..00884dda2 100644 --- a/Validation/Finance/Iban.php +++ b/Validation/Finance/Iban.php @@ -31,7 +31,7 @@ final class Iban extends ValidatorAbstract */ public static function isValid($value, array $constraints = null) : bool { - $value = str_replace(' ', '', strtolower($value)); + $value = \str_replace(' ', '', strtolower($value)); $enumName = 'C_' . strtoupper(substr($value, 0, 2)); if (!IbanEnum::isValidName($enumName)) { @@ -40,7 +40,7 @@ final class Iban extends ValidatorAbstract return false; } - $layout = str_replace(' ', '', IbanEnum::getByName($enumName)); + $layout = \str_replace(' ', '', IbanEnum::getByName($enumName)); if (strlen($value) !== strlen($layout)) { self::$error = IbanErrorType::INVALID_LENGTH; diff --git a/Validation/Validator.php b/Validation/Validator.php index bebc2e2f3..090156223 100644 --- a/Validation/Validator.php +++ b/Validation/Validator.php @@ -136,7 +136,7 @@ final class Validator extends ValidatorAbstract */ public static function matches(string $var, string $pattern) : bool { - return (preg_match($pattern, $var) === 1 ? true : false); + return (\preg_match($pattern, $var) === 1 ? true : false); } /** diff --git a/Views/ViewAbstract.php b/Views/ViewAbstract.php index 398c7fce5..8861a24ab 100644 --- a/Views/ViewAbstract.php +++ b/Views/ViewAbstract.php @@ -203,7 +203,7 @@ abstract class ViewAbstract implements \Serializable public function serialize() : string { if (empty($this->template)) { - return json_encode($this->toArray()); + return \json_encode($this->toArray()); } return $this->render(); @@ -245,7 +245,7 @@ abstract class ViewAbstract implements \Serializable $ob = ''; $path = __DIR__ . '/../..' . $this->template . '.tpl.php'; - if (!file_exists($path)) { + if (!\file_exists($path)) { throw new PathException($path); } @@ -256,7 +256,7 @@ abstract class ViewAbstract implements \Serializable $ob = ob_get_clean(); if (is_array($includeData)) { - return json_encode($includeData); + return \json_encode($includeData); } } catch (\Throwable $e) { $ob = ''; diff --git a/tests/Account/AccountTest.php b/tests/Account/AccountTest.php index 464f2e33a..5e6b16cc5 100644 --- a/tests/Account/AccountTest.php +++ b/tests/Account/AccountTest.php @@ -98,7 +98,7 @@ class AccountTest extends \PHPUnit\Framework\TestCase $array = $account->toArray(); self::assertTrue(is_array($array)); self::assertGreaterThan(0, count($array)); - self::assertEquals(json_encode($array), $account->__toString()); + self::assertEquals(\json_encode($array), $account->__toString()); self::assertEquals($array, $account->jsonSerialize()); } diff --git a/tests/Account/GroupTest.php b/tests/Account/GroupTest.php index da556fe50..e2b163c75 100644 --- a/tests/Account/GroupTest.php +++ b/tests/Account/GroupTest.php @@ -55,7 +55,7 @@ class GroupTest extends \PHPUnit\Framework\TestCase $array = $group->toArray(); self::assertTrue(is_array($array)); self::assertGreaterThan(0, count($array)); - self::assertEquals(json_encode($array), $group->__toString()); + self::assertEquals(\json_encode($array), $group->__toString()); self::assertEquals($array, $group->jsonSerialize()); } diff --git a/tests/Autoloader.php b/tests/Autoloader.php index 932dc5218..14d7d1998 100644 --- a/tests/Autoloader.php +++ b/tests/Autoloader.php @@ -42,10 +42,10 @@ class Autoloader */ public static function defaultAutoloader(string $class) : void { - $class = ltrim($class, '\\'); - $class = str_replace(['_', '\\'], '/', $class); + $class = \ltrim($class, '\\'); + $class = \str_replace(['_', '\\'], '/', $class); - if (!file_exists($path = __DIR__ . '/../../' . $class . '.php')) { + if (!\file_exists($path = __DIR__ . '/../../' . $class . '.php')) { return; } @@ -66,9 +66,9 @@ class Autoloader */ public static function exists(string $class) : bool { - $class = ltrim($class, '\\'); - $class = str_replace(['_', '\\'], '/', $class); + $class = \ltrim($class, '\\'); + $class = \str_replace(['_', '\\'], '/', $class); - return file_exists(__DIR__ . '/../../' . $class . '.php'); + return \file_exists(__DIR__ . '/../../' . $class . '.php'); } } diff --git a/tests/DataStorage/Database/TestModel/BaseModelMapper.php b/tests/DataStorage/Database/TestModel/BaseModelMapper.php index 2eccc4fb8..8b7a423c6 100644 --- a/tests/DataStorage/Database/TestModel/BaseModelMapper.php +++ b/tests/DataStorage/Database/TestModel/BaseModelMapper.php @@ -24,7 +24,7 @@ class BaseModelMapper extends DataMapperAbstract /** * Columns. * - * @var array + * @var array> * @since 1.0.0 */ protected static $columns = [ diff --git a/tests/DataStorage/Database/TestModel/BelongsToModelMapper.php b/tests/DataStorage/Database/TestModel/BelongsToModelMapper.php index 716cea1ad..b4c3f80e0 100644 --- a/tests/DataStorage/Database/TestModel/BelongsToModelMapper.php +++ b/tests/DataStorage/Database/TestModel/BelongsToModelMapper.php @@ -24,7 +24,7 @@ class BelongsToModelMapper extends DataMapperAbstract /** * Columns. * - * @var array + * @var array> * @since 1.0.0 */ protected static $columns = [ diff --git a/tests/DataStorage/Database/TestModel/ManyToManyDirectModelMapper.php b/tests/DataStorage/Database/TestModel/ManyToManyDirectModelMapper.php index 897cdd7ea..1b53fe5ad 100644 --- a/tests/DataStorage/Database/TestModel/ManyToManyDirectModelMapper.php +++ b/tests/DataStorage/Database/TestModel/ManyToManyDirectModelMapper.php @@ -24,7 +24,7 @@ class ManyToManyDirectModelMapper extends DataMapperAbstract /** * Columns. * - * @var array + * @var array> * @since 1.0.0 */ protected static $columns = [ diff --git a/tests/DataStorage/Database/TestModel/ManyToManyRelModelMapper.php b/tests/DataStorage/Database/TestModel/ManyToManyRelModelMapper.php index f8b8bdfd3..799c8b71a 100644 --- a/tests/DataStorage/Database/TestModel/ManyToManyRelModelMapper.php +++ b/tests/DataStorage/Database/TestModel/ManyToManyRelModelMapper.php @@ -24,7 +24,7 @@ class ManyToManyRelModelMapper extends DataMapperAbstract /** * Columns. * - * @var array + * @var array> * @since 1.0.0 */ protected static $columns = [ diff --git a/tests/DataStorage/Database/TestModel/OwnsOneModelMapper.php b/tests/DataStorage/Database/TestModel/OwnsOneModelMapper.php index ab137f620..136120e02 100644 --- a/tests/DataStorage/Database/TestModel/OwnsOneModelMapper.php +++ b/tests/DataStorage/Database/TestModel/OwnsOneModelMapper.php @@ -24,7 +24,7 @@ class OwnsOneModelMapper extends DataMapperAbstract /** * Columns. * - * @var array + * @var array> * @since 1.0.0 */ protected static $columns = [ diff --git a/tests/Localization/Defaults/CityMapperTest.php b/tests/Localization/Defaults/CityMapperTest.php new file mode 100644 index 000000000..376386a12 --- /dev/null +++ b/tests/Localization/Defaults/CityMapperTest.php @@ -0,0 +1,23 @@ +getName()); + self::assertEquals('', $obj->getCountryCode()); + self::assertEquals('', $obj->getState()); + self::assertEquals(0, $obj->getPostal()); + self::assertEquals(0.0, $obj->getLat()); + self::assertEquals(0.0, $obj->getLong()); + } +} diff --git a/tests/Localization/Defaults/CountryMapperTest.php b/tests/Localization/Defaults/CountryMapperTest.php new file mode 100644 index 000000000..629f35676 --- /dev/null +++ b/tests/Localization/Defaults/CountryMapperTest.php @@ -0,0 +1,23 @@ +getName()); + self::assertEquals('', $obj->getCode2()); + self::assertEquals('', $obj->getCode3()); + self::assertEquals(0, $obj->getNumeric()); + self::assertEquals('', $obj->getSubdevision()); + } +} diff --git a/tests/Localization/Defaults/CurrencyMapperTest.php b/tests/Localization/Defaults/CurrencyMapperTest.php new file mode 100644 index 000000000..e80f7f9a9 --- /dev/null +++ b/tests/Localization/Defaults/CurrencyMapperTest.php @@ -0,0 +1,23 @@ +getName()); + self::assertEquals(0, $obj->getNumber()); + self::assertEquals(0, $obj->getDecimals()); + self::assertEquals('', $obj->getCountries()); + } +} diff --git a/tests/Localization/Defaults/IbanMapperTest.php b/tests/Localization/Defaults/IbanMapperTest.php new file mode 100644 index 000000000..080f03bf4 --- /dev/null +++ b/tests/Localization/Defaults/IbanMapperTest.php @@ -0,0 +1,23 @@ +getCountry()); + self::assertEquals('', $obj->getChars()); + self::assertEquals('', $obj->getBban()); + self::assertEquals('', $obj->getFields()); + } +} diff --git a/tests/Localization/Defaults/LanguageMapperTest.php b/tests/Localization/Defaults/LanguageMapperTest.php new file mode 100644 index 000000000..c9a9c0f67 --- /dev/null +++ b/tests/Localization/Defaults/LanguageMapperTest.php @@ -0,0 +1,23 @@ +getName()); + self::assertEquals('', $obj->getNative()); + self::assertEquals('', $obj->getCode2()); + self::assertEquals('', $obj->getCode3()); + } +} diff --git a/tests/Math/Geometry/Shape/D2/TriangleTest.php b/tests/Math/Geometry/Shape/D2/TriangleTest.php index 0be4b4cf0..520e1bd42 100644 --- a/tests/Math/Geometry/Shape/D2/TriangleTest.php +++ b/tests/Math/Geometry/Shape/D2/TriangleTest.php @@ -22,5 +22,6 @@ class TriangleTest extends \PHPUnit\Framework\TestCase self::assertEquals(3, Triangle::getSurface(2, 3), '', 0.001); self::assertEquals(9, Triangle::getPerimeter(2, 3, 4), '', 0.001); self::assertEquals(3, Triangle::getHeight(3, 2), '', 0.001); + self::assertEquals(5, Triangle::getHypot(4, 3), '', 0.001); } } diff --git a/tests/Math/Geometry/Shape/D3/SphereTest.php b/tests/Math/Geometry/Shape/D3/SphereTest.php index 40dcc846e..0b4df8858 100644 --- a/tests/Math/Geometry/Shape/D3/SphereTest.php +++ b/tests/Math/Geometry/Shape/D3/SphereTest.php @@ -22,6 +22,8 @@ class SphereTest extends \PHPUnit\Framework\TestCase $sphere = new Sphere(3); self::assertEquals(113.1, $sphere->getVolume(), '', 0.1); self::assertEquals(113.1, $sphere->getSurface(), '', 0.1); + + self::assertEquals(422740, Sphere::distance2PointsOnSphere(32.9697, -96.80322, 29.46786, -98.53506), '', 50); } public function testGetBy() diff --git a/tests/Math/Optimization/AssignmentProblemTest.php b/tests/Math/Optimization/AssignmentProblemTest.php deleted file mode 100644 index 34e89c7df..000000000 --- a/tests/Math/Optimization/AssignmentProblemTest.php +++ /dev/null @@ -1,24 +0,0 @@ -getName()); - self::assertEquals((float) 0, $obj->getLatitude()); - self::assertEquals((float) 0, $obj->getLongitude()); - self::assertTrue($obj->equals(new City())); - self::assertEquals(0, $obj->getDistanceTo(new City())); - } - - public function testGetSet() - { - $obj = new City(10, 20, 'A'); - self::assertEquals('A', $obj->getName()); - self::assertEquals((float) 10, $obj->getLatitude()); - self::assertEquals((float) 20, $obj->getLongitude()); - self::assertTrue(abs(2476171 - $obj->getDistanceTo(new City())) < 1); - self::assertFalse($obj->equals(new City())); - } -} diff --git a/tests/Math/Optimization/TSP/GATest.php b/tests/Math/Optimization/TSP/GATest.php deleted file mode 100644 index b673a791e..000000000 --- a/tests/Math/Optimization/TSP/GATest.php +++ /dev/null @@ -1,33 +0,0 @@ -evolvePopulation($basePopulation); - - } -} diff --git a/tests/Math/Optimization/TSP/PopulationTest.php b/tests/Math/Optimization/TSP/PopulationTest.php deleted file mode 100644 index 80bb4e78d..000000000 --- a/tests/Math/Optimization/TSP/PopulationTest.php +++ /dev/null @@ -1,24 +0,0 @@ -getCity(1)); - self::assertEquals(0.0, $obj->getFitness()); - self::assertEquals(0.0, $obj->getDistance()); - self::assertFalse($obj->hasCity(new City())); - self::assertEquals(0, $obj->count()); - } -} diff --git a/tests/Math/Optimization/TransportationProblemTest.php b/tests/Math/Optimization/TransportationProblemTest.php deleted file mode 100644 index 711dd7658..000000000 --- a/tests/Math/Optimization/TransportationProblemTest.php +++ /dev/null @@ -1,24 +0,0 @@ -setMethod(RequestMethod::POST); self::assertTrue($request->setData('pdata', 'abc')); - self::assertEquals('abc', json_decode(REST::request($request), true)['form']['pdata']); + self::assertEquals('abc', \json_decode(REST::request($request), true)['form']['pdata']); } public function testPut() @@ -45,7 +45,7 @@ class RestTest extends \PHPUnit\Framework\TestCase $request = new Request(new Http('http://httpbin.org/put')); $request->setMethod(RequestMethod::PUT); self::assertTrue($request->setData('pdata', 'abc')); - self::assertEquals('abc', json_decode(REST::request($request), true)['form']['pdata']); + self::assertEquals('abc', \json_decode(REST::request($request), true)['form']['pdata']); } public function testDelete() @@ -53,7 +53,7 @@ class RestTest extends \PHPUnit\Framework\TestCase $request = new Request(new Http('http://httpbin.org/delete')); $request->setMethod(RequestMethod::DELETE); self::assertTrue($request->setData('ddata', 'abc')); - self::assertEquals('abc', json_decode(REST::request($request), true)['form']['ddata']); + self::assertEquals('abc', \json_decode(REST::request($request), true)['form']['ddata']); } public function testGet() @@ -61,6 +61,6 @@ class RestTest extends \PHPUnit\Framework\TestCase $request = new Request(new Http('http://httpbin.org/get')); $request->setMethod(RequestMethod::GET); self::assertTrue($request->setData('gdata', 'abc')); - self::assertEquals('abc', json_decode(REST::request($request), true)['args']['gdata']); + self::assertEquals('abc', \json_decode(REST::request($request), true)['args']['gdata']); } } diff --git a/tests/Module/InfoManagerTest.php b/tests/Module/InfoManagerTest.php index 39c35cf77..6ac7d988c 100644 --- a/tests/Module/InfoManagerTest.php +++ b/tests/Module/InfoManagerTest.php @@ -24,7 +24,7 @@ class InfoManagerTest extends \PHPUnit\Framework\TestCase $info = new InfoManager(__DIR__ . '/info-test.json'); $info->load(); - $jarray = json_decode(file_get_contents(__DIR__ . '/info-test.json'), true); + $jarray = \json_decode(file_get_contents(__DIR__ . '/info-test.json'), true); self::assertEquals($jarray, $info->get()); self::assertEquals($jarray['name']['internal'], $info->getInternalName()); diff --git a/tests/Security/PhpCodeTest.php b/tests/Security/PhpCodeTest.php index 2a9116244..583198aeb 100644 --- a/tests/Security/PhpCodeTest.php +++ b/tests/Security/PhpCodeTest.php @@ -24,7 +24,7 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase self::assertTrue( PhpCode::hasUnicode( PhpCode::normalizeSource( - file_get_contents(__DIR__ . '/Sample/hasUnicode.php') + \file_get_contents(__DIR__ . '/Sample/hasUnicode.php') ) ) ); @@ -32,7 +32,7 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase self::assertFalse( PhpCode::hasUnicode( PhpCode::normalizeSource( - file_get_contents(__DIR__ . '/Sample/noUnicode.php') + \file_get_contents(__DIR__ . '/Sample/noUnicode.php') ) ) ); @@ -49,7 +49,7 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase self::assertTrue( PhpCode::hasDeprecatedFunction( PhpCode::normalizeSource( - file_get_contents(__DIR__ . '/Sample/hasDeprecated.php') + \file_get_contents(__DIR__ . '/Sample/hasDeprecated.php') ) ) ); @@ -57,7 +57,7 @@ class RouteVerbTest extends \PHPUnit\Framework\TestCase self::assertFalse( PhpCode::hasDeprecatedFunction( PhpCode::normalizeSource( - file_get_contents(__DIR__ . '/Sample/noDeprecated.php') + \file_get_contents(__DIR__ . '/Sample/noDeprecated.php') ) ) ); diff --git a/tests/System/File/Ftp/DirectoryTest.php b/tests/System/File/Ftp/DirectoryTest.php index 769a7c5bf..43411d9cb 100644 --- a/tests/System/File/Ftp/DirectoryTest.php +++ b/tests/System/File/Ftp/DirectoryTest.php @@ -38,7 +38,7 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase self::assertEquals('test', Directory::name($dirPath)); self::assertEquals('test', Directory::basename($dirPath)); self::assertEquals('test', Directory::dirname($dirPath)); - self::assertEquals(str_replace('\\', '/', realpath($dirPath . '/../')), Directory::parent($dirPath)); + self::assertEquals(\str_replace('\\', '/', realpath($dirPath . '/../')), Directory::parent($dirPath)); self::assertEquals($dirPath, Directory::dirpath($dirPath)); $now = new \DateTime('now'); diff --git a/tests/System/File/Ftp/FileTest.php b/tests/System/File/Ftp/FileTest.php index 872ee27d2..bc5ba193b 100644 --- a/tests/System/File/Ftp/FileTest.php +++ b/tests/System/File/Ftp/FileTest.php @@ -44,7 +44,7 @@ class FileTest extends \PHPUnit\Framework\TestCase self::assertTrue(File::prepend($testFile, 'test5')); self::assertEquals('test5test3test4', File::get($testFile)); - self::assertEquals(str_replace('\\', '/', realpath(dirname($testFile) . '/../')), File::parent($testFile)); + self::assertEquals(\str_replace('\\', '/', realpath(\dirname($testFile) . '/../')), File::parent($testFile)); self::assertEquals('txt', File::extension($testFile)); self::assertEquals('test', File::name($testFile)); self::assertEquals('test.txt', File::basename($testFile)); diff --git a/tests/System/File/Ftp/FtpStorageTest.php b/tests/System/File/Ftp/FtpStorageTest.php index aea4d6ba4..511cacefe 100644 --- a/tests/System/File/Ftp/FtpStorageTest.php +++ b/tests/System/File/Ftp/FtpStorageTest.php @@ -44,7 +44,7 @@ class FtpStorageTest extends \PHPUnit\Framework\TestCase self::assertTrue(FtpStorage::prepend($testFile, 'test5')); self::assertEquals('test5test3test4', FtpStorage::get($testFile)); - self::assertEquals(str_replace('\\', '/', realpath(dirname($testFile) . '/../')), FtpStorage::parent($testFile)); + self::assertEquals(\str_replace('\\', '/', realpath(\dirname($testFile) . '/../')), FtpStorage::parent($testFile)); self::assertEquals('txt', FtpStorage::extension($testFile)); self::assertEquals('test', FtpStorage::name($testFile)); self::assertEquals('test.txt', FtpStorage::basename($testFile)); @@ -103,7 +103,7 @@ class FtpStorageTest extends \PHPUnit\Framework\TestCase self::assertEquals('test', FtpStorage::name($dirPath)); self::assertEquals('test', FtpStorage::basename($dirPath)); self::assertEquals('test', FtpStorage::dirname($dirPath)); - self::assertEquals(str_replace('\\', '/', realpath($dirPath . '/../')), FtpStorage::parent($dirPath)); + self::assertEquals(\str_replace('\\', '/', realpath($dirPath . '/../')), FtpStorage::parent($dirPath)); self::assertEquals($dirPath, FtpStorage::dirpath($dirPath)); $now = new \DateTime('now'); diff --git a/tests/System/File/Local/DirectoryTest.php b/tests/System/File/Local/DirectoryTest.php index 59ca84f90..9728b1210 100644 --- a/tests/System/File/Local/DirectoryTest.php +++ b/tests/System/File/Local/DirectoryTest.php @@ -31,7 +31,7 @@ class DirectoryTest extends \PHPUnit\Framework\TestCase self::assertEquals('test', Directory::name($dirPath)); self::assertEquals('test', Directory::basename($dirPath)); self::assertEquals('test', Directory::dirname($dirPath)); - self::assertEquals(str_replace('\\', '/', realpath($dirPath . '/../')), Directory::parent($dirPath)); + self::assertEquals(\str_replace('\\', '/', realpath($dirPath . '/../')), Directory::parent($dirPath)); self::assertEquals($dirPath, Directory::dirpath($dirPath)); $now = new \DateTime('now'); diff --git a/tests/System/File/Local/FileTest.php b/tests/System/File/Local/FileTest.php index 0abb34982..a834ed91d 100644 --- a/tests/System/File/Local/FileTest.php +++ b/tests/System/File/Local/FileTest.php @@ -37,7 +37,7 @@ class FileTest extends \PHPUnit\Framework\TestCase self::assertTrue(File::prepend($testFile, 'test5')); self::assertEquals('test5test3test4', File::get($testFile)); - self::assertEquals(str_replace('\\', '/', realpath(dirname($testFile) . '/../')), File::parent($testFile)); + self::assertEquals(\str_replace('\\', '/', realpath(\dirname($testFile) . '/../')), File::parent($testFile)); self::assertEquals('txt', File::extension($testFile)); self::assertEquals('test', File::name($testFile)); self::assertEquals('test.txt', File::basename($testFile)); diff --git a/tests/System/File/Local/LocalStorageTest.php b/tests/System/File/Local/LocalStorageTest.php index e0854366f..37b4a37ca 100644 --- a/tests/System/File/Local/LocalStorageTest.php +++ b/tests/System/File/Local/LocalStorageTest.php @@ -37,7 +37,7 @@ class LocalStorageTest extends \PHPUnit\Framework\TestCase self::assertTrue(LocalStorage::prepend($testFile, 'test5')); self::assertEquals('test5test3test4', LocalStorage::get($testFile)); - self::assertEquals(str_replace('\\', '/', realpath(dirname($testFile) . '/../')), LocalStorage::parent($testFile)); + self::assertEquals(\str_replace('\\', '/', realpath(\dirname($testFile) . '/../')), LocalStorage::parent($testFile)); self::assertEquals('txt', LocalStorage::extension($testFile)); self::assertEquals('test', LocalStorage::name($testFile)); self::assertEquals('test.txt', LocalStorage::basename($testFile)); @@ -92,7 +92,7 @@ class LocalStorageTest extends \PHPUnit\Framework\TestCase self::assertEquals('test', LocalStorage::name($dirPath)); self::assertEquals('test', LocalStorage::basename($dirPath)); self::assertEquals('test', LocalStorage::dirname($dirPath)); - self::assertEquals(str_replace('\\', '/', realpath($dirPath . '/../')), LocalStorage::parent($dirPath)); + self::assertEquals(\str_replace('\\', '/', realpath($dirPath . '/../')), LocalStorage::parent($dirPath)); self::assertEquals($dirPath, LocalStorage::dirpath($dirPath)); $now = new \DateTime('now'); diff --git a/tests/Utils/Git/RepositoryTest.php b/tests/Utils/Git/RepositoryTest.php index 35b878de7..fe9f2e9a4 100644 --- a/tests/Utils/Git/RepositoryTest.php +++ b/tests/Utils/Git/RepositoryTest.php @@ -21,7 +21,7 @@ class RepositoryTest extends \PHPUnit\Framework\TestCase { $repo = new Repository(realpath(__DIR__ . '/../../../')); self::assertTrue('phpOMS' === $repo->getName() || 'build' === $repo->getName()); - self::assertEquals(str_replace('\\', '/', realpath(__DIR__ . '/../../../.git')), str_replace('\\', '/', $repo->getDirectoryPath())); + self::assertEquals(\str_replace('\\', '/', realpath(__DIR__ . '/../../../.git')), \str_replace('\\', '/', $repo->getDirectoryPath())); self::assertEquals(realpath(__DIR__ . '/../../../'), $repo->getPath()); } } diff --git a/tests/Utils/IO/Zip/ZipTest.php b/tests/Utils/IO/Zip/ZipTest.php index 045ce337f..90e2b4a87 100644 --- a/tests/Utils/IO/Zip/ZipTest.php +++ b/tests/Utils/IO/Zip/ZipTest.php @@ -39,11 +39,11 @@ class ZipTest extends \PHPUnit\Framework\TestCase false )); - $a = file_get_contents(__DIR__ . '/test a.txt'); - $b = file_get_contents(__DIR__ . '/test b.md'); - $c = file_get_contents(__DIR__ . '/test/test c.txt'); - $d = file_get_contents(__DIR__ . '/test/test d.txt'); - $e = file_get_contents(__DIR__ . '/test/sub/test e.txt'); + $a = \file_get_contents(__DIR__ . '/test a.txt'); + $b = \file_get_contents(__DIR__ . '/test b.md'); + $c = \file_get_contents(__DIR__ . '/test/test c.txt'); + $d = \file_get_contents(__DIR__ . '/test/test d.txt'); + $e = \file_get_contents(__DIR__ . '/test/sub/test e.txt'); unlink(__DIR__ . '/test a.txt'); unlink(__DIR__ . '/test b.md'); @@ -71,11 +71,11 @@ class ZipTest extends \PHPUnit\Framework\TestCase self::assertTrue(file_exists(__DIR__ . '/test/sub')); self::assertTrue(file_exists(__DIR__ . '/test')); - self::assertEquals($a, file_get_contents(__DIR__ . '/test a.txt')); - self::assertEquals($b, file_get_contents(__DIR__ . '/test b.md')); - self::assertEquals($c, file_get_contents(__DIR__ . '/test/test c.txt')); - self::assertEquals($d, file_get_contents(__DIR__ . '/test/test d.txt')); - self::assertEquals($e, file_get_contents(__DIR__ . '/test/sub/test e.txt')); + self::assertEquals($a, \file_get_contents(__DIR__ . '/test a.txt')); + self::assertEquals($b, \file_get_contents(__DIR__ . '/test b.md')); + self::assertEquals($c, \file_get_contents(__DIR__ . '/test/test c.txt')); + self::assertEquals($d, \file_get_contents(__DIR__ . '/test/test d.txt')); + self::assertEquals($e, \file_get_contents(__DIR__ . '/test/sub/test e.txt')); unlink(__DIR__ . '/test.zip'); self::assertFalse(file_exists(__DIR__ . '/test.zip')); diff --git a/tests/Utils/ImageUtilsTest.php b/tests/Utils/ImageUtilsTest.php index 9eaf0bfa8..6df0cb339 100644 --- a/tests/Utils/ImageUtilsTest.php +++ b/tests/Utils/ImageUtilsTest.php @@ -22,7 +22,7 @@ class ImageUtilsTest extends \PHPUnit\Framework\TestCase public function testImage() { self::assertEquals( - file_get_contents(__DIR__ . '/logo.png'), + \file_get_contents(__DIR__ . '/logo.png'), ImageUtils::decodeBase64Image( 'data:image/png;base64,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' ) diff --git a/tests/Utils/JsonBuilderTest.php b/tests/Utils/JsonBuilderTest.php index 423c5031f..21cfed82b 100644 --- a/tests/Utils/JsonBuilderTest.php +++ b/tests/Utils/JsonBuilderTest.php @@ -39,7 +39,7 @@ class JsonBuilderTest extends \PHPUnit\Framework\TestCase $arr = $builder->getJson(); self::assertEquals($arr, $builder->jsonSerialize()); - self::assertEquals(json_encode($arr), $builder->serialize()); + self::assertEquals(\json_encode($arr), $builder->serialize()); $builder->unserialize($builder->serialize()); self::assertEquals($arr, $builder->getJson()); diff --git a/tests/Utils/Parser/LaTex/Expressions/ProductTest.php b/tests/Utils/Parser/LaTex/Expressions/ProductTest.php deleted file mode 100644 index ab083ca16..000000000 --- a/tests/Utils/Parser/LaTex/Expressions/ProductTest.php +++ /dev/null @@ -1,24 +0,0 @@ -