From 89c6ba3ac0f49d66e8bd25ea7179e8acaf8e3eea Mon Sep 17 00:00:00 2001 From: Dennis Eichhorn Date: Thu, 10 Oct 2019 12:00:54 +0200 Subject: [PATCH] continue phpcs fixes --- Algorithm/Knappsack/Item.php | 46 +++- Algorithm/PathFinding/AStar.php | 8 +- Algorithm/PathFinding/AStarNode.php | 128 +++++++++-- Algorithm/PathFinding/Grid.php | 60 ++++- Algorithm/PathFinding/JumpPointNode.php | 138 +++++++++++- Algorithm/PathFinding/JumpPointSearch.php | 128 ++++++++++- Algorithm/PathFinding/Path.php | 70 +++++- Algorithm/PathFinding/PathFinderInterface.php | 3 +- Algorithm/Sort/FlashSort.php | 30 +-- DataStorage/Database/Query/Count.php | 27 +++ Math/Geometry/Shape/D2/Polygon.php | 30 +++ Math/Geometry/Shape/D2/Quadrilateral.php | 27 ++- Math/Geometry/Shape/D3/Prism.php | 56 ++++- Math/Integral/Gauss.php | 20 -- Math/Matrix/EigenvalueDecomposition.php | 35 +++ Stdlib/Base/Heap.php | 196 ++++++++++++++-- Stdlib/Graph/Graph.php | 63 ++++++ System/File/Ftp/Directory.php | 3 + System/File/Ftp/File.php | 7 + System/File/Ftp/FtpStorage.php | 21 +- Utils/IO/Csv/CsvInterface.php | 63 +++--- Utils/IO/Csv/CsvSettings.php | 10 +- Utils/IO/Excel/ExcelDatabaseMapper.php | 211 +++++++++++++++++- Utils/IO/IODatabaseMapper.php | 41 +++- Views/PaginationView.php | 8 +- Views/TableView.php | 31 --- tests/Math/Integral/GaussTest.php | 26 --- 27 files changed, 1281 insertions(+), 205 deletions(-) delete mode 100644 Math/Integral/Gauss.php delete mode 100644 Views/TableView.php delete mode 100644 tests/Math/Integral/GaussTest.php diff --git a/Algorithm/Knappsack/Item.php b/Algorithm/Knappsack/Item.php index b25eff2d1..19d5c2cd7 100644 --- a/Algorithm/Knappsack/Item.php +++ b/Algorithm/Knappsack/Item.php @@ -15,7 +15,7 @@ declare(strict_types=1); namespace phpOMS\Algorithm\Knappsack; /** - * Matching a value with a set of coins + * Item in the knappsack * * @package phpOMS\Algorithm\Knappsack * @license OMS License 1.0 @@ -24,16 +24,56 @@ namespace phpOMS\Algorithm\Knappsack; */ class Item { + /** + * Value of the item + * + * @var float + * @since 1.0.0 + */ private $value = 0.0; + /** + * Cost of the item + * + * @var float + * @since 1.0.0 + */ private $cost = 0.0; - public function getValue() + /** + * Cosntructor. + * + * @param float $value Value of the item + * @param float $cost Cost of the item + * + * @since 1.0.0 + */ + public function __construct(float $value, float $cost) + { + $this->value = $value; + $this->cost = $cost; + } + + /** + * Get value of the item + * + * @return float + * + * @since 1.0.0 + */ + public function getValue() : float { return $this->value; } - public function getCost() + /** + * Get value of the item + * + * @return float + * + * @since 1.0.0 + */ + public function getCost() : float { return $this->cost; } diff --git a/Algorithm/PathFinding/AStar.php b/Algorithm/PathFinding/AStar.php index 698760f08..d81b6de5b 100644 --- a/Algorithm/PathFinding/AStar.php +++ b/Algorithm/PathFinding/AStar.php @@ -24,7 +24,7 @@ use phpOMS\Stdlib\Base\Heap; * @link https://orange-management.org * @since 1.0.0 */ -class JumpPointSearch implements PathFinderInterface +class AStar implements PathFinderInterface { /** * {@inheritdoc} @@ -48,9 +48,11 @@ class JumpPointSearch implements PathFinderInterface $startNode->setF(0.0); $startNode->setOpened(true); - $openList = new Heap(function(AStarNode $node1, AStarNode $node2) { return $node1->getF() - $node2->getF(); }); - $openList->push($startNode); + $openList = new Heap(function(AStarNode $node1, AStarNode $node2) { + return $node1->getF() - $node2->getF(); + }); + $openList->push($startNode); $node = null; while (!$openList->isEmpty()) { diff --git a/Algorithm/PathFinding/AStarNode.php b/Algorithm/PathFinding/AStarNode.php index 26eb9f6f8..5fba91752 100644 --- a/Algorithm/PathFinding/AStarNode.php +++ b/Algorithm/PathFinding/AStarNode.php @@ -24,71 +24,173 @@ namespace phpOMS\Algorithm\PathFinding; */ class AStarNode extends Node { + /** + * The g score is cost of the path + * + * @var float + * @since 1.0.0 + */ private float $g = 0.0; + + /** + * The heuristic distance is the cost to the end node + * + * @var float + * @since 1.0.0 + */ private ?float $h = null; + + /** + * The f score is defined as f(n) = g(n) + h(n) + * + * @var float + * @since 1.0.0 + */ private float $f = 0.0; + /** + * Define as checked node + * + * @var bool + * @since 1.0.0 + */ private bool $isClosed = false; - private bool $isOpened = false; - private bool $isTested = false; + /** + * Define as potential candidate + * + * @var bool + * @since 1.0.0 + */ + private bool $isOpened = false; + + /** + * Is checked? + * + * @return bool + * + * @since 1.0.0 + */ public function isClosed() : bool { return $this->isClosed; } + /** + * Is potential candidate + * + * @return bool + * + * @since 1.0.0 + */ public function isOpened() : bool { return $this->isOpened; } - public function isTested() : bool - { - return $this->isTested; - } - + /** + * Set check status + * + * @param bool $isClosed Is closed + * + * @return void + * + * @since 1.0.0 + */ public function setClosed(bool $isClosed) : void { $this->isClosed = $isClosed; } + /** + * Set potential candidate + * + * @param bool $isOpened Is potential candidate + * + * @return void + * + * @since 1.0.0 + */ public function setOpened(bool $isOpened) : void { $this->isOpened = $isOpened; } - public function setTested(bool $isTested) : void - { - $this->isTested = $isTested; - } - + /** + * Set the g score + * + * @param float $g G score + * + * @return void + * + * @since 1.0.0 + */ public function setG(float $g) : void { $this->g = $g; } + /** + * Set the heuristic distance + * + * @param float $h H distance + * + * @return void + * + * @since 1.0.0 + */ public function setH(?float $h) : void { $this->h = $h; } + /** + * Set the f score + * + * @param float $f F score + * + * @return void + * + * @since 1.0.0 + */ public function setF(float $f) : void { $this->f = $f; } + /** + * Get the g score + * + * @return float + * + * @since 1.0.0 + */ public function getG() : float { return $this->g; } + /** + * Get the heuristic distance + * + * @return float + * + * @since 1.0.0 + */ public function getH() : ?float { return $this->h; } + /** + * Get the f score + * + * @return float + * + * @since 1.0.0 + */ public function getF() : float { return $this->f; } -} \ No newline at end of file +} diff --git a/Algorithm/PathFinding/Grid.php b/Algorithm/PathFinding/Grid.php index f2f2b52de..e262efed8 100644 --- a/Algorithm/PathFinding/Grid.php +++ b/Algorithm/PathFinding/Grid.php @@ -24,8 +24,19 @@ namespace phpOMS\Algorithm\PathFinding; */ class Grid { + /** + * Grid system containing all nodes + * + * @var array + * @since 1.0.0 + */ private array $nodes = [[]]; + /** + * Create a grid from an array + * + * @param array $gridArray Grid defined in an array (0 = empty, 1 = start, 2 = end, 9 = not walkable) + */ public static function createGridFromArray(array $gridArray, string $node) : self { $grid = new self(); @@ -44,11 +55,32 @@ class Grid return $grid; } + /** + * Set node at position + * + * @param int $x X-Coordinate + * @param int $y Y-Coordinate + * @param Node $node Node to set + * + * @return void + * + * @since 1.0.0 + */ public function setNode(int $x, int $y, Node $node) : void { $this->nodes[$y][$x] = $node; } + /** + * Get node at position + * + * @param int $x X-Coordinate + * @param int $y Y-Coordinate + * + * @return null|Node + * + * @since 1.0.0 + */ public function getNode(int $x, int $y) : ?Node { if (!isset($this->nodes[$y]) || !isset($this->nodes[$y][$x])) { @@ -59,6 +91,16 @@ class Grid return $this->nodes[$y][$x]; } + /** + * Is node walkable" + * + * @param int $x X-Coordinate + * @param int $y Y-Coordinate + * + * @return bool + * + * @since 1.0.0 + */ public function isWalkable(int $x, int $y) : bool { if (!isset($this->nodes[$y]) || !isset($this->nodes[$y][$x]) || !$this->nodes[$y][$x]->isWalkable()) { @@ -68,6 +110,16 @@ class Grid return true; } + /** + * Get neighbors of node + * + * @param Node $node Node to get neighbors from + * @param int $movement Allowed movements + * + * @return array + * + * @since 1.0.0 + */ public function getNeighbors(Node $node, int $movement) : array { $x = $node->getX(); @@ -87,22 +139,22 @@ class Grid // todo: check $x and $y because original implementation is flipped!!! if ($this->isWalkable($x, $y - 1)) { $neighbors[] = $this->getNode($x, $y - 1); - $s0 = true; + $s0 = true; } if ($this->isWalkable($x + 1, $y)) { $neighbors[] = $this->getNode($x + 1, $y); - $s1 = true; + $s1 = true; } if ($this->isWalkable($x, $y + 1)) { $neighbors[] = $this->getNode($x, $y + 1); - $s2 = true; + $s2 = true; } if ($this->isWalkable($x - 1, $y)) { $neighbors[] = $this->getNode($x - 1, $y); - $s3 = true; + $s3 = true; } if ($movement === MovementType::STRAIGHT) { diff --git a/Algorithm/PathFinding/JumpPointNode.php b/Algorithm/PathFinding/JumpPointNode.php index 718d30f9e..205b07e27 100644 --- a/Algorithm/PathFinding/JumpPointNode.php +++ b/Algorithm/PathFinding/JumpPointNode.php @@ -24,71 +24,207 @@ namespace phpOMS\Algorithm\PathFinding; */ class JumpPointNode extends Node { + /** + * The g score is cost of the path + * + * @var float + * @since 1.0.0 + */ private float $g = 0.0; + + /** + * The heuristic distance is the cost to the end node + * + * @var float + * @since 1.0.0 + */ private ?float $h = null; + + /** + * The f score is defined as f(n) = g(n) + h(n) + * + * @var float + * @since 1.0.0 + */ private float $f = 0.0; + /** + * Define as checked node + * + * @var bool + * @since 1.0.0 + */ private bool $isClosed = false; + + /** + * Define as potential candidate + * + * @var bool + * @since 1.0.0 + */ private bool $isOpened = false; + + /** + * The node was already tested? + * + * @var bool + * @since 1.0.0 + */ private bool $isTested = false; + /** + * Is checked? + * + * @return bool + * + * @since 1.0.0 + */ public function isClosed() : bool { return $this->isClosed; } + /** + * Is potential candidate + * + * @return bool + * + * @since 1.0.0 + */ public function isOpened() : bool { return $this->isOpened; } + /** + * Is already tested + * + * @return bool + * + * @since 1.0.0 + */ public function isTested() : bool { return $this->isTested; } + /** + * Set check status + * + * @param bool $isClosed Is closed + * + * @return void + * + * @since 1.0.0 + */ public function setClosed(bool $isClosed) : void { $this->isClosed = $isClosed; } + /** + * Set potential candidate + * + * @param bool $isOpened Is potential candidate + * + * @return void + * + * @since 1.0.0 + */ public function setOpened(bool $isOpened) : void { $this->isOpened = $isOpened; } + /** + * Set tested + * + * @param bool $isTested Node tested? + * + * @return void + * + * @since 1.0.0 + */ public function setTested(bool $isTested) : void { $this->isTested = $isTested; } + /** + * Set the g score + * + * @param float $g G score + * + * @return void + * + * @since 1.0.0 + */ public function setG(float $g) : void { $this->g = $g; } + /** + * Set the heuristic distance + * + * @param float $h H distance + * + * @return void + * + * @since 1.0.0 + */ public function setH(?float $h) : void { $this->h = $h; } + /** + * Set the f score + * + * @param float $f F score + * + * @return void + * + * @since 1.0.0 + */ public function setF(float $f) : void { $this->f = $f; } + /** + * Get the g score + * + * @return float + * + * @since 1.0.0 + */ public function getG() : float { return $this->g; } + /** + * Get the heuristic distance + * + * @return float + * + * @since 1.0.0 + */ public function getH() : ?float { return $this->h; } + /** + * Get the f score + * + * @return float + * + * @since 1.0.0 + */ public function getF() : float { return $this->f; } -} \ No newline at end of file +} diff --git a/Algorithm/PathFinding/JumpPointSearch.php b/Algorithm/PathFinding/JumpPointSearch.php index 405475b6b..06ce18a2f 100644 --- a/Algorithm/PathFinding/JumpPointSearch.php +++ b/Algorithm/PathFinding/JumpPointSearch.php @@ -48,7 +48,10 @@ class JumpPointSearch implements PathFinderInterface $startNode->setF(0.0); $startNode->setOpened(true); - $openList = new Heap(function($node1, $node2) { return $node1->getF() - $node2->getF(); }); + $openList = new Heap(function($node1, $node2) { + return $node1->getF() - $node2->getF(); + }); + $openList->push($startNode); $node = null; @@ -73,6 +76,20 @@ class JumpPointSearch implements PathFinderInterface return $path; } + /** + * Find possible successor jump points + * + * @param JumpPointNode $node Node to find successor for + * @param Grid $grid Grid of the nodes + * @param int $heuristic Heuristic/metrics type for the distance calculation + * @param int $movement Movement type + * @param JumpPointNode $endNode End node to find path to + * @param Heap $openList Heap of open nodes + * + * @return Heap + * + * @since 1.0.0 + */ public static function identifySuccessors(JumpPointNode $node, Grid $grid, int $heuristic, int $movement, JumpPointNode $endNode, Heap $openList) : Heap { $neighbors = self::findNeighbors($node, $movement, $grid); @@ -107,6 +124,17 @@ class JumpPointSearch implements PathFinderInterface return $openList; } + /** + * Find neighbor of node + * + * @param JumpPointNode $node Node to find successor for + * @param int $movement Movement type + * @param Grid $grid Grid of the nodes + * + * @return array Neighbors of node + * + * @since 1.0.0 + */ private static function findNeighbors(JumpPointNode $node, int $movement, Grid $grid) : array { if ($movement === MovementType::STRAIGHT) { @@ -120,6 +148,16 @@ class JumpPointSearch implements PathFinderInterface return self::findNeighborsDiagonalNoObstacle($node, $grid); } + /** + * Find neighbor of node + * + * @param JumpPointNode $node Node to find successor for + * @param Grid $grid Grid of the nodes + * + * @return array Neighbors of node + * + * @since 1.0.0 + */ private static function findNeighborsStraight(JumpPointNode $node, Grid $grid) : array { if ($node->getParent() === null) { @@ -167,6 +205,16 @@ class JumpPointSearch implements PathFinderInterface return $neighbors; } + /** + * Find neighbor of node + * + * @param JumpPointNode $node Node to find successor for + * @param Grid $grid Grid of the nodes + * + * @return array Neighbors of node + * + * @since 1.0.0 + */ private static function findNeighborsDiagonal(JumpPointNode $node, Grid $grid) : array { if ($node->getParent() === null) { @@ -234,6 +282,16 @@ class JumpPointSearch implements PathFinderInterface return $neighbors; } + /** + * Find neighbor of node + * + * @param JumpPointNode $node Node to find successor for + * @param Grid $grid Grid of the nodes + * + * @return array Neighbors of node + * + * @since 1.0.0 + */ private static function findNeighborsDiagonalOneObstacle(JumpPointNode $node, Grid $grid) : array { if ($node->getParent() === null) { @@ -297,6 +355,16 @@ class JumpPointSearch implements PathFinderInterface return $neighbors; } + /** + * Find neighbor of node + * + * @param JumpPointNode $node Node to find successor for + * @param Grid $grid Grid of the nodes + * + * @return array Neighbors of node + * + * @since 1.0.0 + */ private static function findNeighborsDiagonalNoObstacle(JumpPointNode $node, Grid $grid) : array { if ($node->getParent() === null) { @@ -378,6 +446,18 @@ class JumpPointSearch implements PathFinderInterface return $neighbors; } + /** + * Find next jump point + * + * @param JumpPointNode $node Node to find jump point from + * @param JumpPointNode $endNode End node to find path to + * @param int $movement Movement type + * @param Grid $grid Grid of the nodes + * + * @return null|JumpPointNode + * + * @since 1.0.0 + */ private static function jump(JumpPointNode $node, JumpPointNode $endNode, int $movement, Grid $grid) : ?JumpPointNode { if ($movement === MovementType::STRAIGHT) { @@ -391,6 +471,17 @@ class JumpPointSearch implements PathFinderInterface return self::jumpDiagonalNoObstacle($node, $endNode, $grid); } + /** + * Find next jump point + * + * @param JumpPointNode $node Node to find jump point from + * @param JumpPointNode $endNode End node to find path to + * @param Grid $grid Grid of the nodes + * + * @return null|JumpPointNode + * + * @since 1.0.0 + */ private static function jumpStraight(JumpPointNode $node, JumpPointNode $endNode, Grid $grid) : ?JumpPointNode { $x = $node->getX(); @@ -435,6 +526,17 @@ class JumpPointSearch implements PathFinderInterface return self::jumpStraight($grid->getNode($x + $dx, $y + $dy), $node, $grid); } + /** + * Find next jump point + * + * @param JumpPointNode $node Node to find jump point from + * @param JumpPointNode $endNode End node to find path to + * @param Grid $grid Grid of the nodes + * + * @return null|JumpPointNode + * + * @since 1.0.0 + */ private static function jumpDiagonal(JumpPointNode $node, JumpPointNode $endNode, Grid $grid) : ?JumpPointNode { $x = $node->getX(); @@ -483,6 +585,17 @@ class JumpPointSearch implements PathFinderInterface return self::jumpDiagonal($grid->getNode($x + $dx, $y + $dy), $node, $grid); } + /** + * Find next jump point + * + * @param JumpPointNode $node Node to find jump point from + * @param JumpPointNode $endNode End node to find path to + * @param Grid $grid Grid of the nodes + * + * @return null|JumpPointNode + * + * @since 1.0.0 + */ private static function jumpDiagonalOneObstacle(JumpPointNode $node, JumpPointNode $endNode, Grid $grid) : ?JumpPointNode { $x = $node->getX(); @@ -535,6 +648,17 @@ class JumpPointSearch implements PathFinderInterface return null; } + /** + * Find next jump point + * + * @param JumpPointNode $node Node to find jump point from + * @param JumpPointNode $endNode End node to find path to + * @param Grid $grid Grid of the nodes + * + * @return null|JumpPointNode + * + * @since 1.0.0 + */ private static function jumpDiagonalNoObstacle(JumpPointNode $node, JumpPointNode $endNode, Grid $grid) : ?JumpPointNode { $x = $node->getX(); @@ -580,4 +704,4 @@ class JumpPointSearch implements PathFinderInterface return null; } -} \ No newline at end of file +} diff --git a/Algorithm/PathFinding/Path.php b/Algorithm/PathFinding/Path.php index 06cec0afa..4978dfa65 100644 --- a/Algorithm/PathFinding/Path.php +++ b/Algorithm/PathFinding/Path.php @@ -24,21 +24,74 @@ namespace phpOMS\Algorithm\PathFinding; */ class Path { + /** + * Nodes in the path + * + * @var Nodes[] + * @since 1.0.0 + */ public array $nodes = []; + + /** + * Weight/cost of the total path + * + * @var float + * @since 1.0.0 + */ private float $weight = 0.0; + + /** + * Distance of the total path + * + * @var float + * @since 1.0.0 + */ private float $distance = 0.0; + + /** + * Grid this path belongs to + * + * @var Grid + * @since 1.0.0 + */ private Grid $grid; + /** + * Cosntructor. + * + * @param Grid $grid Grid this path belongs to + * + * @since 1.0.0 + */ public function __construct(Grid $grid) { $this->grid = $grid; } + /** + * Add node to the path + * + * @param Node $node Node + * + * @return void + * + * @since 1.0.0 + */ public function addNode(Node $node) : void { $this->nodes[] = $node; } + /** + * Fill all nodes in bettween + * + * The path may only contain the jump points or pivot points. + * In order to get every node it needs to be expanded. + * + * @return array + * + * @since 1.0.0 + */ public function expandPath() : array { $reverse = \array_reverse($this->nodes); @@ -64,6 +117,19 @@ class Path return $expanded; } + /** + * Find nodes in bettween two nodes. + * + * The path may only contain the jump points or pivot points. + * In order to get every node it needs to be expanded. + * + * @param Node $node1 Node + * @param Node $node2 Node + * + * @return array + * + * @since 1.0.0 + */ private function interpolate(Node $node1, Node $node2) : array { $dx = \abs($node2->getX() - $node1->getX()); @@ -88,13 +154,13 @@ class Path if ($e2 > -$dy) { $err -= $dy; - $x0 = $node->getX() + $sx; + $x0 = $node->getX() + $sx; } $y0 = 0; if ($e2 < $dx) { $err += $dx; - $y0 = $node->getY() + $sy; + $y0 = $node->getY() + $sy; } $node = $this->grid->getNode($x0, $y0); diff --git a/Algorithm/PathFinding/PathFinderInterface.php b/Algorithm/PathFinding/PathFinderInterface.php index bf5e993a6..99651570e 100644 --- a/Algorithm/PathFinding/PathFinderInterface.php +++ b/Algorithm/PathFinding/PathFinderInterface.php @@ -22,7 +22,8 @@ namespace phpOMS\Algorithm\PathFinding; * @link https://orange-management.org * @since 1.0.0 */ -interface PathFinderInterface { +interface PathFinderInterface +{ /** * Find path from one point to another * diff --git a/Algorithm/Sort/FlashSort.php b/Algorithm/Sort/FlashSort.php index 3ed91e00b..0d61968dd 100644 --- a/Algorithm/Sort/FlashSort.php +++ b/Algorithm/Sort/FlashSort.php @@ -14,6 +14,8 @@ declare(strict_types=1); namespace phpOMS\Algorithm\Sort; +use phpOMS\Utils\NumericUtils; + /** * FlashSort class. * @@ -51,32 +53,32 @@ class FlashSort implements SortInterface // todo: replace >>> with Numeric::uRightShift - for ($i = 0; (($i += 2) - $n) >>> 31;) { - if ((($kmax = $list[$i - 1])->getValue() - ($kmin = $list[$i])->getValue()) >>> 31) { - if (($kmax->getValue() - $anmin->getValue()) >>> 31) { + for ($i = 0; NumericUtils::uRightShift(($i += 2) - $n, 31);) { + if (NumericUtils::uRightShift(($kmax = $list[$i - 1])->getValue() - ($kmin = $list[$i])->getValue(), 31)) { + if (NumericUtils::uRightShift($kmax->getValue() - $anmin->getValue(), 31)) { $anmin = $list[$i - 1]; } - if (($anmax->getValue() - $kmin->getValue()) >>> 31) { + if (NumericUtils::uRightShift($anmax->getValue() - $kmin->getValue(), 31)) { $anmax = $list[$i]; $nmax = $i; } } else { - if (($kmin->getValue() - $anmin->getValue()) >>> 31) { + if (NumericUtils::uRightShift($kmin->getValue() - $anmin->getValue(), 31)) { $anmin = $list[$i]; } - if (($anmax->getValue() - $kmin->getValue()) >>> 31) { + if (NumericUtils::uRightShift($anmax->getValue() - $kmin->getValue(), 31)) { $anmax = $list[$i - 1]; $nmax = $i - 1; } } } - if ((--$i - $n) >>> 31) { - if ((($k = $list[$i])->getValue() - $anmin->getValue()) >>> 31) { + if (NumericUtils::uRightShift(--$i - $n, 31)) { + if (NumericUtils::uRightShift(($k = $list[$i])->getValue() - $anmin->getValue(), 31)) { $anmin = $list[$i]; - } elseif (($anmax->getValue() - $k->getValue()) >>> 31) { + } elseif (NumericUtils::uRightShift($anmax->getValue() - $k->getValue(), 31)) { $anmax = $list[$i]; $nmax = $i; } @@ -88,12 +90,12 @@ class FlashSort implements SortInterface $c1 = (($m - 1) << 13) / ($anmax->getValue() - $anmin->getValue()); - for ($i = -1; (++$i - $n) >>> 31;) { + for ($i = -1; NumericUtils::uRightShift(++$i - $n, 31);) { ++$l[($c1 * ($list[$i]->getValue() - $anmin->getValue())) >> 13]; } $lk = $l[0]; - for ($k = 0; (++$k - $m) >>> 31;) { + for ($k = 0; NumericUtils::uRightShift(++$k - $m, 31);) { $lk = ($l[$k] += $lk); } @@ -106,7 +108,7 @@ class FlashSort implements SortInterface $k = ($m - 1); $i = ($n - 1); - while (($nmove - $i) >>> 31) { + while (NumericUtils::uRightShift($nmove - $i, 31)) { while ($j !== $lk) { $k = ($c1 * ($list[(++$j)]->getValue() - $anmin->getValue())) >> 13; } @@ -114,7 +116,9 @@ class FlashSort implements SortInterface $flash = $a[$j]; $lk = $l[$k]; - while ($j !== $lk) + while ($j !== $lk) { + + } } } } diff --git a/DataStorage/Database/Query/Count.php b/DataStorage/Database/Query/Count.php index e69de29bb..a41545c37 100644 --- a/DataStorage/Database/Query/Count.php +++ b/DataStorage/Database/Query/Count.php @@ -0,0 +1,27 @@ +isSymmetric; } + /** + * Get V matrix + * + * @return Matrix + * + * @since 1.0.0 + */ public function getV() : Matrix { $matrix = new Matrix(); @@ -872,6 +886,13 @@ final class EigenvalueDecomposition return $matrix; } + /** + * Get real eigenvalues + * + * @return Vector + * + * @since 1.0.0 + */ public function getRealEigenvalues() : Vector { $vector = new Vector(); @@ -880,6 +901,13 @@ final class EigenvalueDecomposition return $vector; } + /** + * Get imaginary eigenvalues + * + * @return Vector + * + * @since 1.0.0 + */ public function getImagEigenvalues() : Vector { $vector = new Vector(); @@ -888,6 +916,13 @@ final class EigenvalueDecomposition return $vector; } + /** + * Get D matrix + * + * @return Matrix + * + * @since 1.0.0 + */ public function getD() : Matrix { $matrix = new Matrix(); diff --git a/Stdlib/Base/Heap.php b/Stdlib/Base/Heap.php index 3e2e8b421..4923b09aa 100644 --- a/Stdlib/Base/Heap.php +++ b/Stdlib/Base/Heap.php @@ -24,27 +24,52 @@ namespace phpOMS\Stdlib\Base; */ class Heap { + /** + * Comparison function + * + * @var \Closure + * @since 1.0.0 + */ private \Closure $compare; /** - * Heap elements + * Heap items * * @var array * @since 1.0.0 */ private array $nodes = []; + /** + * Constructor. + * + * @param null|\Closure $compare Compare function + * + * @since 1.0.0 + */ public function __construct(\Closure $compare = null) { - $this->compare = $compare ?? function($a, $b) { return $a <=> $b; }; + $this->compare = $compare ?? function($a, $b) { + return $a <=> $b; + }; } - public function insort($x, $lo = 0) : void + /** + * Insert item into sorted heap at correct position + * + * @param mixed $x Element to insert + * @param int $lo Lower bound + * + * @return void + * + * @since 1.0.0 + */ + public function insort($x, int $lo = 0) : void { $hi = \count($this->nodes); while ($lo < $hi) { - $mid = (int) \floor(($lo + $hi) / 2); + $mid = (int) (($lo + $hi) / 2); if (($this->compare)($x, $this->nodes[$mid]) < 0) { $hi = $mid; } else { @@ -55,12 +80,28 @@ class Heap $this->nodes = \array_splice($this->nodes, $lo, 0, $x); } + /** + * Push item onto the heap + * + * @param mixed $item Item to add to the heap + * + * @return void; + * + * @since 1.0.0 + */ public function push($item) : void { $this->nodes[] = $item; $this->siftDown(0, \count($this->nodes) - 1); } + /** + * Pop the smallest item off the heap + * + * @return mixed + * + * @since 1.0.0 + */ public function pop() { $last = \array_pop($this->nodes); @@ -68,18 +109,34 @@ class Heap return $last; } - $item = $this->nodes[0]; + $item = $this->nodes[0]; $this->nodes[0] = $last; $this->siftUp(0); return $item; } + /** + * Get first item without popping + * + * @return mixed + * + * @since 1.0.0 + */ public function peek() { return $this->nodes[0]; } + /** + * Contains item? + * + * @param mixed $item Item to check + * + * @return bool + * + * @since 1.0.0 + */ public function contains($item) : bool { foreach ($this->nodes as $key => $node) { @@ -97,20 +154,38 @@ class Heap return false; } + /** + * Pop a item and push a new one (replace with a new one) + * + * @param mixed $new New item + * + * @return mixed popped item + * + * @since 1.0.0 + */ public function replace($new) { - $old = $this->nodes[0]; + $old = $this->nodes[0]; $this->nodes[0] = $new; $this->siftUp(0); return $old; } + /** + * Push item and pop one + * + * @param mixed $item New item + * + * @return mixed popped item + * + * @since 1.0.0 + */ public function pushpop($item) { if (!empty($this->nodes) && ($this->compare)($this->nodes[0], $item) < 0) { - $temp = $item; - $item = $this->nodes[0]; + $temp = $item; + $item = $this->nodes[0]; $this->nodes[0] = $temp; $this->siftUp(0); } @@ -118,13 +193,35 @@ class Heap return $item; } - public function heapify() : void + /** + * Turn list into heap + * + * @param array $list Item list + * + * @return void + * + * @since 1.0.0 + */ + public function heapify(array $list) : void { - for ($i = (int) \floor(\count($this->nodes) / 2); $i > -1; --$i) { + $this->nodes = $list; + + for ($i = (int) (\count($this->nodes) / 2); $i > -1; --$i) { $this->siftUp($i); } } + /** + * Update the position of a item + * + * This is called after changing an item + * + * @param mixed $item Item to update + * + * @return bool + * + * @since 1.0.0 + */ public function update($item) : bool { $pos = null; @@ -152,32 +249,56 @@ class Heap return true; } + /** + * Get n largest items + * + * @param int $n Number of items + * + * @return array + * + * @since 1.0.0 + */ public function getNLargest(int $n) : array { $nodes = $this->nodes; - \uasort($nodes, $this->compare); - return \array_slice(\array_reverse($nodes), 0, $n); } + /** + * Get n smalles items + * + * @param int $n Number of items + * + * @return array + * + * @since 1.0.0 + */ public function getNSmallest(int $n): array { $nodes = $this->nodes; - \uasort($nodes, $this->compare); - return \array_slice($nodes, 0, $n); } + /** + * Down shift + * + * @param int $start Start index + * @param int $pos Pos of the pivot item + * + * @return void + * + * @since 1.0.0 + */ private function siftDown(int $start, int $pos) : void { $item = $this->nodes[$pos]; while ($pos > $start) { - $pPos = ($pos - 1) >> 1; + $pPos = ($pos - 1) >> 1; $parent = $this->nodes[$pPos]; if (($this->compare)($item, $parent) < 0) { $this->nodes[$pos] = $parent; - $pos = $pPos; + $pos = $pPos; continue; } @@ -188,6 +309,15 @@ class Heap $this->nodes[$pos] = $item; } + /** + * Up shift + * + * @param int $pos Pos of the pivot item + * + * @return void + * + * @since 1.0.0 + */ private function siftUp(int $pos) : void { $ePos = \count($this->nodes); @@ -203,30 +333,58 @@ class Heap } $this->nodes[$pos] = $this->nodes[$cPos]; - $pos = $cPos; - $cPos = 2 * $pos + 1; + $pos = $cPos; + $cPos = 2 * $pos + 1; } $this->nodes[$pos] = $item; $this->siftDown($sPos, $pos); } + /** + * Clear heap + * + * @return void + * + * @since 1.0.0 + */ public function clear() : void { $this->nodes = []; } + /** + * Is heap empty? + * + * @return bool + * + * @since 1.0.0 + */ public function isEmpty() : bool { return empty($this->nodes); } + /** + * Get heap size + * + * @return int + * + * @since 1.0.0 + */ public function size() : int { return \count($this->nodes); } - public function toArray() + /** + * Get heap array + * + * @return array + * + * @since 1.0.0 + */ + public function toArray() : array { return $this->nodes; } diff --git a/Stdlib/Graph/Graph.php b/Stdlib/Graph/Graph.php index 4de1ba88f..5293e6353 100644 --- a/Stdlib/Graph/Graph.php +++ b/Stdlib/Graph/Graph.php @@ -436,32 +436,74 @@ class Graph return $diameter; } + /** + * Get the graph girth + * + * @return int + * + * @since 1.0.0 + */ public function getGirth() : int { return 0; } + /** + * Get the graph circuit rank + * + * @return int + * + * @since 1.0.0 + */ public function getCircuitRank() : int { return 0; } + /** + * Get the graph node connectivity + * + * @return int + * + * @since 1.0.0 + */ public function getNodeConnectivity() : int { return 0; } + /** + * Get the graph edge connectivity + * + * @return int + * + * @since 1.0.0 + */ public function getEdgeConnectivity() : int { return 0; } + /** + * Is the graph connected? + * + * @return bool + * + * @since 1.0.0 + */ public function isConnected() : bool { // todo: implement return true; } + /** + * Get unconnected sub graphs + * + * @return Graph[] + * + * @since 1.0.0 + */ public function getUnconnected() : array { // todo: implement @@ -470,18 +512,39 @@ class Graph return []; } + /** + * Is the graph bipartite? + * + * @return bool + * + * @since 1.0.0 + */ public function isBipartite() : bool { // todo: implement return true; } + /** + * Is the graph triangle? + * + * @return bool + * + * @since 1.0.0 + */ public function isTriangleFree() : bool { // todo: implement return true; } + /** + * Is the graph circle free? + * + * @return bool + * + * @since 1.0.0 + */ public function isCircleFree() : bool { // todo: implement diff --git a/System/File/Ftp/Directory.php b/System/File/Ftp/Directory.php index 0780861f1..c1ebf3eec 100644 --- a/System/File/Ftp/Directory.php +++ b/System/File/Ftp/Directory.php @@ -518,6 +518,9 @@ class Directory extends FileAbstract implements FtpContainerInterface, Directory // todo: add node } + /** + * {@inheritdoc} + */ public function addNode($file) : bool { $this->count += $file->getCount(); diff --git a/System/File/Ftp/File.php b/System/File/Ftp/File.php index 29c17b879..ea62d594f 100644 --- a/System/File/Ftp/File.php +++ b/System/File/Ftp/File.php @@ -52,6 +52,13 @@ class File extends FileAbstract implements FileInterface */ private ?Http $uri = null; + /** + * Create ftp connection + * + * @param string $path Ftp path including username and password + * + * @since 1.0.0 + */ public function __construct(string $path) { $this->uri = new Http($path); diff --git a/System/File/Ftp/FtpStorage.php b/System/File/Ftp/FtpStorage.php index fb7343dd9..561688b57 100644 --- a/System/File/Ftp/FtpStorage.php +++ b/System/File/Ftp/FtpStorage.php @@ -30,13 +30,21 @@ use phpOMS\System\File\StorageAbstract; */ class FtpStorage extends StorageAbstract { + /** + * Storage instance. + * + * @var FtpStorage + * @since 1.0.0 + */ private static ?self $instance = null; - public function __construct() - { - - } - + /** + * Get instance. + * + * @return FtpStorage + * + * @since 1.0.0 + */ public static function getInstance() : StorageAbstract { if (self::$instance === null) { @@ -46,6 +54,9 @@ class FtpStorage extends StorageAbstract return self::$instance; } + /** + * {@inheritdoc} + */ protected static function getClassType(string $path) : string { return \is_dir($path) || (!\is_file($path) && \stripos($path, '.') === false) ? Directory::class : File::class; diff --git a/Utils/IO/Csv/CsvInterface.php b/Utils/IO/Csv/CsvInterface.php index 3613cd190..11f0faf65 100644 --- a/Utils/IO/Csv/CsvInterface.php +++ b/Utils/IO/Csv/CsvInterface.php @@ -4,7 +4,7 @@ * * PHP Version 7.4 * - * @package TBD + * @package phpOMS\Utils\IO\Csv * @copyright Dennis Eichhorn * @license OMS License 1.0 * @version 1.0.0 @@ -12,42 +12,37 @@ */ declare(strict_types=1); -namespace phpOMS\Utils\IO\Csv { +namespace phpOMS\Utils\IO\Csv; + +/** + * Cvs interface. + * + * @package phpOMS\Utils\IO\Csv + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ +interface CsvInterface +{ + /** + * Export Csv. + * + * @param string $path Path to export + * + * @since 1.0.0 + * @author Dennis Eichhorn + */ + public function exportCsv($path); /** - * Cvs interface. + * Import Csv. * - * PHP Version 7.4 + * @param string $path Path to import * - * @package Framework - * @copyright Dennis Eichhorn - * @license OMS License 1.0 - * @version 1.0.0 - * @link https://orange-management.org - * @since 1.0.0 + * @return void + * + * @since 1.0.0 + * @author Dennis Eichhorn */ - interface CsvInterface - { - /** - * Export Csv. - * - * @param string $path Path to export - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function exportCsv($path); - - /** - * Import Csv. - * - * @param string $path Path to import - * - * @return void - * - * @since 1.0.0 - * @author Dennis Eichhorn - */ - public function importCsv($path) : void; - } + public function importCsv($path) : void; } diff --git a/Utils/IO/Csv/CsvSettings.php b/Utils/IO/Csv/CsvSettings.php index 9eb65b468..b2e1bc604 100644 --- a/Utils/IO/Csv/CsvSettings.php +++ b/Utils/IO/Csv/CsvSettings.php @@ -15,15 +15,17 @@ declare(strict_types=1); namespace phpOMS\Utils\IO\Csv; /** - * Options trait. + * Csv settings. * - * @package phpOMS\Utils\IO\Csv - * @since 1.0.0 + * @package phpOMS\Utils\IO\Csv + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 */ class CsvSettings { /** - * Get csv file delimiter. + * Get csv file delimiter based on file content. * * @param mixed $file File resource * @param int $checkLines Lines to check for evaluation diff --git a/Utils/IO/Excel/ExcelDatabaseMapper.php b/Utils/IO/Excel/ExcelDatabaseMapper.php index 580423612..aa6dda24e 100644 --- a/Utils/IO/Excel/ExcelDatabaseMapper.php +++ b/Utils/IO/Excel/ExcelDatabaseMapper.php @@ -4,7 +4,7 @@ * * PHP Version 7.4 * - * @package TBD + * @package phpOMS\Utils\IO\Excel * @copyright Dennis Eichhorn * @license OMS License 1.0 * @version 1.0.0 @@ -14,30 +14,217 @@ declare(strict_types=1); namespace phpOMS\Utils\IO\Excel; +use phpOMS\DataStorage\Database\Connection\ConnectionAbstract; +use phpOMS\DataStorage\Database\Query\Builder; use phpOMS\Utils\IO\IODatabaseMapper; +use phpOMS\Utils\StringUtils; +/** + * Excel database mapper. + * + * @package phpOMS\Utils\IO\Excel + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ class ExcelDatabaseMapper implements IODatabaseMapper { - private $sources = []; + /** + * Database connection + * + * @var ConnectionAbstract + * @since 1.0.0 + */ + private ConnectionAbstract $con; - private $lineBuffer = 500; + /** + * Path to source or destination + * + * @var string + * @since 1.0.0 + */ + private string $path = ''; - public function addSource(string $source) : void + /** + * Constructor. + * + * @param ConnectionAbstract $con Database connection + * + * @since 1.0.0 + */ + public function __construct(ConnectionAbstract $con) { - $this->sources[] = $source; + $this->con = $con; } - public function setLineBuffer(int $buffer) : void + /** + * Add path + * + * This is the path of the source data in case of inserting/updating data or the destination file for selecting data. + * + * @param string $path File path + * + * @return void + * + * @since 1.0.0 + */ + public function setPath(string $path) : void { - $this->lineBuffer = $buffer; - } - - public function setSources(array $sources) : void - { - $this->sources = $sources; + $this->path = $path; } + /** + * {@inheritdoc} + */ public function insert() : void { + $reader = null; + if (StringUtils::endsWith($this->path, '.xlsx')) { + $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx(); + } elseif (StringUtils::endsWith($this->path, '.ods')) { + $sheet = new \PhpOffice\PhpSpreadsheet\Reader\Ods(); + } else { + $sheet = new \PhpOffice\PhpSpreadsheet\Reader\Xls(); + } + + $reader->setReadDataOnly(true); + $sheet = $reader->load($this->path); + + $tables = $sheet->getSheetCount(); + for ($i = 0; $i < $tables; ++$i) { + $sheet->setActiveSheetIndex($i); + + $workSheet = $sheet->getSheet($i); + $table = $workSheet->getTitle(); + $titles = []; + + // get column titles + $column = 1; + while (!empty($value = $workSheet->getCellByColmnAndRow($column, 1)->getValue())) { + $titles[] = $value; + } + + $columns = \count($titles); + + // insert data + $query = new Builder($this->con); + $query->insert(...$titles)->into($table); + + $line = 2; + while (!empty($row = $workSheet->getCellByColumnAndRow(1, $line)->getValue())) { + $cells = []; + for ($j = 1; $j <= $columns; ++$j) { + $cells[] = $workSheet->getCellByColumnAndRow(j, $line)->getValue(); + } + + $query->values(...$cells); + } + + $query->execute(); + } + } + + /** + * {@inheritdoc} + */ + public function select(array $queries) : void + { + $sheet = new Spreadsheet(); + $sheet->getProperties() + ->setCreator('Orange-Management') + ->setLastModifiedBy('Orange-Management') + ->setTitle('Database export') + ->setSubject('Database export') + ->setDescription('This document is automatically generated from a database export.'); + + $sheetCount = $sheet->getSheetCount(); + + foreach ($queries as $key => $query) { + $results = $query->execute()->fetchAll(\PDO::FETCH_ASSOC); + + if ($key > $sheetCount - 1) { + $sheet->createSheet($key); + } + + $workSheet = $sheet->setActiveSheetIndex($key); + $rows = \count($results); + + if ($rows < 1) { + break; + } + + $colCount = \count($results[0]); + $columns = \array_keys($results[0]); + + // set column titles + for ($i = 1; $i <= $colCount; ++$i) { + $workSheet->setCellValueByColumnAndRow($i, 1, $columns[0][$i - 1]); + } + + // set data + foreach ($results as $key => $result) { + for ($i = 1; $i <= $colCount; ++$i) { + $workSheet->setCellValueByColumnAndRow($i, $key + 1, $result[$i - 1]); + } + } + } + + if (StringUtils::endsWith($this->path, '.xlsx')) { + (new \PhpOffice\PhpSpreadsheet\Writer\Xlsx())->save($this->path); + } elseif (StringUtils::endsWith($this->path, '.ods')) { + (new \PhpOffice\PhpSpreadsheet\Writer\Ods())->save($this->path); + } else { + (new \PhpOffice\PhpSpreadsheet\Writer\Xls())->save($this->path); + } + } + + /** + * {@inheritdoc} + */ + public function update() : void + { + $reader = null; + if (StringUtils::endsWith($this->path, '.xlsx')) { + $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx(); + } elseif (StringUtils::endsWith($this->path, '.ods')) { + $sheet = new \PhpOffice\PhpSpreadsheet\Reader\Ods(); + } else { + $sheet = new \PhpOffice\PhpSpreadsheet\Reader\Xls(); + } + + $reader->setReadDataOnly(true); + $sheet = $reader->load($this->path); + + $tables = $sheet->getSheetCount(); + for ($i = 0; $i < $tables; ++$i) { + $sheet->setActiveSheetIndex($i); + + $workSheet = $sheet->getSheet($i); + $table = $workSheet->getTitle(); + $titles = []; + + // get column titles + $column = 1; + while (!empty($value = $workSheet->getCellByColmnAndRow($column, 1)->getValue())) { + $titles[] = $value; + } + + $columns = \count($titles); + + // insert data + $line = 2; + while (!empty($row = $workSheet->getCellByColumnAndRow(1, $line)->getValue())) { + $query = new Builder($this->con); + $query->update(...$titles)->into($table); + + $cells = []; + for ($j = 1; $j <= $columns; ++$j) { + $cells[] = $workSheet->getCellByColumnAndRow(j, $line)->getValue(); + } + + $query->values(...$cells)->where($titles[0], '=', $cells[0]); + $query->execute(); + } + } } } diff --git a/Utils/IO/IODatabaseMapper.php b/Utils/IO/IODatabaseMapper.php index 933402fe1..db518686f 100644 --- a/Utils/IO/IODatabaseMapper.php +++ b/Utils/IO/IODatabaseMapper.php @@ -4,7 +4,7 @@ * * PHP Version 7.4 * - * @package TBD + * @package phpOMS\Utils\IO * @copyright Dennis Eichhorn * @license OMS License 1.0 * @version 1.0.0 @@ -14,13 +14,42 @@ declare(strict_types=1); namespace phpOMS\Utils\IO; +/** + * IO database mapper. + * + * @package phpOMS\Utils\IO + * @license OMS License 1.0 + * @link https://orange-management.org + * @since 1.0.0 + */ interface IODatabaseMapper { - public function addSource(string $source); + /** + * Insert data from excel sheet into database + * + * @return void + * + * @since 1.0.0 + */ + public function insert() : void; - public function setSources(array $sources); + /** + * Select data from database and store in excel sheet + * + * @param Builder[] $queries Queries to execute + * + * @return void + * + * @since 1.0.0 + */ + public function select(array $queries) : void; - public function setLineBuffer(int $buffer); - - public function insert(); + /** + * Update data from excel sheet into database + * + * @return void + * + * @since 1.0.0 + */ + public function update() : void; } diff --git a/Views/PaginationView.php b/Views/PaginationView.php index 7f25d4df5..259add848 100644 --- a/Views/PaginationView.php +++ b/Views/PaginationView.php @@ -68,7 +68,7 @@ class PaginationView extends View } /** - * @param int $maxPages + * @param int $maxPages Maximum amount of pages to be shown * * @return void * @@ -90,7 +90,7 @@ class PaginationView extends View } /** - * @param int $pages + * @param int $pages Number of pages * * @return void * @@ -112,7 +112,7 @@ class PaginationView extends View } /** - * @param int $page + * @param int $page Current page index * * @return void * @@ -134,7 +134,7 @@ class PaginationView extends View } /** - * @param int $results + * @param int $results Amount of results * * @return void * diff --git a/Views/TableView.php b/Views/TableView.php deleted file mode 100644 index 8df49bc83..000000000 --- a/Views/TableView.php +++ /dev/null @@ -1,31 +0,0 @@ -