From 9ae86275ff3f1477111f7d95295e0312d02c8dd1 Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Tue, 29 Mar 2022 16:41:17 +0200 Subject: [PATCH] phpstan and phpcs fixes --- Account/PermissionAbstract.php | 6 +- Ai/Ocr/Tesseract/TesseractOcr.php | 10 +++- Application/InstallerAbstract.php | 10 ++-- Application/StatusAbstract.php | 4 +- Contract/SerializableInterface.php | 17 ++++++ .../Database/Query/Grammar/Grammar.php | 2 +- Dispatcher/Dispatcher.php | 2 +- Event/EventManager.php | 4 +- Image/Kernel.php | 8 ++- Image/Skew.php | 55 ++++++++++++++----- Image/Thresholding.php | 21 ++++++- Message/Console/ConsoleRequest.php | 3 + Message/Http/HttpRequest.php | 2 +- Message/RequestAbstract.php | 18 ++++++ Module/InstallerAbstract.php | 10 ++-- Module/StatusAbstract.php | 8 +-- Module/UninstallerAbstract.php | 8 +-- System/SystemUtils.php | 7 +++ Uri/Argument.php | 18 ++---- Uri/HttpUri.php | 26 +++++++-- Uri/UriInterface.php | 13 ++++- Utils/ImageUtils.php | 20 +++++++ Utils/NumericUtils.php | 4 +- Utils/Parser/Pdf/PdfParser.php | 27 ++++++--- Utils/TaskSchedule/Cron.php | 20 +++++++ Views/View.php | 14 ++++- 26 files changed, 265 insertions(+), 72 deletions(-) diff --git a/Account/PermissionAbstract.php b/Account/PermissionAbstract.php index 6c9b28d6d..63b2031af 100755 --- a/Account/PermissionAbstract.php +++ b/Account/PermissionAbstract.php @@ -138,7 +138,7 @@ class PermissionAbstract implements \JsonSerializable * @param null|string $app App App to check (null if all are acceptable) * @param null|string $module Module Module to check (null if all are acceptable) * @param null|string $from Provided by which module - * @param null|int $category Type (e.g. customer) (null if all are acceptable) + * @param null|int $category Category (e.g. customer) (null if all are acceptable) * @param null|int $element (e.g. customer id) (null if all are acceptable) * @param null|int $component (e.g. address) (null if all are acceptable) * @param int $permission Permission to check @@ -159,7 +159,7 @@ class PermissionAbstract implements \JsonSerializable $this->app = $app; $this->module = $module; $this->from = $from; - $this->category = $category; + $this->category = $category; $this->element = $element; $this->component = $component; @@ -469,7 +469,7 @@ class PermissionAbstract implements \JsonSerializable * @param null|int $unit Unit Unit to check (null if all are acceptable) * @param null|string $app App App to check (null if all are acceptable) * @param null|string $module Module Module to check (null if all are acceptable) - * @param null|int $category Type (e.g. customer) (null if all are acceptable) + * @param null|int $category Category (e.g. customer) (null if all are acceptable) * @param null|int $element (e.g. customer id) (null if all are acceptable) * @param null|int $component (e.g. address) (null if all are acceptable) * diff --git a/Ai/Ocr/Tesseract/TesseractOcr.php b/Ai/Ocr/Tesseract/TesseractOcr.php index cc82b044f..377f82636 100644 --- a/Ai/Ocr/Tesseract/TesseractOcr.php +++ b/Ai/Ocr/Tesseract/TesseractOcr.php @@ -87,10 +87,15 @@ final class TesseractOcr */ public function parseImage(string $image, array $languages = ['eng'], int $psm = 3, int $oem = 3) : string { + $temp = \tempnam(\sys_get_temp_dir(), 'ocr_'); + if ($temp === false) { + return ''; + } + SystemUtils::runProc( self::$bin, $image . ' ' - . ($temp = \tempnam(\sys_get_temp_dir(), 'ocr_')) + . $temp . ' -c preserve_interword_spaces=1' . ' --psm ' . $psm . ' --oem ' . $oem @@ -98,6 +103,9 @@ final class TesseractOcr ); $parsed = \file_get_contents($temp . '.txt'); + if ($parsed === false) { + return ''; + } // @todo: auto flip image if x% of text are garbage words? diff --git a/Application/InstallerAbstract.php b/Application/InstallerAbstract.php index 67cb31bf3..f8929ecf4 100644 --- a/Application/InstallerAbstract.php +++ b/Application/InstallerAbstract.php @@ -41,9 +41,9 @@ abstract class InstallerAbstract /** * Install app. * - * @param ApplicationAbstract $app Application - * @param ApplicationInfo $info App info - * @param SettingsInterface $cfgHandler Settings/Configuration handler + * @param ApplicationAbstract $app Application + * @param ApplicationInfo $info App info + * @param SettingsInterface $cfgHandler Settings/Configuration handler * * @return void * @@ -125,8 +125,8 @@ abstract class InstallerAbstract /** * Activate after install. * - * @param ApplicationAbstract $app Application - * @param ApplicationInfo $info App info + * @param ApplicationAbstract $app Application + * @param ApplicationInfo $info App info * * @return void * diff --git a/Application/StatusAbstract.php b/Application/StatusAbstract.php index c533f88f6..6680c620b 100644 --- a/Application/StatusAbstract.php +++ b/Application/StatusAbstract.php @@ -42,8 +42,8 @@ abstract class StatusAbstract /** * Deactivate app. * - * @param ApplicationAbstract $app Application - * @param ApplicationInfo $info Module info + * @param ApplicationAbstract $app Application + * @param ApplicationInfo $info Module info * * @return void * diff --git a/Contract/SerializableInterface.php b/Contract/SerializableInterface.php index c313eb475..40f8826b3 100644 --- a/Contract/SerializableInterface.php +++ b/Contract/SerializableInterface.php @@ -27,6 +27,23 @@ namespace phpOMS\Contract; */ interface SerializableInterface { + /** + * Serialize object + * + * @return string + * + * @since 1.0.0 + */ public function serialize() : string; + + /** + * Fill object with data + * + * @param mixed $data Date to unserialize + * + * @return void + * + * @since 1.0.0 + */ public function unserialize($data) : void; } diff --git a/DataStorage/Database/Query/Grammar/Grammar.php b/DataStorage/Database/Query/Grammar/Grammar.php index 0bedf22d5..a56676384 100644 --- a/DataStorage/Database/Query/Grammar/Grammar.php +++ b/DataStorage/Database/Query/Grammar/Grammar.php @@ -611,7 +611,7 @@ class Grammar extends GrammarAbstract return ''; } - $cols = '('; + $cols = '('; for ($i = 0; $i < $count; ++$i) { $cols .= $this->compileSystem($columns[$i]) . ', '; } diff --git a/Dispatcher/Dispatcher.php b/Dispatcher/Dispatcher.php index 8713f1c08..cd6db7af2 100644 --- a/Dispatcher/Dispatcher.php +++ b/Dispatcher/Dispatcher.php @@ -65,7 +65,7 @@ final class Dispatcher implements DispatcherInterface public function dispatch(array | string | \Closure $controller, ...$data) : array { $views = []; - $data = $data !== null ? \array_values($data) : null; + $data = $data !== null ? \array_values($data) : null; if (\is_array($controller) && isset($controller['dest'])) { if (!empty($controller['data'])) { diff --git a/Event/EventManager.php b/Event/EventManager.php index e4cd3973d..34f0bc15f 100644 --- a/Event/EventManager.php +++ b/Event/EventManager.php @@ -251,14 +251,14 @@ final class EventManager implements \Countable foreach ($this->callbacks[$group]['callbacks'] as $func) { if (\is_array($data)) { $data[':triggerGroup'] ??= $group; - $data[':triggerId'] = $id; + $data[':triggerId'] = $id; } else { $data = [ $data, ]; $data[':triggerGroup'] ??= $group; - $data[':triggerId'] = $id; + $data[':triggerId'] = $id; } $this->dispatcher->dispatch($func, ...$data); diff --git a/Image/Kernel.php b/Image/Kernel.php index b82f3c4b5..3879ab0bf 100644 --- a/Image/Kernel.php +++ b/Image/Kernel.php @@ -86,15 +86,19 @@ final class Kernel $im = \imagecreatefromgif($inPath); } + if ($im == false) { + return; + } + if (\count($kernel) === 3) { \imageconvolution($im, $kernel, 1, 0); } else { // @todo: implement @see https://rosettacode.org/wiki/Image_convolution // @todo: not working yet - $dim = [\imagesx($im), \imagesy($im)]; + $dim = [\imagesx($im), \imagesy($im)]; $kDim = [\count($kernel[1]), \count($kernel)]; // @todo: is the order correct? mhh... - $kWidthRadius = NumericUtils::uRightShift($kDim[0], 1); + $kWidthRadius = NumericUtils::uRightShift($kDim[0], 1); $kHeightRadius = NumericUtils::uRightShift($kDim[1], 1); for ($i = $dim[0] - 1; $i >= 0; --$i) { diff --git a/Image/Skew.php b/Image/Skew.php index daec1fc31..ba99cd48b 100644 --- a/Image/Skew.php +++ b/Image/Skew.php @@ -14,8 +14,6 @@ declare(strict_types=1); namespace phpOMS\Image; -use phpOMS\Utils\ImageUtils; - /** * Skew image * @@ -29,10 +27,11 @@ final class Skew /** * Automatically rotate image based on projection profile * - * @param string $inPath Binary input image (black/white) - * @param string $outPath Output image - * @param array $start Start coordinates for analysis (e.g. ignore top/border of image) - * @param array $end End coordinates for analysis (e.g. ignore bottom/border of image) + * @param string $inPath Binary input image (black/white) + * @param string $outPath Output image + * @param int $maxDegree Max degree to consider for rotation + * @param array $start Start coordinates for analysis (e.g. ignore top/border of image) + * @param array $end End coordinates for analysis (e.g. ignore bottom/border of image) */ public static function autoRotate(string $inPath, string $outPath, int $maxDegree = 45, array $start = [], array $end = []) : void { @@ -45,6 +44,10 @@ final class Skew $im = \imagecreatefromgif($inPath); } + if ($im == false) { + return; + } + $dim = [\imagesx($im), \imagesy($im)]; $start = [\max(0, $start[0] ?? 0), \max(0, $start[1] ?? 0)]; @@ -59,15 +62,15 @@ final class Skew for ($i = $start[0]; $i < $end[0]; ++$i) { for ($j = $start[1]; $j < $end[1]; ++$j) { $imMatrix[$j - $start[1]][$i - $start[0]] = \imagecolorat($im, $i, $j) < 0.5 ? 1 : 0; - $avg += $imMatrix[$j - $start[1]][$i - $start[0]]; + $avg += $imMatrix[$j - $start[1]][$i - $start[0]]; } } $avg /= $start[1] - $end[1]; $dimImMatrix = [\count($imMatrix), \count($imMatrix[0])]; - $bestScore = 0; - $bestDegree = 0; + $bestScore = 0; + $bestDegree = 0; for ($i = -$maxDegree; $i < $maxDegree; $i += 1) { if ($i === 0) { @@ -75,7 +78,7 @@ final class Skew } $rotated = self::rotatePixelMatrix($imMatrix, $dimImMatrix, $i); - $hist = []; + $hist = []; for ($j = 0; $j < $dimImMatrix[0]; ++$j) { $hist[$j] = \array_sum($rotated[$j]); @@ -88,12 +91,15 @@ final class Skew $score = \array_sum($hist); if ($bestScore < $score) { - $bestScore = $score; + $bestScore = $score; $bestDegree = $i; } } $im = \imagerotate($im, $bestDegree, 1); + if ($im == false) { + return; + } if (\strripos($outPath, 'png') !== false) { \imagepng($im, $outPath); @@ -106,6 +112,17 @@ final class Skew \imagedestroy($im); } + /** + * Rotate the pixel matrix by a certain degree + * + * @param array $pixel Pixel matrix (0 index = y, 1 index = x) + * @param array $dim Matrix dimension (0 index = y, 1 index = x) + * @param int $deg Degree to rotate + * + * @return array + * + * @since 1.0.0 + */ public static function rotatePixelMatrix(array $pixel, array $dim, int $deg) : array { $rad = \deg2rad($deg); @@ -131,12 +148,24 @@ final class Skew return $rotated; } + /** + * Find the closes pixel based on floating points + * + * @param array $pixel Pixel matrix (0 index = y, 1 index = x) + * @param array $dim Matrix dimension (0 index = y, 1 index = x) + * @param float $x X coordinate + * @param float $y Y coordinate + * + * @return int + * + * @since 1.0.0 + */ private static function getNearestValue(array $pixel, array $dim, float $x, float $y) : int { - $xLow = \min((int) $x, $dim[1] - 1); + $xLow = \min((int) $x, $dim[1] - 1); $xHigh = \min((int) \ceil($x), $dim[1] - 1); - $yLow = \min((int) $y, $dim[0] - 1); + $yLow = \min((int) $y, $dim[0] - 1); $yHigh = \min((int) \ceil($y), $dim[0] - 1); $points = [ diff --git a/Image/Thresholding.php b/Image/Thresholding.php index f54a63eeb..eae7ff036 100644 --- a/Image/Thresholding.php +++ b/Image/Thresholding.php @@ -50,8 +50,15 @@ final class Thresholding $im = \imagecreatefromgif($inPath); } + if ($im == false) { + return; + } + $dim = [\imagesx($im), \imagesy($im)]; $out = \imagecreate($dim[0], $dim[1]); + if ($out == false) { + return; + } $intImg = [[]]; for ($i = 0; $i < $dim[0]; ++$i) { @@ -59,6 +66,10 @@ final class Thresholding for ($j = 0; $j < $dim[1]; ++$j) { $rgb = \imagecolorat($im, $i, $j); + if ($rgb === false) { + $rgb = 0; + } + $sum += ImageUtils::lightness($rgb); $intImg[$i][$j] = $i === 0 ? $sum : $intImg[$i - 1][$j] + $sum; @@ -71,6 +82,10 @@ final class Thresholding $black = \imagecolorallocate($out, 0, 0, 0); $white = \imagecolorallocate($out, 255, 255, 255); + if ($black === false || $white === false) { + return; + } + for ($i = 0; $i < $dim[0]; ++$i) { for ($j = 0; $j < $dim[1]; ++$j) { $x1 = \max(1, (int) ($i - $s / 2.0)); @@ -82,7 +97,11 @@ final class Thresholding $count = ($x2 - $x1) * ($y2 - $y1); $sum = $intImg[$x2][$y2] - $intImg[$x2][$y1 - 1] - $intImg[$x1 - 1][$y2] + $intImg[$x1 - 1][$y1 - 1]; - $rgb = \imagecolorat($im, $i, $j); + $rgb = \imagecolorat($im, $i, $j); + if ($rgb === false) { + $rgb = 0; + } + $brightness = ImageUtils::lightness($rgb); $color = $brightness * $count <= ($sum * (100.0 - $t) / 100.0) ? $black : $white; diff --git a/Message/Console/ConsoleRequest.php b/Message/Console/ConsoleRequest.php index f69e7e1a6..0256c6085 100644 --- a/Message/Console/ConsoleRequest.php +++ b/Message/Console/ConsoleRequest.php @@ -111,6 +111,9 @@ final class ConsoleRequest extends RequestAbstract } } + /** + * {@inheritdoc} + */ public function hasData(string $key) : bool { $key = '-' . \mb_strtolower($key); diff --git a/Message/Http/HttpRequest.php b/Message/Http/HttpRequest.php index 2a702878d..e80905598 100644 --- a/Message/Http/HttpRequest.php +++ b/Message/Http/HttpRequest.php @@ -76,7 +76,7 @@ final class HttpRequest extends RequestAbstract { $this->header = new HttpHeader(); $this->header->l11n = $l11n ?? new Localization(); - $this->uri = $uri ?? new HttpUri(''); + $this->uri = $uri ?? new HttpUri(''); } /** diff --git a/Message/RequestAbstract.php b/Message/RequestAbstract.php index 092ef4d5b..0c3b56026 100644 --- a/Message/RequestAbstract.php +++ b/Message/RequestAbstract.php @@ -267,9 +267,18 @@ abstract class RequestAbstract implements MessageInterface * Get the origin request source (IPv4/IPv6) * * @return string + * + * @since 1.0.0 */ abstract public function getOrigin() : string; + /** + * Get the route verb + * + * @return int + * + * @since 1.0.0 + */ abstract public function getRouteVerb() : int; /** @@ -292,6 +301,15 @@ abstract class RequestAbstract implements MessageInterface return $this->files; } + /** + * Add file to request + * + * @param array $file File data to add (Array here means one file with multiple information e.g. name, path, size) + * + * @return void + * + * @since 1.0.0 + */ public function addFile(array $file) : void { $this->files[] = $file; diff --git a/Module/InstallerAbstract.php b/Module/InstallerAbstract.php index 4ce6961a9..2b4388492 100644 --- a/Module/InstallerAbstract.php +++ b/Module/InstallerAbstract.php @@ -42,9 +42,9 @@ abstract class InstallerAbstract /** * Install module. * - * @param ApplicationAbstract $app Application - * @param ModuleInfo $info Module info - * @param SettingsInterface $cfgHandler Settings/Configuration handler + * @param ApplicationAbstract $app Application + * @param ModuleInfo $info Module info + * @param SettingsInterface $cfgHandler Settings/Configuration handler * * @return void * @@ -87,8 +87,8 @@ abstract class InstallerAbstract /** * Activate after install. * - * @param ApplicationAbstract $app Application - * @param ModuleInfo $info Module info + * @param ApplicationAbstract $app Application + * @param ModuleInfo $info Module info * * @return void * diff --git a/Module/StatusAbstract.php b/Module/StatusAbstract.php index f363d0f72..a26e8c027 100644 --- a/Module/StatusAbstract.php +++ b/Module/StatusAbstract.php @@ -46,8 +46,8 @@ abstract class StatusAbstract /** * Deactivate module. * - * @param ApplicationAbstract $app Application - * @param ModuleInfo $info Module info + * @param ApplicationAbstract $app Application + * @param ModuleInfo $info Module info * * @return void * @@ -176,8 +176,8 @@ abstract class StatusAbstract /** * Deactivate module. * - * @param ApplicationAbstract $app Application - * @param ModuleInfo $info Module info + * @param ApplicationAbstract $app Application + * @param ModuleInfo $info Module info * * @return void * diff --git a/Module/UninstallerAbstract.php b/Module/UninstallerAbstract.php index 41fc6a110..edb524530 100644 --- a/Module/UninstallerAbstract.php +++ b/Module/UninstallerAbstract.php @@ -40,8 +40,8 @@ abstract class UninstallerAbstract /** * Install module. * - * @param ApplicationAbstract $app Application - * @param ModuleInfo $info Module info + * @param ApplicationAbstract $app Application + * @param ModuleInfo $info Module info * * @return void * @@ -57,8 +57,8 @@ abstract class UninstallerAbstract /** * Activate after install. * - * @param ApplicationAbstract $app Application - * @param ModuleInfo $info Module info + * @param ApplicationAbstract $app Application + * @param ModuleInfo $info Module info * * @return void * diff --git a/System/SystemUtils.php b/System/SystemUtils.php index d6f1cf09f..9aafe2e96 100644 --- a/System/SystemUtils.php +++ b/System/SystemUtils.php @@ -147,6 +147,13 @@ final class SystemUtils return 'localhost.localdomain'; } + /** + * Execute a command + * + * @param string $executable Path or name of the executable + * @param string $cmd Command to execute + * @param bool $async Execute async + */ public static function runProc(string $executable, string $cmd, bool $async = false) : array { if (\strtolower((string) \substr(\PHP_OS, 0, 3)) === 'win') { diff --git a/Uri/Argument.php b/Uri/Argument.php index c3c0670e4..922b828d4 100644 --- a/Uri/Argument.php +++ b/Uri/Argument.php @@ -119,7 +119,7 @@ final class Argument implements UriInterface /** * Uri query. * - * @var array + * @var array * @since 1.0.0 */ private array $query = []; @@ -172,23 +172,17 @@ final class Argument implements UriInterface // Handle no path information only data $uriParts = \stripos($uriParts[0], '-') === 0 ? ['/', $uriParts[0]] : $uriParts; - $this->path = \array_shift($uriParts); + $this->path = \count($uriParts) === 0 ? '' : \array_shift($uriParts); $this->pathElements = \explode('/', \ltrim($this->path, '/')); - $path = \array_slice($this->pathElements, $this->pathOffset); + $path = \array_slice($this->pathElements, $this->pathOffset); $this->offsetPath = '/' . \implode('/', $path); $this->setQuery(\implode(' ', $uriParts)); } /** - * Set query from uri. - * - * @param string $uri Uri to parse - * - * @return void - * - * @since 1.0.0 + * {@inheritdoc} */ public function setQuery(string $uri) : void { @@ -250,7 +244,7 @@ final class Argument implements UriInterface { $this->pathOffset = $offset; - $path = \array_slice($this->pathElements, $this->pathOffset); + $path = \array_slice($this->pathElements, $this->pathOffset); $this->offsetPath = '/' . \implode('/', $path); } @@ -270,7 +264,7 @@ final class Argument implements UriInterface $this->path = $path; $this->pathElements = \explode('/', \ltrim($this->path, '/')); - $path = \array_slice($this->pathElements, $this->pathOffset); + $path = \array_slice($this->pathElements, $this->pathOffset); $this->offsetPath = '/' . \implode('/', $path); } diff --git a/Uri/HttpUri.php b/Uri/HttpUri.php index cba9dd6f0..bd0c4fde0 100644 --- a/Uri/HttpUri.php +++ b/Uri/HttpUri.php @@ -110,6 +110,14 @@ final class HttpUri implements UriInterface */ private string $path; + /** + * Uri path with offset. + * + * @var string + * @since 1.0.0 + */ + private string $offsetPath = ''; + /** * Uri query. * @@ -205,10 +213,10 @@ final class HttpUri implements UriInterface $this->pathElements = \explode('/', \trim($this->path, '/')); - $path = \array_slice($this->pathElements, $this->pathOffset); + $path = \array_slice($this->pathElements, $this->pathOffset); $this->offsetPath = '/' . \implode('/', $path); - $this->queryString = $url['query'] ?? ''; + $this->queryString = $url['query'] ?? ''; if (!empty($this->queryString)) { \parse_str($this->queryString, $this->query); @@ -283,7 +291,7 @@ final class HttpUri implements UriInterface { $this->pathOffset = $offset; - $path = \array_slice($this->pathElements, $this->pathOffset); + $path = \array_slice($this->pathElements, $this->pathOffset); $this->offsetPath = '/' . \implode('/', $path); } @@ -322,7 +330,7 @@ final class HttpUri implements UriInterface $this->path = $path; $this->pathElements = \explode('/', \ltrim($this->path, '/')); - $path = \array_slice($this->pathElements, $this->pathOffset); + $path = \array_slice($this->pathElements, $this->pathOffset); $this->offsetPath = '/' . \implode('/', $path); } @@ -363,6 +371,16 @@ final class HttpUri implements UriInterface return $this->queryString; } + /** + * {@inheritdoc} + */ + public function setQuery(string $uri) : void + { + \parse_str($uri, $this->query); + + $this->query = \array_change_key_case($this->query, \CASE_LOWER); + } + /** * {@inheritdoc} */ diff --git a/Uri/UriInterface.php b/Uri/UriInterface.php index f2fc2b470..56359a181 100644 --- a/Uri/UriInterface.php +++ b/Uri/UriInterface.php @@ -134,6 +134,17 @@ interface UriInterface */ public function getPathElements() : array; + /** + * Set query from uri. + * + * @param string $uri Uri to parse + * + * @return void + * + * @since 1.0.0 + */ + public function setQuery(string $uri) : void; + /** * Get query. * @@ -148,7 +159,7 @@ interface UriInterface /** * Get query array. * - * @return array + * @return string[] * * @since 1.0.0 */ diff --git a/Utils/ImageUtils.php b/Utils/ImageUtils.php index 32cecfe49..067aa5793 100644 --- a/Utils/ImageUtils.php +++ b/Utils/ImageUtils.php @@ -53,6 +53,15 @@ final class ImageUtils return (string) \base64_decode($img); } + /** + * Calculate the lightness from an RGB value as integer + * + * @param int $rgb RGB value represented as integer + * + * @return float + * + * @since 1.0.0 + */ public static function lightness(int $rgb) : float { $sR = ($rgb >> 16) & 0xFF; @@ -62,6 +71,17 @@ final class ImageUtils return self::lightnessFromRgb($sR, $sG, $sB); } + /** + * Calculate lightess from rgb values + * + * @param int $r Red + * @param int $g Green + * @param int $b Blue + * + * @return float + * + * @since 1.0.0 + */ public static function lightnessFromRgb(int $r, int $g, int $b) : float { $vR = $r / 255.0; diff --git a/Utils/NumericUtils.php b/Utils/NumericUtils.php index 64ba63ef4..695a4e7df 100755 --- a/Utils/NumericUtils.php +++ b/Utils/NumericUtils.php @@ -60,10 +60,10 @@ final class NumericUtils } if ($a < 0) { - $a = ($a >> 1); + $a = ($a >> 1); $a &= 0x7fffffff; $a |= 0x40000000; - $a = ($a >> ($b - 1)); + $a = ($a >> ($b - 1)); } else { $a = ($a >> $b); } diff --git a/Utils/Parser/Pdf/PdfParser.php b/Utils/Parser/Pdf/PdfParser.php index a73c5847b..6329680cf 100644 --- a/Utils/Parser/Pdf/PdfParser.php +++ b/Utils/Parser/Pdf/PdfParser.php @@ -39,34 +39,47 @@ class PdfParser */ public static function pdf2text(string $path) : string { - $text = ''; + $text = ''; $tmpDir = \sys_get_temp_dir(); + $out = \tempnam($tmpDir, 'pdf_'); + if ($out === false) { + return ''; + } + SystemUtils::runProc( '/usr/bin/pdftotext', '-layout ' . \escapeshellarg($path) . ' ' - . \escapeshellarg($out = \tempnam($tmpDir, 'pdf_')) + . \escapeshellarg($out) ); $text = \file_get_contents($out); \unlink($out); + if ($text === false) { + $text = ''; + } + if (\strlen($text) < 256) { + $out = \tempnam($tmpDir, 'pdf_'); + if ($out === false) { + return ''; + } + SystemUtils::runProc( '/usr/bin/pdftoppm', '-jpeg -r 300 ' . \escapeshellarg($path) . ' ' - . \escapeshellarg($out = \tempnam($tmpDir, 'pdf_')) + . \escapeshellarg($out) ); $files = \glob($out . '*'); if ($files === false) { - return $text; + return $text === false ? '' : $text; } foreach ($files as $file) { - if ( - !StringUtils::endsWith($file, '.jpg') + if (!StringUtils::endsWith($file, '.jpg') && !StringUtils::endsWith($file, '.png') && !StringUtils::endsWith($file, '.gif') ) { @@ -84,7 +97,7 @@ class PdfParser . \escapeshellarg($file) ); - $ocr = new TesseractOcr(); + $ocr = new TesseractOcr(); $text = $ocr->parseImage($file); \unlink($file); diff --git a/Utils/TaskSchedule/Cron.php b/Utils/TaskSchedule/Cron.php index b6b5e0fdb..157f659b0 100644 --- a/Utils/TaskSchedule/Cron.php +++ b/Utils/TaskSchedule/Cron.php @@ -31,6 +31,10 @@ class Cron extends SchedulerAbstract public function create(TaskAbstract $task) : void { $path = \tempnam(\sys_get_temp_dir(), 'cron_'); + if ($path === false) { + throw new \Exception(); + } + $this->run('-l > ' . $path); \file_put_contents($path, $task->__toString() . "\n", \FILE_APPEND); $this->run($path); @@ -43,6 +47,10 @@ class Cron extends SchedulerAbstract public function update(TaskAbstract $task) : void { $path = \tempnam(\sys_get_temp_dir(), 'cron_'); + if ($path === false) { + throw new \Exception(); + } + $this->run('-l > ' . $path); $new = ''; @@ -82,6 +90,10 @@ class Cron extends SchedulerAbstract public function deleteByName(string $name) : void { $path = \tempnam(\sys_get_temp_dir(), 'cron_'); + if ($path === false) { + throw new \Exception(); + } + $this->run('-l > ' . $path); $new = ''; @@ -113,6 +125,10 @@ class Cron extends SchedulerAbstract public function getAll() : array { $path = \tempnam(\sys_get_temp_dir(), 'cron_'); + if ($path === false) { + throw new \Exception(); + } + $this->run('-l > ' . $path); $jobs = []; @@ -152,6 +168,10 @@ class Cron extends SchedulerAbstract public function getAllByName(string $name, bool $exact = true) : array { $path = \tempnam(\sys_get_temp_dir(), 'cron_'); + if ($path === false) { + throw new \Exception(); + } + $this->run('-l > ' . $path); $jobs = []; diff --git a/Views/View.php b/Views/View.php index 4808e1b10..572482124 100644 --- a/Views/View.php +++ b/Views/View.php @@ -356,8 +356,20 @@ class View extends ViewAbstract return $this->l11nManager->getDateTime($this->l11n, $datetime, $format); } + /** + * Render user name based on format + * + * @param string $format Format used in printf + * @param array $names Names to render according to the format + * + * @return string + * + * @since 1.0.0 + */ public function renderUserName(string $format, array $names) : string { - return \trim(\preg_replace('/\s+/', ' ', \sprintf($format, ...$names)));; + $name = \preg_replace('/\s+/', ' ', \sprintf($format, ...$names)); + + return $name === null ? '' : \trim($name); } }