diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 5aabc9fe..361f6b40 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,18 +3,6 @@ -## Related Issue - - - - - -## How Has This Been Tested - - - - - ## Types of changes diff --git a/.github/workflows/_publish-docs.yml b/.github/workflows/_publish-docs.yml index 5a3cb75c..b67ad3c5 100644 --- a/.github/workflows/_publish-docs.yml +++ b/.github/workflows/_publish-docs.yml @@ -17,7 +17,7 @@ jobs: - name: Set up php ${{ matrix.php-version }} uses: shivammathur/setup-php@v2 with: - php-version: 8.2 + php-version: 8.3 - name: Install phpdocumentor run: | diff --git a/.github/workflows/_static-analysis.yml b/.github/workflows/_static-analysis.yml index 3052897f..5a72d400 100644 --- a/.github/workflows/_static-analysis.yml +++ b/.github/workflows/_static-analysis.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ["7.4"] + php-version: ["8.1"] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/_test-code-samples.yml b/.github/workflows/_test-code-samples.yml index 72604bd5..62a04106 100644 --- a/.github/workflows/_test-code-samples.yml +++ b/.github/workflows/_test-code-samples.yml @@ -12,8 +12,8 @@ jobs: max-parallel: 2 matrix: php-version: - - "7.4" - - "8.3" + - "8.1" + - "8.4" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/_test-integrations.yml b/.github/workflows/_test-integrations.yml index 0a955595..79bbbcee 100644 --- a/.github/workflows/_test-integrations.yml +++ b/.github/workflows/_test-integrations.yml @@ -24,8 +24,8 @@ jobs: max-parallel: 2 matrix: php-version: - - 7.4 - - 8.3 + - 8.1 + - 8.4 runs-on: "ubuntu-latest" steps: - uses: actions/checkout@v4 @@ -59,8 +59,8 @@ jobs: # max-parallel: 2 # matrix: # php-version: -# - 7.4 -# - 8.3 +# - 8.1 +# - 8.4 # runs-on: "macos-latest" # steps: # - uses: actions/checkout@v4 @@ -90,8 +90,8 @@ jobs: max-parallel: 2 matrix: php-version: - - 7.4 - - 8.3 + - 8.1 + - 8.4 runs-on: "windows-latest" steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/_test-units.yml b/.github/workflows/_test-units.yml index 107b8651..32d2f52d 100644 --- a/.github/workflows/_test-units.yml +++ b/.github/workflows/_test-units.yml @@ -10,11 +10,10 @@ jobs: strategy: matrix: php-version: - - 7.4 - - 8.0 - 8.1 - 8.2 - 8.3 + - 8.4 runs-on: "ubuntu-latest" steps: - uses: actions/checkout@v4 @@ -37,11 +36,10 @@ jobs: strategy: matrix: php-version: - - 7.4 - - 8.0 - 8.1 - 8.2 - 8.3 + - 8.4 runs-on: "ubuntu-latest" steps: - uses: actions/checkout@v4 @@ -74,11 +72,10 @@ jobs: strategy: matrix: php-version: - - 7.4 - - 8.0 - 8.1 - 8.2 - 8.3 + - 8.4 runs-on: "macos-latest" steps: - uses: actions/checkout@v4 @@ -104,11 +101,10 @@ jobs: # strategy: # matrix: # php-version: -# - 7.4 -# - 8.0 # - 8.1 # - 8.2 # - 8.3 +# - 8.4 # runs-on: "macos-latest" # steps: # - uses: actions/checkout@v4 @@ -146,11 +142,10 @@ jobs: strategy: matrix: php-version: - - 7.4 - - 8.0 - 8.1 - 8.2 - 8.3 + - 8.4 runs-on: "windows-latest" steps: - uses: actions/checkout@v4 @@ -176,22 +171,21 @@ jobs: strategy: matrix: php-version: - - 7.4 - - 8.0 - 8.1 - 8.2 - 8.3 + - 8.4 runs-on: "windows-latest" steps: - uses: actions/checkout@v4 with: submodules: recursive - name: Install Ghostscript - run: choco install ghostscript --version 10.03.1 -y + run: choco install ghostscript --version 10.04.0 -y - name: Create Ghostscript alias run: | - New-Item -ItemType SymbolicLink -Path "C:\Windows\gs.exe" -Target "C:\Program Files\gs\gs10.03.1\bin\gswin64c.exe" - New-Item -ItemType SymbolicLink -Path "C:\Windows\gs" -Target "C:\Program Files\gs\gs10.03.1\bin\gswin64c.exe" + New-Item -ItemType SymbolicLink -Path "C:\Windows\gs.exe" -Target "C:\Program Files\gs\gs10.04.0\bin\gswin64c.exe" + New-Item -ItemType SymbolicLink -Path "C:\Windows\gs" -Target "C:\Program Files\gs\gs10.04.0\bin\gswin64c.exe" shell: powershell - name: Set up php ${{ matrix.php-version }} uses: shivammathur/setup-php@v2 diff --git a/bin/MindeeCLICommand.php b/bin/MindeeCLICommand.php index 84b846d7..c7334193 100644 --- a/bin/MindeeCLICommand.php +++ b/bin/MindeeCLICommand.php @@ -441,7 +441,7 @@ private function handleCustomOrGeneratedProduct( PredictMethodOptions $predictMethodOptions, string $product ): bool { - if (in_array($product, ["custom", "generated"])) { + if ($product == "generated") { $accountName = $input->getOption('account_name'); $endpointName = $input->getOption('endpoint_name'); $endpointVersion = $input->getOption('endpoint_version') ?? '1'; @@ -459,7 +459,6 @@ private function handleCustomOrGeneratedProduct( "No version provided for \"$endpointName\", version 1 will be used by default." ); } - $endpoint = $client->createEndpoint($endpointName, $accountName, $endpointVersion); $predictMethodOptions->setEndpoint($endpoint); } diff --git a/bin/MindeeCLIDocuments.php b/bin/MindeeCLIDocuments.php index 11d488ff..83411e52 100644 --- a/bin/MindeeCLIDocuments.php +++ b/bin/MindeeCLIDocuments.php @@ -20,12 +20,6 @@ public static function getSpecs(): array false, true ), - "custom" => new DocumentCommandConfig( - "Custom document type from API builder", - \Mindee\Product\Custom\CustomV1::class, - true, - false - ), "barcode-reader" => new DocumentCommandConfig( "Barcode Reader", \Mindee\Product\BarcodeReader\BarcodeReaderV1::class, diff --git a/composer.json b/composer.json index 14327de5..18be00f3 100644 --- a/composer.json +++ b/composer.json @@ -4,20 +4,20 @@ "type": "library", "license": "MIT", "require": { - "php": ">=7.4", + "php": ">=8.1", "ext-curl": "*", "ext-fileinfo": "*", "ext-json": "*", - "symfony/console": ">=5.4", + "symfony/console": ">=6.0", "setasign/fpdf": "^1.8", "setasign/fpdi": "^2.6", - "smalot/pdfparser": "^2.11" + "smalot/pdfparser": "^2.12" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.38", "squizlabs/php_codesniffer": "^3.7", "phpunit/phpunit": "^9.6", - "madewithlove/license-checker": "^0.10.0" + "madewithlove/license-checker": "^v1.0" }, "suggest": { "ext-imagick": "Required for PDF rasterization and image processing features", diff --git a/docs/code_samples/custom_v1.txt b/docs/code_samples/custom_v1.txt index 13c19a2e..3c06284f 100644 --- a/docs/code_samples/custom_v1.txt +++ b/docs/code_samples/custom_v1.txt @@ -1,5 +1,11 @@ fixPDF(); + } + return $input; } /** @@ -83,9 +87,13 @@ public function sourceFromPath(string $filePath, bool $fixPDF = false): PathInpu * @param boolean $fixPDF Whether the PDF should be fixed or not. * @return FileInput */ - public function sourceFromFile($file, bool $fixPDF = false): FileInput + public function sourceFromFile(mixed $file, bool $fixPDF = false): FileInput { - return new FileInput($file, $fixPDF); + $input = new FileInput($file); + if ($fixPDF) { + $input->fixPDF(); + } + return $input; } /** @@ -98,7 +106,11 @@ public function sourceFromFile($file, bool $fixPDF = false): FileInput */ public function sourceFromBytes(string $fileBytes, string $fileName, bool $fixPDF = false): BytesInput { - return new BytesInput($fileBytes, $fileName, $fixPDF); + $input = new BytesInput($fileBytes, $fileName); + if ($fixPDF) { + $input->fixPDF(); + } + return $input; } /** @@ -111,7 +123,11 @@ public function sourceFromBytes(string $fileBytes, string $fileName, bool $fixPD */ public function sourceFromB64String(string $fileB64, string $fileName, bool $fixPDF = false): Base64Input { - return new Base64Input($fileB64, $fileName, $fixPDF); + $input = new Base64Input($fileB64, $fileName); + if ($fixPDF) { + $input->fixPDF(); + } + return $input; } /** @@ -515,7 +531,6 @@ public function parseQueued( return $this->makeParseQueuedRequest($predictionType, $queueId, $endpoint); } - /** * @param string $predictionType Name of the product's class. * @param LocalResponse $localResponse Local response to load. @@ -540,7 +555,6 @@ public function loadPrediction( } } - /** * Sends a document to a workflow. * diff --git a/src/Extraction/ExtractedImage.php b/src/Extraction/ExtractedImage.php index 1946eeee..6c56fedd 100644 --- a/src/Extraction/ExtractedImage.php +++ b/src/Extraction/ExtractedImage.php @@ -40,7 +40,7 @@ class ExtractedImage * @param string $saveFormat The format to save the image. * @throws MindeeUnhandledException Throws if PDF operations aren't supported. */ - public function __construct($image, string $filename, string $saveFormat) + public function __construct(mixed $image, string $filename, string $saveFormat) { DependencyChecker::isImageMagickAvailable(); DependencyChecker::isGhostscriptAvailable(); @@ -86,17 +86,12 @@ public function asInputSource(): BytesInput */ private function getEncodedImageFormat(string $saveFormat): string { - switch (strtolower($saveFormat)) { - case 'png': - return 'png'; - case 'bmp': - return 'bmp'; - case 'gif': - return 'gif'; - case 'webp': - return 'webp'; - default: - return 'jpeg'; - } + return match (strtolower($saveFormat)) { + 'png' => 'png', + 'bmp', => 'bmp', + 'gif' => 'gif', + 'webp' => 'webp', + default => 'jpeg', + }; } } diff --git a/src/Extraction/PdfExtractor.php b/src/Extraction/PdfExtractor.php index 70ab5a62..23605f17 100644 --- a/src/Extraction/PdfExtractor.php +++ b/src/Extraction/PdfExtractor.php @@ -180,8 +180,6 @@ public function extractInvoices($pageIndexes, bool $strict = false): array $previousConfidence = $confidence; $i++; } - - return $this->extractSubDocuments($correctPageIndexes); } diff --git a/src/Geometry/BBox.php b/src/Geometry/BBox.php index 4fa20044..af9e311d 100644 --- a/src/Geometry/BBox.php +++ b/src/Geometry/BBox.php @@ -85,10 +85,10 @@ public function getMaxY(): float /** * Extends the BBox with the provided points. * - * @param Polygon|array $points Series of points to add to the BBox. + * @param array|Polygon $points Series of points to add to the BBox. * @return void */ - public function extendWith($points) + public function extendWith(Polygon|array $points): void { if ($points instanceof Polygon) { $sequence = $points->getCoordinates(); diff --git a/src/Geometry/BBoxUtils.php b/src/Geometry/BBoxUtils.php index 1d9f9bdd..90e98974 100644 --- a/src/Geometry/BBoxUtils.php +++ b/src/Geometry/BBoxUtils.php @@ -18,12 +18,11 @@ public static function generateBBoxFromPolygon(?Polygon $polygon): ?BBox if (!$polygon || !$polygon->getCoordinates()) { return null; } - return new BBox( - PolygonUtils::getMinXCoordinate($polygon), - PolygonUtils::getMaxXCoordinate($polygon), - PolygonUtils::getMinYCoordinate($polygon), - PolygonUtils::getMaxYCoordinate($polygon), + $polygon->getMinX(), + $polygon->getMaxX(), + $polygon->getMinY(), + $polygon->getMaxY(), ); } @@ -38,19 +37,17 @@ public static function generateBBoxFromPolygons(array $polygons): ?BBox if (!$polygons) { return null; } - $merged = $polygons[0]; foreach ($polygons as $polygon) { - if ($merged !== $polygon) { + if ($polygon && $merged !== $polygon) { $merged = PolygonUtils::merge($merged, $polygon); } } - return new BBox( - PolygonUtils::getMinXCoordinate($merged), - PolygonUtils::getMaxXCoordinate($merged), - PolygonUtils::getMinYCoordinate($merged), - PolygonUtils::getMaxYCoordinate($merged), + $merged->getMinX(), + $merged->getMaxX(), + $merged->getMinY(), + $merged->getMaxY(), ); } @@ -83,7 +80,6 @@ public static function mergeBBoxes(array $bboxes): ?BBox $maxY = $bbox->getMaxY(); } } - return new BBox((float)$minX, (float)$maxX, (float)$minY, (float)$maxY); } } diff --git a/src/Geometry/MinMaxUtils.php b/src/Geometry/MinMaxUtils.php index abe94596..9ff86c79 100644 --- a/src/Geometry/MinMaxUtils.php +++ b/src/Geometry/MinMaxUtils.php @@ -2,6 +2,9 @@ namespace Mindee\Geometry; +use Mindee\Error\ErrorCode; +use Mindee\Error\MindeeGeometryException; + /** * Utility class for MinMax. */ @@ -11,15 +14,21 @@ class MinMaxUtils * Retrieves the upper and lower bounds of the y-axis from an array of points. * * @param array $points An array of points. - * @return \Mindee\Geometry\MinMax + * @return MinMax + * @throws MindeeGeometryException Throws if the provided array is too small. */ public static function getMinMaxY(array $points): MinMax { + if (count($points) < 1) { + throw new MindeeGeometryException( + 'The provided point array must have at least 1 point to calculate the Y bounds.', + ErrorCode::GEOMETRIC_OPERATION_FAILED + ); + } $yCoords = []; foreach ($points as $point) { $yCoords[] = $point->getY(); } - return new MinMax(min($yCoords), max($yCoords)); } @@ -27,15 +36,21 @@ public static function getMinMaxY(array $points): MinMax * Retrieves the upper and lower bounds of the x-axis from an array of points. * * @param array $points An array of points. - * @return \Mindee\Geometry\MinMax + * @return MinMax + * @throws MindeeGeometryException Throws if the provided array is too small. */ public static function getMinMaxX(array $points): MinMax { + if (count($points) < 1) { + throw new MindeeGeometryException( + 'The provided point array must have at least 1 point to calculate the X bounds.', + ErrorCode::GEOMETRIC_OPERATION_FAILED + ); + } $xCoords = []; foreach ($points as $point) { $xCoords[] = $point->getX(); } - return new MinMax(min($xCoords), max($xCoords)); } } diff --git a/src/Geometry/Polygon.php b/src/Geometry/Polygon.php index f2d3793f..dea64e78 100644 --- a/src/Geometry/Polygon.php +++ b/src/Geometry/Polygon.php @@ -2,6 +2,8 @@ namespace Mindee\Geometry; +use Mindee\Error\MindeeGeometryException; + /** * Polygon represented as a set of coordinates (vertices/points). */ @@ -12,6 +14,16 @@ class Polygon */ public ?array $coordinates; + /** + * @var MinMax Min and max Y values of the polygon. + */ + private MinMax $minMaxY; + + /** + * @var MinMax Min and max X values of the polygon. + */ + private MinMax $minMaxX; + /** * @param array|null $coordinates Coordinates of the polygon as a set of Points. */ @@ -44,7 +56,10 @@ public function getCentroid(): Point */ public function getMinMaxY(): MinMax { - return MinMaxUtils::getMinMaxY($this->coordinates); + if (!isset($this->minMaxY)) { + $this->minMaxY = MinMaxUtils::getMinMaxY($this->coordinates); + } + return $this->minMaxY; } /** @@ -54,7 +69,10 @@ public function getMinMaxY(): MinMax */ public function getMinMaxX(): MinMax { - return MinMaxUtils::getMinMaxX($this->coordinates); + if (!isset($this->minMaxX)) { + $this->minMaxX = MinMaxUtils::getMinMaxX($this->coordinates); + } + return $this->minMaxX; } /** @@ -81,6 +99,46 @@ public function isPointInX(Point $point): bool return PolygonUtils::isPointInX($point, $minMax->getMin(), $minMax->getMax()); } + /** + * Retrieves the minimum X coordinate. + * + * @return float + */ + public function getMinX(): float + { + return $this->getMinMaxX()->getMin(); + } + + /** + * Retrieves the maximum X coordinate. + * + * @return float + */ + public function getMaxX(): float + { + return $this->getMinMaxX()->getMax(); + } + + /** + * Retrieves the minimum Y coordinate. + * + * @return float + */ + public function getMinY(): float + { + return $this->getMinMaxY()->getMin(); + } + + /** + * Retrieves the maximum Y coordinate. + * + * @return float + */ + public function getMaxY(): float + { + return $this->getMinMaxY()->getMax(); + } + /** * Checks whether the Polygon has coordinates. * diff --git a/src/Geometry/PolygonUtils.php b/src/Geometry/PolygonUtils.php index 47c6d9b9..4d808ae1 100644 --- a/src/Geometry/PolygonUtils.php +++ b/src/Geometry/PolygonUtils.php @@ -2,6 +2,7 @@ namespace Mindee\Geometry; +use Mindee\Error\ErrorCode; use Mindee\Error\MindeeGeometryException; /** @@ -31,106 +32,6 @@ public static function getCentroid(array $vertices): Point return new Point($xSum / $verticesSum, $ySum / $verticesSum); } - /** - * Retrieves the minimum y coordinate of a Polygon. - * - * @param Polygon $polygon Polygon to get the minimum y coordinate of. - * @return float - * @throws MindeeGeometryException Throws if a minimum y-axis value cannot - * be found, e.g. if the polygon is empty. - */ - public static function getMinYCoordinate(Polygon $polygon): float - { - $min = null; - foreach ($polygon->getCoordinates() as $point) { - if (!isset($min) || $min > $point->getY()) { - $min = $point->getY(); - } - } - if (!isset($min)) { - throw new MindeeGeometryException( - 'The provided polygon seems to be empty, or the Y coordinates of each point are invalid.' - ); - } - - return $min; - } - - /** - * Retrieves the minimum x coordinate of a Polygon. - * - * @param Polygon $polygon Polygon to get the minimum y coordinate of. - * @return float - * @throws MindeeGeometryException Throws if a minimum x-axis value cannot be - * found, e.g. if the polygon is empty. - */ - public static function getMinXCoordinate(Polygon $polygon): float - { - $min = null; - foreach ($polygon->getCoordinates() as $point) { - if (!isset($min) || $min > $point->getX()) { - $min = $point->getX(); - } - } - if (!isset($min)) { - throw new MindeeGeometryException( - 'The provided polygon seems to be empty, or the X coordinates of each point are invalid.' - ); - } - - return $min; - } - - /** - * Retrieves the maximum y coordinate of a Polygon. - * - * @param Polygon $polygon Polygon to get the minimum y coordinate of. - * @return float - * @throws MindeeGeometryException Throws if a maximum y-axis value cannot be - * found, e.g. if the polygon is empty. - */ - public static function getMaxYCoordinate(Polygon $polygon): float - { - $min = null; - foreach ($polygon->getCoordinates() as $point) { - if (!isset($min) || $min < $point->getY()) { - $min = $point->getY(); - } - } - if (!isset($min)) { - throw new MindeeGeometryException( - 'The provided polygon seems to be empty, or the Y coordinates of each point are invalid.' - ); - } - - return $min; - } - - /** - * Retrieves the maximum x coordinate of a Polygon. - * - * @param Polygon $polygon Polygon to get the minimum y coordinate of. - * @return float - * @throws MindeeGeometryException Throws if a maximum x-axis value cannot be - * found, e.g. if the polygon is empty. - */ - public static function getMaxXCoordinate(Polygon $polygon): float - { - $min = null; - foreach ($polygon->getCoordinates() as $point) { - if (!isset($min) || $min < $point->getX()) { - $min = $point->getX(); - } - } - if (!isset($min)) { - throw new MindeeGeometryException( - 'The provided polygon seems to be empty, or the X coordinates of each point are invalid.' - ); - } - - return $min; - } - /** * Compares two polygons on the Y axis. Returns a sort-compliant result (0;-1;1). * @@ -140,52 +41,58 @@ public static function getMaxXCoordinate(Polygon $polygon): float */ public static function compareOnY(Polygon $polygon1, Polygon $polygon2): int { - $sort = self::getMinYCoordinate($polygon1) - self::getMinYCoordinate($polygon2); + $sort = ($polygon1->getMinY() - $polygon2->getMinY()); if ($sort == 0) { return 0; } - return $sort < 0 ? -1 : 1; } /** * Merges two polygons. * - * @param Polygon|null $base First polygon to merge. - * @param Polygon|null $target Second polygon to merge. + * @param Polygon $base First polygon to merge. + * @param Polygon $target Second polygon to merge. * @return Polygon * @throws MindeeGeometryException Throws if both polygons are empty. */ - public static function merge(?Polygon $base, ?Polygon $target): Polygon + public static function merge(Polygon $base, Polygon $target): Polygon { - if ((!$base || !$base->getCoordinates()) && (!$target || !$target->getCoordinates())) { - throw new MindeeGeometryException('Cannot merge two empty polygons.'); + if ((!$base->getCoordinates()) && (!$target->getCoordinates())) { + throw new MindeeGeometryException( + 'Cannot merge two empty polygons.', + ErrorCode::GEOMETRIC_OPERATION_FAILED + ); } - if (!$base || !$base->getCoordinates()) { + if (!$base->getCoordinates()) { return $target; } - if (!$target || !$target->getCoordinates()) { + if (!$target->getCoordinates()) { return $base; } - - return new Polygon(array_unique(array_merge($base->getCoordinates(), $target->getCoordinates()), SORT_REGULAR)); + return new Polygon( + array_unique(array_merge($base->getCoordinates(), $target->getCoordinates()), SORT_REGULAR) + ); } /** * Creates a bounding box from one or two polygons. * - * @param Polygon|null $base First polygon. + * @param Polygon $base First polygon. * @param Polygon|null $target Second polygon. * @return Polygon */ - public static function createBoundingBoxFrom(?Polygon $base, ?Polygon $target = null): Polygon + public static function createBoundingBoxFrom(Polygon $base, ?Polygon $target = null): Polygon { - $merged = PolygonUtils::merge($base, $target); - - $topLeft = new Point(self::getMinXCoordinate($merged), self::getMinYCoordinate($merged)); - $topRight = new Point(self::getMaxXCoordinate($merged), self::getMinYCoordinate($merged)); - $bottomRight = new Point(self::getMaxXCoordinate($merged), self::getMaxYCoordinate($merged)); - $bottomLeft = new Point(self::getMinXCoordinate($merged), self::getMaxYCoordinate($merged)); + if ($target) { + $merged = PolygonUtils::merge($base, $target); + } else { + $merged = $base; + } + $topLeft = new Point($merged->getMinX(), $merged->getMinY()); + $topRight = new Point($merged->getMaxX(), $merged->getMinY()); + $bottomRight = new Point($merged->getMaxX(), $merged->getMaxY()); + $bottomLeft = new Point($merged->getMinX(), $merged->getMaxY()); return new Polygon([ $topLeft, @@ -207,29 +114,7 @@ public static function quadrilateralFromPrediction(array $prediction): Polygon if (count($prediction) != 4) { throw new MindeeGeometryException('Prediction must have exactly 4 points.'); } - - return new Polygon([ - new Point($prediction[0][0], $prediction[0][1]), - new Point($prediction[1][0], $prediction[1][1]), - new Point($prediction[2][0], $prediction[2][1]), - new Point($prediction[3][0], $prediction[3][1]), - ]); - } - - /** - * Generates a Polygon from a given prediction. - * - * @deprecated construct a new Polygon() instead. - * @param array $prediction Raw prediction array. - * @return Polygon - */ - public static function polygonFromPrediction(array $prediction): Polygon - { - $points = []; - foreach ($prediction as $point) { - $points[] = new Point($point[0], $point[1]); - } - return new Polygon($points); + return new Polygon($prediction); } /** @@ -245,20 +130,6 @@ public static function isPointInX(Point $point, float $minX, float $maxX): bool return $point->getX() >= $minX && $point->getX() <= $maxX; } - /** - * Checks whether a point is in a polygon's x-axis range. - * - * @param Point $point Point to check. - * @param Polygon $polygon Polygon. - * @return boolean - */ - public static function isPointInPolygonX(Point $point, Polygon $polygon): bool - { - $minX = MinMaxUtils::getMinMaxX($polygon->getCoordinates())->getMin(); - $maxX = MinMaxUtils::getMinMaxX($polygon->getCoordinates())->getMax(); - return self::isPointInX($point, $minX, $maxX); - } - /** * Checks whether a point is located within a coordinate range on the y-axis. * @@ -271,18 +142,4 @@ public static function isPointInY(Point $point, float $minY, float $maxY): bool { return $point->getY() >= $minY && $point->getY() <= $maxY; } - - /** - * Checks whether a point is in a polygon's y-axis range. - * - * @param Point $point Point to check. - * @param Polygon $polygon Polygon. - * @return boolean - */ - public static function isPointInPolygonY(Point $point, Polygon $polygon): bool - { - $minY = MinMaxUtils::getMinMaxY($polygon->getCoordinates())->getMin(); - $maxY = MinMaxUtils::getMinMaxY($polygon->getCoordinates())->getMax(); - return self::isPointInY($point, $minY, $maxY); - } } diff --git a/src/Http/Endpoint.php b/src/Http/Endpoint.php index 919ae90e..22d8f08f 100644 --- a/src/Http/Endpoint.php +++ b/src/Http/Endpoint.php @@ -90,13 +90,13 @@ public function predictAsyncRequestPost( /** * Starts a CURL session, using POST. * - * @param InputSource $fileCurl File to upload. - * @param PredictMethodOptions $options Prediction Options. - * @param boolean $async Whether to use the async endpoint. + * @param InputSource $inputSource File to upload. + * @param PredictMethodOptions $options Prediction Options. + * @param boolean $async Whether to use the async endpoint. * @return array */ private function initCurlSessionPost( - InputSource $fileCurl, + InputSource $inputSource, PredictMethodOptions $options, bool $async ): array { @@ -115,13 +115,14 @@ private function initCurlSessionPost( curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); $postFields = null; - if ($fileCurl instanceof URLInputSource) { - $postFields = ['document' => $fileCurl->url]; - } elseif ($fileCurl instanceof LocalInputSource) { + if ($inputSource instanceof URLInputSource) { + $postFields = ['document' => $inputSource->url]; + } elseif ($inputSource instanceof LocalInputSource) { + $inputSource->checkNeedsFix(); if ($options->closeFile) { - $fileCurl->close(); + $inputSource->close(); } - $postFields = ['document' => $fileCurl->fileObject]; + $postFields = ['document' => $inputSource->fileObject]; } if ($options->predictOptions->includeWords) { $postFields['include_mvision'] = 'true'; diff --git a/src/Http/MindeeApiV2.php b/src/Http/MindeeApiV2.php index 5c007248..e05e490f 100644 --- a/src/Http/MindeeApiV2.php +++ b/src/Http/MindeeApiV2.php @@ -305,6 +305,7 @@ private function documentEnqueuePost( if ($inputSource instanceof URLInputSource) { $postFields['url'] = $inputSource->url; } elseif ($inputSource instanceof LocalInputSource) { + $inputSource->checkNeedsFix(); if ($params->closeFile) { $inputSource->close(); } diff --git a/src/Image/ImageUtils.php b/src/Image/ImageUtils.php index 7a091e0b..45e15afa 100644 --- a/src/Image/ImageUtils.php +++ b/src/Image/ImageUtils.php @@ -16,7 +16,7 @@ class ImageUtils * The resulting image is formatted to jpeg. * @throws MindeeImageException Throws if something goes wrong during image conversion. */ - public static function toMagickImage($image): \Imagick + public static function toMagickImage(mixed $image): \Imagick { try { if ($image instanceof \Imagick) { diff --git a/src/Input/Base64Input.php b/src/Input/Base64Input.php index 800c5376..7972333e 100644 --- a/src/Input/Base64Input.php +++ b/src/Input/Base64Input.php @@ -13,11 +13,10 @@ class Base64Input extends LocalInputSource private string $tempFile; /** - * @param string $strBase64 Raw data as a base64-encoded string. - * @param string $fileName File name of the input. - * @param boolean $fixPDF Whether the PDF should be fixed or not. + * @param string $strBase64 Raw data as a base64-encoded string. + * @param string $fileName File name of the input. */ - public function __construct(string $strBase64, string $fileName, bool $fixPDF = false) + public function __construct(string $strBase64, string $fileName) { $this->tempFile = tempnam(sys_get_temp_dir(), 'b64_'); $this->fileName = $fileName; @@ -26,7 +25,7 @@ public function __construct(string $strBase64, string $fileName, bool $fixPDF = $finfo = finfo_open(FILEINFO_MIME_TYPE); $this->fileMimetype = finfo_buffer($finfo, base64_decode($strBase64)); $this->fileObject = new \CURLFile($this->tempFile, $this->fileMimetype, $this->fileName); - parent::__construct($fixPDF); + parent::__construct(); } diff --git a/src/Input/BytesInput.php b/src/Input/BytesInput.php index 327f107e..c356384c 100644 --- a/src/Input/BytesInput.php +++ b/src/Input/BytesInput.php @@ -13,11 +13,10 @@ class BytesInput extends LocalInputSource private string $tempFile; /** - * @param string $fileBytes Raw data as bytes. - * @param string $fileName File name of the input. - * @param boolean $fixPDF Whether the PDF should be fixed or not. + * @param string $fileBytes Raw data as bytes. + * @param string $fileName File name of the input. */ - public function __construct(string $fileBytes, string $fileName, bool $fixPDF = false) + public function __construct(string $fileBytes, string $fileName) { $this->tempFile = tempnam(sys_get_temp_dir(), 'b64_'); $this->fileName = $fileName; @@ -26,7 +25,7 @@ public function __construct(string $fileBytes, string $fileName, bool $fixPDF = $finfo = finfo_open(FILEINFO_MIME_TYPE); $this->fileMimetype = finfo_buffer($finfo, $fileBytes); $this->fileObject = new \CURLFile($this->tempFile, $this->fileMimetype, $this->fileName); - parent::__construct($fixPDF); + parent::__construct(); } diff --git a/src/Input/FileInput.php b/src/Input/FileInput.php index 0ceb4015..ee1b308f 100644 --- a/src/Input/FileInput.php +++ b/src/Input/FileInput.php @@ -13,23 +13,21 @@ class FileInput extends LocalInputSource /** * @var mixed $file A file-like object compatible with CURLFile. */ - private $file; + private mixed $file; /** - * @param mixed &$file File reference. - * @param boolean $fixPDF Whether the PDF should be fixed or not. + * @param mixed &$file File reference. */ - public function __construct(&$file, bool $fixPDF = false) + public function __construct(mixed &$file) { $this->file = &$file; $this->filePath = stream_get_meta_data($this->file)['uri']; $this->fileName = basename($this->filePath); $this->fileMimetype = mime_content_type($this->filePath); $this->fileObject = new \CURLFile($this->filePath, $this->fileName, $this->fileMimetype); - parent::__construct($fixPDF); + parent::__construct(); } - /** * Reads the contents of the file. * @@ -41,7 +39,6 @@ public function readContents(): array return [$this->fileName, $fileContents]; } - /** * Closes the file. * diff --git a/src/Input/LocalInputSource.php b/src/Input/LocalInputSource.php index 2592855f..45d054c6 100644 --- a/src/Input/LocalInputSource.php +++ b/src/Input/LocalInputSource.php @@ -9,13 +9,10 @@ use CURLFile; use Exception; use Mindee\Error\ErrorCode; -use Mindee\Error\MindeeImageException; use Mindee\Error\MindeeMimeTypeException; use Mindee\Error\MindeePDFException; use Mindee\Error\MindeeSourceException; -use Mindee\Error\MindeeUnhandledException; use Mindee\Image\ImageCompressor; -use Mindee\Parsing\DependencyChecker; use Mindee\PDF\PDFCompressor; use Mindee\PDF\PDFUtils; use setasign\Fpdi\Fpdi; @@ -33,6 +30,7 @@ 'image/jpeg', 'image/tiff', 'image/webp', + 'application/octet-stream', ]; /** @@ -62,6 +60,21 @@ abstract class LocalInputSource extends InputSource */ protected bool $throwsOnClose; + /** + * Checks if the file needs fixing. + * @return void + */ + public function checkNeedsFix(): void + { + if ($this->fileMimetype == 'application/octet-stream') { + trigger_error( + 'File type application/octet-stream is probably incorrect. ' + . 'Try to run fixPDF() on the file.', + E_USER_WARNING + ); + } + } + /** * Checks the mimetype integrity of a file. * @@ -83,13 +96,9 @@ private function checkMimeType() /** * Base constructor, mostly used for Mime type checking. - * @param boolean $fixPDF Whether the PDF should be fixed or not. */ - public function __construct(bool $fixPDF = false) + public function __construct() { - if ($fixPDF) { - $this->fixPDF(); - } $this->checkMimeType(); $this->throwsOnClose = false; } @@ -101,6 +110,7 @@ public function __construct(bool $fixPDF = false) */ public function isPDF(): bool { + $this->checkMimeType(); return $this->fileMimetype == 'application/pdf'; } @@ -131,27 +141,11 @@ public function countDocPages(): int } } - /** - * Processes a PDF file. - * To be implemented. - * - * @param string $behavior Behaviors available: KEEP_ONLY, REMOVE. - * @param integer $onMinPages Minimum of pages to apply the operation. - * @param array $pageIndexes Indexes of the pages to apply the operation to. - * @return void - * @throws MindeePDFException Throws if the operation is unknown, or if the resulting PDF can't be processed. - * @deprecated Use applyPageOptions() instead. - */ - public function processPDF(string $behavior, int $onMinPages, array $pageIndexes) - { - $this->applyPageOptions(new PageOptions($pageIndexes, $behavior, $onMinPages)); - } - /** * @param string $fileBytes Raw data as bytes. * @return void */ - private function saveBytesAsFile(string $fileBytes) + private function saveBytesAsFile(string $fileBytes): void { $cutPdfTempFile = tempnam(sys_get_temp_dir(), 'mindee_cut_pdf_'); file_put_contents($cutPdfTempFile, $fileBytes); @@ -165,7 +159,7 @@ private function saveBytesAsFile(string $fileBytes) * @return void * @throws MindeePDFException Throws if the pdf file can't be processed. */ - public function mergePDFPages(array $pageNumbers) + public function mergePDFPages(array $pageNumbers): void { try { $pdf = new FPDI(); @@ -232,14 +226,13 @@ public function readContents(): array return [basename($this->fileObject->getFilename()), $strContents]; } - /** * Attempts to fix a PDF file. * * @return void * @throws MindeeSourceException Throws if the file couldn't be fixed. */ - private function fixPDF(): void + public function fixPDF(): void { if (str_starts_with($this->fileMimetype, "image/")) { error_log("Input file is an image, skipping PDF fix."); @@ -260,7 +253,6 @@ private function fixPDF(): void $this->fileObject = new CURLFile($tempFile, $this->fileMimetype, $this->fileName); return; } - throw new MindeeSourceException( "PDF file could not be fixed.", ErrorCode::FILE_OPERATION_ERROR diff --git a/src/Input/LocalResponse.php b/src/Input/LocalResponse.php index 5c0d9f90..9df33843 100644 --- a/src/Input/LocalResponse.php +++ b/src/Input/LocalResponse.php @@ -20,7 +20,7 @@ class LocalResponse * @param mixed $inputFile A string, path or file-like object to load as a local response. * @throws MindeeException Throws if the input file isn't acceptable. */ - public function __construct($inputFile) + public function __construct(mixed $inputFile) { if (is_resource($inputFile) && get_resource_type($inputFile) === 'file') { $content = fread($inputFile, filesize($inputFile)); diff --git a/src/Input/PathInput.php b/src/Input/PathInput.php index 51bed031..e236866f 100644 --- a/src/Input/PathInput.php +++ b/src/Input/PathInput.php @@ -8,10 +8,9 @@ class PathInput extends LocalInputSource { /** - * @param string $filePath Path to open. - * @param boolean $fixPDF Whether the PDF should be fixed or not. + * @param string $filePath Path to open. */ - public function __construct(string $filePath, bool $fixPDF = false) + public function __construct(string $filePath) { $this->filePath = $filePath; $this->fileName = basename($filePath); @@ -21,6 +20,6 @@ public function __construct(string $filePath, bool $fixPDF = false) $this->fileMimetype = $mimeType; $this->fileObject = new \CURLFile($this->filePath, $mimeType, $this->fileName); finfo_close($file); - parent::__construct($fixPDF); + parent::__construct(); } } diff --git a/src/Input/URLInputSource.php b/src/Input/URLInputSource.php index d0f55f35..7c56fcf7 100644 --- a/src/Input/URLInputSource.php +++ b/src/Input/URLInputSource.php @@ -21,7 +21,7 @@ class URLInputSource extends InputSource */ public function __construct(string $url) { - if ((substr($url, 0, 8) !== 'https://')) { + if ((!str_starts_with($url, 'https://'))) { throw new MindeeSourceException( 'URL must be HTTPS', ErrorCode::USER_INPUT_ERROR diff --git a/src/PDF/PDFUtils.php b/src/PDF/PDFUtils.php index 6af56302..710cfccf 100644 --- a/src/PDF/PDFUtils.php +++ b/src/PDF/PDFUtils.php @@ -21,7 +21,7 @@ class PDFUtils * @return string Path of the file. * @throws MindeePDFException Throws if a path can't be extracted from the input. */ - public static function extractFilePath($input): string + public static function extractFilePath(mixed $input): string { if (is_string($input) && file_exists($input) && is_file($input)) { return $input; diff --git a/src/Parsing/Common/Extras/Extras.php b/src/Parsing/Common/Extras/Extras.php index 813578cd..1fdccbec 100644 --- a/src/Parsing/Common/Extras/Extras.php +++ b/src/Parsing/Common/Extras/Extras.php @@ -35,7 +35,7 @@ class Extras * @param mixed $value Value to set the field with. * @return void */ - public function __set(string $varName, $value) + public function __set(string $varName, mixed $value) { $this->data[$varName] = $value; } diff --git a/src/Parsing/Common/Ocr/OcrPage.php b/src/Parsing/Common/Ocr/OcrPage.php index 7dc2571b..8cee1982 100644 --- a/src/Parsing/Common/Ocr/OcrPage.php +++ b/src/Parsing/Common/Ocr/OcrPage.php @@ -2,9 +2,6 @@ namespace Mindee\Parsing\Common\Ocr; -use Mindee\Geometry\MinMaxUtils; -use Mindee\Geometry\PolygonUtils; - /** * OCR extraction for a single page. */ @@ -22,28 +19,28 @@ class OcrPage /** * Checks whether the words are on the same line. * - * @param \Mindee\Parsing\Common\Ocr\OcrWord $currentWord Reference word to compare. - * @param \Mindee\Parsing\Common\Ocr\OcrWord $nextWord Next word to compare. + * @param OcrWord $currentWord Reference word to compare. + * @param OcrWord $nextWord Next word to compare. * @return boolean */ private static function areWordsOnSameLine(OcrWord $currentWord, OcrWord $nextWord): bool { - $currentInNext = PolygonUtils::isPointInPolygonY($currentWord->polygon->getCentroid(), $nextWord->polygon); - $nextInCurrent = PolygonUtils::isPointInPolygonY($nextWord->polygon->getCentroid(), $currentWord->polygon); + $currentInNext = $nextWord->polygon->isPointInY($currentWord->polygon->getCentroid()); + $nextInCurrent = $currentWord->polygon->isPointInY($nextWord->polygon->getCentroid()); return $currentInNext || $nextInCurrent; } /** * Compares word positions on the X axis. Returns a sort-compliant result (0;-1;1). * - * @param \Mindee\Parsing\Common\Ocr\OcrWord $word1 First word. - * @param \Mindee\Parsing\Common\Ocr\OcrWord $word2 Second word. + * @param OcrWord $word1 First word. + * @param OcrWord $word2 Second word. * @return integer */ public static function getMinMaxX(OcrWord $word1, OcrWord $word2): int { - $word1X = MinMaxUtils::getMinMaxX($word1->polygon->getCoordinates())->getMin(); - $word2X = MinMaxUtils::getMinMaxX($word2->polygon->getCoordinates())->getMin(); + $word1X = $word1->polygon->getMinMaxX()->getMin(); + $word2X = $word2->polygon->getMinMaxX()->getMin(); if ($word1X == $word2X) { return 0; } @@ -53,14 +50,14 @@ public static function getMinMaxX(OcrWord $word1, OcrWord $word2): int /** * Compares word positions on the Y axis. Returns a sort-compliant result (0;-1;1). * - * @param \Mindee\Parsing\Common\Ocr\OcrWord $word1 First word. - * @param \Mindee\Parsing\Common\Ocr\OcrWord $word2 Second word. + * @param OcrWord $word1 First word. + * @param OcrWord $word2 Second word. * @return integer */ public static function getMinMaxY(OcrWord $word1, OcrWord $word2): int { - $word1Y = MinMaxUtils::getMinMaxY($word1->polygon->getCoordinates())->getMin(); - $word2Y = MinMaxUtils::getMinMaxY($word2->polygon->getCoordinates())->getMin(); + $word1Y = $word1->polygon->getMinMaxY()->getMin(); + $word2Y = $word2->polygon->getMinMaxY()->getMin(); if ($word1Y == $word2Y) { return 0; } diff --git a/src/Parsing/Custom/ClassificationField.php b/src/Parsing/Custom/ClassificationField.php deleted file mode 100644 index ea171b13..00000000 --- a/src/Parsing/Custom/ClassificationField.php +++ /dev/null @@ -1,36 +0,0 @@ -value = $rawPrediction['value']; - $this->confidence = $rawPrediction['confidence']; - } - - /** - * @return string String representation. - */ - public function __toString(): string - { - return $this->value ?? ''; - } -} diff --git a/src/Parsing/Custom/CustomLine.php b/src/Parsing/Custom/CustomLine.php deleted file mode 100644 index a733a636..00000000 --- a/src/Parsing/Custom/CustomLine.php +++ /dev/null @@ -1,226 +0,0 @@ -rowNumber = $rowNumber; - $this->bbox = new BBox(1, 0, 1, 0); - $this->fields = []; - } - - /** - * Updates a field's value. - * - * @param string $fieldName Name of the field. - * @param \Mindee\Parsing\Custom\ListFieldValue $fieldValue Value of the field. - * @return void - */ - public function updateField(string $fieldName, ListFieldValue $fieldValue) - { - if (array_key_exists($fieldName, $this->fields)) { - $existingField = $this->fields[$fieldName]; - $existingContent = $existingField->content; - $mergedContent = ''; - if (strlen($existingContent) > 0) { - $mergedContent .= $existingContent . ' '; - } - $mergedContent .= $fieldValue->content; - $mergedPolygon = BBoxUtils::generateBBoxFromPolygons([$existingField->polygon, $fieldValue->polygon]); - $mergedConfidence = $existingField->confidence * $fieldValue->confidence; - } else { - $mergedContent = $fieldValue->content; - $mergedConfidence = $fieldValue->confidence; - $mergedPolygon = BBoxUtils::generateBBoxFromPolygon($fieldValue->polygon); - } - $this->fields[$fieldName] = new ListFieldValue([ - 'content' => $mergedContent, - 'confidence' => $mergedConfidence, - 'polygon' => $mergedPolygon, - ]); - } - - /** - * Checks if a BBox is in a given line. - * - * @param \Mindee\Parsing\Custom\CustomLine $line Current line to check. - * @param \Mindee\Geometry\BBox $bbox BBox. - * @param float $heightLineTolerance Height tolerance in pixels. - * @return boolean - */ - public static function isBBoxInLine( - CustomLine $line, - BBox $bbox, - float $heightLineTolerance - ): bool { - if (abs($bbox->getMinY() - $line->bbox->getMinY()) <= $heightLineTolerance) { - return true; - } - - return abs($line->bbox->getMinY() - $bbox->getMinY()) <= $heightLineTolerance; - } - - /** - * Prepares the line items before filling them. - * - * @param string $anchorName Name of the anchor. - * @param array $fields List of fields. - * @param float $heightLineTolerance Height tolerance in pixels. - * @return array - * @throws \Mindee\Error\MindeeException Throws if no lines have been found. - */ - public static function prepare( - string $anchorName, - array $fields, - float $heightLineTolerance - ): array { - $linesPrepared = []; - if (array_key_exists($anchorName, $fields)) { - $anchorField = $fields[$anchorName]; - } else { - throw new MindeeException( - 'No lines have been detected.', - ErrorCode::GEOMETRIC_OPERATION_FAILED - ); - } - $currentLineNumber = 1; - $currentLine = new CustomLine($currentLineNumber); - if ($anchorField && count($anchorField->values) > 0) { - $currentValue = $anchorField->values[0]; - $currentLine->bbox->extendWith($currentValue->polygon); - } - for ($i = 1; $i < count($anchorField->values); ++$i) { - $currentValue = $anchorField->values[$i]; - $currentFieldBox = BBoxUtils::generateBBoxFromPolygon($currentValue->polygon); - if ( - !CustomLine::isBBoxInLine( - $currentLine, - $currentFieldBox, - $heightLineTolerance - ) - ) { - $linesPrepared[] = $currentLine; - ++$currentLineNumber; - $currentLine = new CustomLine($currentLineNumber); - $currentLine->bbox->extendWith($currentValue->polygon); - } - } - $countValidLines = 0; - foreach ($linesPrepared as $line) { - if ($line->rowNumber == $currentLineNumber) { - ++$countValidLines; - } - } - if ($countValidLines == 0) { - $linesPrepared[] = $currentLine; - } - - return $linesPrepared; - } - - /** - * Finds the best anchor for a given array of fields. - * - * @param array $anchors Array of potential anchors. - * @param array $fields Array of fields. - * @return string - */ - private static function findBestAnchor( - array $anchors, - array $fields - ): string { - $anchor = ''; - $anchorRows = 0; - foreach ($anchors as $field) { - $values = $fields[$field]->values; - if ($values && count($values) > $anchorRows) { - $anchorRows = count($values); - $anchor = $field; - } - } - - return $anchor; - } - - /** - * Creates the line items. - * - * @param array $anchors List of anchor candidates. - * @param array $fieldNames List of field names. - * @param array $fields List of all fields. - * @param float $heightLineTolerance Height tolerance in pixels. - * @return array - */ - public static function getLineItems( - array $anchors, - array $fieldNames, - array $fields, - float $heightLineTolerance = 0.01 - ): array { - $lineItems = []; - $fieldsToTransform = []; - foreach ($fields as $fieldName => $fieldValue) { - if (in_array($fieldName, $fieldNames)) { - $fieldsToTransform[$fieldName] = $fieldValue; - } - } - $anchor = CustomLine::findBestAnchor($anchors, $fieldsToTransform); - if (!$anchor) { - error_log('Could not find an anchor!'); - - return $lineItems; - } - - $linesPrepared = CustomLine::prepare( - $anchor, - $fieldsToTransform, - $heightLineTolerance - ); - - foreach ($linesPrepared as $currentLine) { - foreach ($fieldsToTransform as $fieldName => $field) { - foreach ($field->values as $listFieldValue) { - $minMaxY = MinMaxUtils::getMinMaxY($listFieldValue->polygon->getCoordinates()); - if ( - (abs($minMaxY->getMax() - $currentLine->bbox->getMaxY()) <= - $heightLineTolerance) && - (abs($minMaxY->getMin() - $currentLine->bbox->getMinY()) <= - $heightLineTolerance) - ) { - $currentLine->updateField($fieldName, $listFieldValue); - } - } - } - } - - return $linesPrepared; - } -} diff --git a/src/Parsing/Custom/ListField.php b/src/Parsing/Custom/ListField.php deleted file mode 100644 index 621f2a44..00000000 --- a/src/Parsing/Custom/ListField.php +++ /dev/null @@ -1,77 +0,0 @@ -values = []; - $this->reconstructed = $reconstructed; - - if (array_key_exists("values", $rawPrediction)) { - foreach ($rawPrediction['values'] as $value) { - if (array_key_exists("page_id", $value)) { - $pageId = $value["page_id"]; - } - $this->values[] = new ListFieldValue($value, $pageId); - } - } - $this->confidence = 0.0; - } - - /** - * Returns the contents of the list as an array of values. - * - * @return array Contents as an array. - */ - public function contentsList(): array - { - $arr = []; - foreach ($this->values as $value) { - $arr[] = $value->content; - } - - return $arr; - } - - /** - * Returns the contents of a list as a concatenated string. - * - * @param string $separator Separator to repeat and insert between lines. - * @return string - */ - public function contentsString(string $separator = ' '): string - { - return implode($separator, $this->contentsList()); - } - - /** - * @return string String representation. - */ - public function __toString(): string - { - return $this->contentsString(); - } -} diff --git a/src/Parsing/Custom/ListFieldValue.php b/src/Parsing/Custom/ListFieldValue.php deleted file mode 100644 index ecc0defd..00000000 --- a/src/Parsing/Custom/ListFieldValue.php +++ /dev/null @@ -1,51 +0,0 @@ -content = $rawPrediction['content']; - $this->confidence = $rawPrediction['confidence']; - $this->pageId = $pageId; - $this->setPosition($rawPrediction); - } - - - /** - * @return string String representation. - */ - public function __toString(): string - { - return strval($this->content); - } -} diff --git a/src/Parsing/Standard/BaseField.php b/src/Parsing/Standard/BaseField.php index 11827334..1f2b5d92 100644 --- a/src/Parsing/Standard/BaseField.php +++ b/src/Parsing/Standard/BaseField.php @@ -2,12 +2,6 @@ namespace Mindee\Parsing\Standard; -use Mindee\Geometry\BBox; -use Mindee\Geometry\Point; -use Mindee\Geometry\Polygon; - -use function Mindee\Geometry\createBoundingBoxFrom; - /** * Base class for most fields. */ @@ -57,7 +51,7 @@ public function __construct( /** * Compares with the value of another field. * - * @param \Mindee\Parsing\Standard\BaseField $obj Field to compare. + * @param BaseField $obj Field to compare. * @return boolean */ public function __compare(BaseField $obj): bool diff --git a/src/Parsing/Standard/FieldPositionMixin.php b/src/Parsing/Standard/FieldPositionMixin.php index f2d8130e..9be9acc9 100644 --- a/src/Parsing/Standard/FieldPositionMixin.php +++ b/src/Parsing/Standard/FieldPositionMixin.php @@ -12,11 +12,11 @@ trait FieldPositionMixin { /** - * @var \Mindee\Geometry\Polygon A polygon containing the word in the document. + * @var Polygon A polygon containing the word in the document. */ public Polygon $polygon; /** - * @var \Mindee\Geometry\Polygon|null A right rectangle containing the word in the document. + * @var Polygon|null A right rectangle containing the word in the document. */ public ?Polygon $boundingBox; @@ -26,16 +26,12 @@ trait FieldPositionMixin * @param array $rawPrediction Raw prediction array. * @return void */ - protected function setPosition(array $rawPrediction) + protected function setPosition(array $rawPrediction): void { $this->boundingBox = null; $this->polygon = new Polygon(); if (array_key_exists('polygon', $rawPrediction) and isset($rawPrediction['polygon'])) { - $points = []; - foreach ($rawPrediction['polygon'] as $point) { - $points[] = new Point($point[0], $point[1]); - } - $this->polygon = new Polygon($points); + $this->polygon = new Polygon($rawPrediction['polygon']); } if ($this->polygon->getCoordinates()) { $this->boundingBox = PolygonUtils::createBoundingBoxFrom($this->polygon); diff --git a/src/Parsing/Standard/StringField.php b/src/Parsing/Standard/StringField.php index e5baf971..f0319e87 100644 --- a/src/Parsing/Standard/StringField.php +++ b/src/Parsing/Standard/StringField.php @@ -17,7 +17,7 @@ class StringField extends BaseField /** * @var string|null The value as it appears on the document. */ - public $rawValue; + public string|null $rawValue; /** diff --git a/src/Parsing/V2/Field/BaseField.php b/src/Parsing/V2/Field/BaseField.php index 3a9e73b6..c0271d12 100644 --- a/src/Parsing/V2/Field/BaseField.php +++ b/src/Parsing/V2/Field/BaseField.php @@ -37,30 +37,27 @@ public function __construct(array $rawPrediction, int $indentLevel = 0) } } if (array_key_exists("confidence", $rawPrediction) && $rawPrediction["confidence"]) { - $this->confidence = new FieldConfidence($rawPrediction["confidence"]); + $this->confidence = FieldConfidence::from($rawPrediction["confidence"]); } } /** * @param array $rawPrediction Raw prediction array. * @param integer $indentLevel Level of indentation for rst display. - * @return BaseField + * @return ListField|ObjectField|SimpleField * @throws MindeeApiException Throws if the field type isn't recognized. */ - public static function createField(array $rawPrediction, int $indentLevel = 0) + public static function createField(array $rawPrediction, int $indentLevel = 0): ListField|ObjectField|SimpleField { if (array_key_exists('items', $rawPrediction)) { return new ListField($rawPrediction, $indentLevel); } - if (array_key_exists('fields', $rawPrediction)) { return new ObjectField($rawPrediction, $indentLevel); } - if (array_key_exists('value', $rawPrediction)) { return new SimpleField($rawPrediction, $indentLevel); } - throw new MindeeApiException( sprintf('Unrecognized field format in %s.', json_encode($rawPrediction)) ); diff --git a/src/Parsing/V2/Field/FieldConfidence.php b/src/Parsing/V2/Field/FieldConfidence.php index 35af9a10..9caeff94 100644 --- a/src/Parsing/V2/Field/FieldConfidence.php +++ b/src/Parsing/V2/Field/FieldConfidence.php @@ -2,74 +2,10 @@ namespace Mindee\Parsing\V2\Field; -use InvalidArgumentException; - -/** - * Confidence level of a field as returned by the V2 API. - */ -class FieldConfidence +enum FieldConfidence: string { - public const CERTAIN = 'Certain'; - public const HIGH = 'High'; - public const MEDIUM = 'Medium'; - public const LOW = 'Low'; - - /** - * @var string - */ - private string $value; - - /** - * @param string $value Vale provided. - * @throws InvalidArgumentException Throws if an invalid value is provided. - */ - public function __construct(string $value) - { - if (!self::isValid($value)) { - throw new InvalidArgumentException(sprintf( - 'Invalid confidence value "%s". Valid values are: %s', - $value, - implode(', ', self::getValidValues()) - )); - } - $this->value = $value; - } - - /** - * @param string $value Value to check. - * @return boolean True if the value is valid. - */ - public static function isValid(string $value): bool - { - return in_array($value, self::getValidValues(), true); - } - - /** - * @return array - */ - public static function getValidValues(): array - { - return [ - self::CERTAIN, - self::HIGH, - self::MEDIUM, - self::LOW, - ]; - } - - /** - * @return string String representation. - */ - public function getValue(): string - { - return $this->value; - } - - /** - * @return string - */ - public function __toString(): string - { - return $this->value; - } + case Certain = 'Certain'; + case High = 'High'; + case Medium = 'Medium'; + case Low = 'Low'; } diff --git a/src/Product/Custom/CustomV1.php b/src/Product/Custom/CustomV1.php deleted file mode 100644 index fbe6624f..00000000 --- a/src/Product/Custom/CustomV1.php +++ /dev/null @@ -1,39 +0,0 @@ -prediction = new CustomV1Document($rawPrediction['prediction']); - $this->pages = []; - foreach ($rawPrediction['pages'] as $page) { - $this->pages[] = new Page(CustomV1Page::class, $page); - } - } -} diff --git a/src/Product/Custom/CustomV1Document.php b/src/Product/Custom/CustomV1Document.php deleted file mode 100644 index b2b2b214..00000000 --- a/src/Product/Custom/CustomV1Document.php +++ /dev/null @@ -1,74 +0,0 @@ -fields = []; - $this->classifications = []; - - foreach ($rawPrediction as $fieldName => $fieldContents) { - if (array_key_exists("value", $fieldContents)) { - $this->classifications[$fieldName] = new ClassificationField($fieldContents); - } elseif (array_key_exists("values", $fieldContents)) { - $this->fields[$fieldName] = new ListField($fieldContents); - } - } - } - - /** - * Order column fields into line items. - * - * @param array $anchorNames List of possible anchor fields. - * @param array $fieldNames List of all column fields. - * @param float $heightTolerance Height tolerance to apply to lines. - * @return array - */ - public function columnsToLineItems(array $anchorNames, array $fieldNames, float $heightTolerance): array - { - return CustomLine::getLineItems( - $anchorNames, - $fieldNames, - $this->fields, - $heightTolerance - ); - } - - /** - * @return string String representation. - */ - public function __toString(): string - { - $outStr = ""; - foreach ($this->classifications as $classificationName => $classificationValue) { - $outStr .= ":$classificationName: $classificationValue\n"; - } - foreach ($this->fields as $fieldName => $fieldValue) { - $outStr .= ":$fieldName: $fieldValue\n"; - } - return SummaryHelper::cleanOutString($outStr); - } -} diff --git a/src/Product/Custom/CustomV1Page.php b/src/Product/Custom/CustomV1Page.php deleted file mode 100644 index 67fbb736..00000000 --- a/src/Product/Custom/CustomV1Page.php +++ /dev/null @@ -1,42 +0,0 @@ -fields = []; - foreach ($rawPrediction as $fieldName => $fieldContents) { - $this->fields[$fieldName] = new ListField($fieldContents); - } - } - - /** - * @return string String representation. - */ - public function __toString(): string - { - $outStr = ""; - foreach ($this->fields as $fieldName => $fieldValue) { - $outStr .= ":$fieldName: $fieldValue\n"; - } - return SummaryHelper::cleanOutString($outStr); - } -} diff --git a/tests/CLI/MindeeCLICommandTestFunctional.php b/tests/CLI/MindeeCLICommandTestFunctional.php index e3c5ff4a..a35316f8 100644 --- a/tests/CLI/MindeeCLICommandTestFunctional.php +++ b/tests/CLI/MindeeCLICommandTestFunctional.php @@ -3,8 +3,8 @@ namespace CLI; require_once(__DIR__ . "/../../vendor/autoload.php"); -require_once(__DIR__."/../../bin/MindeeCLIDocuments.php"); -require_once(__DIR__."/MindeeCLITestingUtilities.php"); +require_once(__DIR__ . "/../../bin/MindeeCLIDocuments.php"); +require_once(__DIR__ . "/MindeeCLITestingUtilities.php"); use Mindee\CLI\MindeeCLIDocuments; use PHPUnit\Framework\TestCase; @@ -35,9 +35,6 @@ private function runValidCall($productName, $async = false, $initialArgs = []): public function productDataProvider() { $data = []; - $account = getenv('MINDEE_ACCOUNT_SE_TESTS'); - $endpoint = getenv('MINDEE_ENDPOINT_SE_TESTS'); - $data[] = ["custom", false, ["-a", $account, "-e", $endpoint, "-d", "1"]]; $data[] = ["generated", true, ["-a", "mindee", "-e", "invoice_splitter", "-d", "1"]]; foreach (MindeeCLIDocuments::getSpecs() as $productName => $productSpecs) { if ($productName != "custom" && $productName != "generated") { @@ -59,6 +56,9 @@ public function testProduct($productName, $async, $additionnalArgs = []) { $cmdOutput = $this->runValidCall($productName, $async, $additionnalArgs); $this->assertEquals(0, $cmdOutput["code"], $productName . ($async ? " async" : " sync") . " test (code)."); - $this->assertTrue(str_contains($cmdOutput["output"][1], "Document"), $productName . ($async ? " async" : " sync") . " test (string return)."); + $this->assertTrue( + str_contains($cmdOutput["output"][1], "Document"), + $productName . ($async ? " async" : " sync") . " test (string return)." + ); } } diff --git a/tests/ClientV2TestFunctional.php b/tests/ClientV2TestFunctional.php index 092e8691..9eb2a0de 100644 --- a/tests/ClientV2TestFunctional.php +++ b/tests/ClientV2TestFunctional.php @@ -24,7 +24,7 @@ protected function setUp(): void public function testParseFileEmptyMultiPageMustSucceed(): void { $source = new PathInput(__DIR__ . '/resources/file_types/pdf/multipage_cut-2.pdf'); - $inferenceParams = new InferenceParameters($this->modelId, false, true); + $inferenceParams = new InferenceParameters($this->modelId, rag: false, rawText: true); $response = $this->mindeeClient->enqueueAndGetInference($source, $inferenceParams); $this->assertNotNull($response); @@ -60,7 +60,7 @@ public function testParseFileFilledSinglePageMustSucceed(): void { $source = new PathInput(__DIR__ . '/resources/products/financial_document/default_sample.jpg'); - $inferenceParams = new InferenceParameters($this->modelId, false); + $inferenceParams = new InferenceParameters($this->modelId, rag: false); $response = $this->mindeeClient->enqueueAndGetInference($source, $inferenceParams); $this->assertNotNull($response); diff --git a/tests/Geometry/PolygonUtilsTest.php b/tests/Geometry/PolygonUtilsTest.php index 61af484f..ce5b3c2e 100644 --- a/tests/Geometry/PolygonUtilsTest.php +++ b/tests/Geometry/PolygonUtilsTest.php @@ -2,11 +2,11 @@ namespace Geometry; -use Mindee\Error\MindeeGeometryException; use Mindee\Geometry\Point; use Mindee\Geometry\Polygon; use Mindee\Geometry\PolygonUtils; use PHPUnit\Framework\TestCase; +use TypeError; class PolygonUtilsTest extends TestCase { @@ -36,47 +36,47 @@ public function testGivenAValidPolygonMustGetTheValidCentroid() public function testGivenAValidPolygonMustGetTheMinX() { - $this->assertEquals(0.123, PolygonUtils::getMinXCoordinate($this->polygonWhichIsNotRectangle)); + $this->assertEquals(0.123, $this->polygonWhichIsNotRectangle->getMinX()); } public function testGivenAValidPolygonMustGetTheMinY() { - $this->assertEquals(0.53, PolygonUtils::getMinYCoordinate($this->polygonWhichIsNotRectangle)); + $this->assertEquals(0.53, $this->polygonWhichIsNotRectangle->getMinY()); } public function testGivenAValidPolygonMustGetTheMaxX() { - $this->assertEquals(0.175, PolygonUtils::getMaxXCoordinate($this->polygonWhichIsNotRectangle)); + $this->assertEquals(0.175, $this->polygonWhichIsNotRectangle->getMaxX()); } public function testGivenAValidPolygonMustGetTheMaxY() { - $this->assertEquals(0.546, PolygonUtils::getMaxYCoordinate($this->polygonWhichIsNotRectangle)); + $this->assertEquals(0.546, $this->polygonWhichIsNotRectangle->getMaxY()); } public function testMergePolygonsWithTwoNotNullMustGetAValidPolygon() { $mergedPolygon = PolygonUtils::merge($this->polygon1, $this->polygon2); - $this->assertEquals(0.442, PolygonUtils::getMinYCoordinate($mergedPolygon)); - $this->assertEquals(0.081, PolygonUtils::getMinXCoordinate($mergedPolygon)); - $this->assertEquals(0.451, PolygonUtils::getMaxYCoordinate($mergedPolygon)); - $this->assertEquals(0.26, PolygonUtils::getMaxXCoordinate($mergedPolygon)); + $this->assertEquals(0.442, $mergedPolygon->getMinY()); + $this->assertEquals(0.081, $mergedPolygon->getMinX()); + $this->assertEquals(0.451, $mergedPolygon->getMaxY()); + $this->assertEquals(0.26, $mergedPolygon->getMaxX()); } public function testMergeWithNullPolygonMustThrow() { - $this->expectException(MindeeGeometryException::class); + $this->expectException(TypeError::class); PolygonUtils::merge(null, null); } public function testMergeWith1PolygonAndANullPolygonMustGetPolygon() { - $mergedPolygon = PolygonUtils::merge($this->polygon1, null); + $mergedPolygon = PolygonUtils::merge($this->polygon1, new Polygon([])); - $this->assertEquals(0.442, PolygonUtils::getMinYCoordinate($mergedPolygon)); - $this->assertEquals(0.081, PolygonUtils::getMinXCoordinate($mergedPolygon)); - $this->assertEquals(0.451, PolygonUtils::getMaxYCoordinate($mergedPolygon)); - $this->assertEquals(0.15, PolygonUtils::getMaxXCoordinate($mergedPolygon)); + $this->assertEquals(0.442, $mergedPolygon->getMinY()); + $this->assertEquals(0.081, $mergedPolygon->getMinX()); + $this->assertEquals(0.451, $mergedPolygon->getMaxY()); + $this->assertEquals(0.15, $mergedPolygon->getMaxX()); } } diff --git a/tests/Parsing/V2/InferenceTest.php b/tests/Parsing/V2/InferenceTest.php index 229bdb2c..57cb51b2 100644 --- a/tests/Parsing/V2/InferenceTest.php +++ b/tests/Parsing/V2/InferenceTest.php @@ -335,7 +335,7 @@ public function testCoordinatesAndLocationDataMustBeAccessible(): void new Point(0.9015345, 0.23731850000000002), $location->polygon->getCentroid() ); - $this->assertEquals(FieldConfidence::MEDIUM, $dateField->confidence); - $this->assertEquals('Medium', $dateField->confidence->getValue()); + $this->assertEquals(FieldConfidence::Medium, $dateField->confidence); + $this->assertEquals('Medium', $dateField->confidence->value); } } diff --git a/tests/Product/Custom/CustomV1LineItemsTest.php b/tests/Product/Custom/CustomV1LineItemsTest.php deleted file mode 100644 index 874c0a43..00000000 --- a/tests/Product/Custom/CustomV1LineItemsTest.php +++ /dev/null @@ -1,102 +0,0 @@ -customV1LineItemsDocV1 = $lineItemsDoc->inference->prediction; - $page = new Page( - CustomV1Page::class, - $rawDataV1Complete["document"]["inference"]["pages"][0] - ); - $this->customV1LineItemsPage0V1 = $page->prediction; - - $jsonV1CompleteV2 = file_get_contents( - ProductSharedData::getProductDataDir() . "custom/response_v2/line_items/single_table_01.json" - ); - $rawDataV1CompleteV2 = json_decode($jsonV1CompleteV2, true); - $lineItemsDocV2 = new Document(CustomV1::class, $rawDataV1CompleteV2["document"]); - $this->customV1LineItemsDocV2 = $lineItemsDocV2->inference->prediction; - $pageV2 = new Page( - CustomV1Page::class, - $rawDataV1CompleteV2["document"]["inference"]["pages"][0] - ); - $this->customV1LineItemsPage0V2 = $pageV2->prediction; - $this->anchors = ["beneficiary_name"]; - $this->columns = [ - "beneficiary_birth_date", - "beneficiary_number", - "beneficiary_name", - "beneficiary_rank", - ]; - } - - public function testSingleTable01() - { - assert($this->customV1LineItemsDocV1 instanceof CustomV1Document); - $lineItemsDoc = $this->customV1LineItemsDocV1->columnsToLineItems($this->anchors, $this->columns, 0.011); - assert($this->customV1LineItemsPage0V1 instanceof CustomV1Page); - $lineItemsPage = $this->customV1LineItemsPage0V1->columnsToLineItems($this->anchors, $this->columns, 0.011); - foreach ([$lineItemsDoc, $lineItemsPage] as $lineItems) { - $this->assertEquals(3, count($lineItems)); - - $this->assertEquals("JAMES BOND 007", $lineItems[0]->fields["beneficiary_name"]->content); - $this->assertEquals("1970-11-11", $lineItems[0]->fields["beneficiary_birth_date"]->content); - $this->assertEquals(1, $lineItems[0]->rowNumber); - - $this->assertEquals("HARRY POTTER", $lineItems[1]->fields["beneficiary_name"]->content); - $this->assertEquals("2010-07-18", $lineItems[1]->fields["beneficiary_birth_date"]->content); - $this->assertEquals(2, $lineItems[1]->rowNumber); - - $this->assertEquals("DRAGO MALFOY", $lineItems[2]->fields["beneficiary_name"]->content); - $this->assertEquals("2015-07-05", $lineItems[2]->fields["beneficiary_birth_date"]->content); - $this->assertEquals(3, $lineItems[2]->rowNumber); - } - } - - public function testSingleTable02() - { - assert($this->customV1LineItemsDocV2 instanceof CustomV1Document); - $lineItemsDoc = $this->customV1LineItemsDocV2->columnsToLineItems($this->anchors, $this->columns, 0.011); - assert($this->customV1LineItemsPage0V2 instanceof CustomV1Page); - $lineItemsPage = $this->customV1LineItemsPage0V2->columnsToLineItems($this->anchors, $this->columns, 0.011); - foreach ([$lineItemsDoc, $lineItemsPage] as $lineItems) { - $this->assertEquals(3, count($lineItems)); - - $this->assertEquals("JAMES BOND 007", $lineItems[0]->fields["beneficiary_name"]->content); - $this->assertEquals("1970-11-11", $lineItems[0]->fields["beneficiary_birth_date"]->content); - $this->assertEquals(1, $lineItems[0]->rowNumber); - - $this->assertEquals("HARRY POTTER", $lineItems[1]->fields["beneficiary_name"]->content); - $this->assertEquals("2010-07-18", $lineItems[1]->fields["beneficiary_birth_date"]->content); - $this->assertEquals(2, $lineItems[1]->rowNumber); - - $this->assertEquals("DRAGO MALFOY", $lineItems[2]->fields["beneficiary_name"]->content); - $this->assertEquals("2015-07-05", $lineItems[2]->fields["beneficiary_birth_date"]->content); - $this->assertEquals(3, $lineItems[2]->rowNumber); - } - } -} diff --git a/tests/Product/Custom/CustomV1Test.php b/tests/Product/Custom/CustomV1Test.php deleted file mode 100644 index e2a450a0..00000000 --- a/tests/Product/Custom/CustomV1Test.php +++ /dev/null @@ -1,81 +0,0 @@ -customV1CompleteDoc = new Document(CustomV1::class, $rawDataV1Complete["document"]); - - $jsonV1Empty = file_get_contents( - ProductSharedData::getProductDataDir() . "custom/response_v1/empty.json" - ); - $rawDataV1Empty = json_decode($jsonV1Empty, true); - $this->customV1EmptyDoc = new Document(CustomV1::class, $rawDataV1Empty["document"]); - } - - public function testEmptyDoc(): void - { - $documentPrediction = $this->customV1EmptyDoc->inference->prediction; - assert($documentPrediction instanceof CustomV1Document); - foreach ($documentPrediction->fields as $fieldName => $field) { - $this->assertGreaterThan(0, strlen($fieldName)); - $this->assertInstanceOf(ListField::class, $field); - $this->assertEquals(0, count($field->values)); - } - foreach ($documentPrediction->classifications as $classificationName => $classification) { - $this->assertGreaterThan(0, strlen($classificationName)); - $this->assertInstanceOf(ClassificationField::class, $classification); - $this->assertNull($classification->value); - } - } - - public function testCompleteDoc() - { - $documentPrediction = $this->customV1CompleteDoc->inference->prediction; - assert($documentPrediction instanceof CustomV1Document); - $docStr = file_get_contents(ProductSharedData::getProductDataDir() . "custom/response_v1/summary_full.rst"); - foreach ($documentPrediction->fields as $fieldName => $field) { - $this->assertGreaterThan(0, strlen($fieldName)); - $this->assertInstanceOf(ListField::class, $field); - $this->assertGreaterThan(0, count($field->values)); - $this->assertEquals(count($field->values), count($field->contentsList())); - foreach ($field->values as $value) { - $this->assertInstanceOf(ListFieldValue::class, $value); - $this->assertNotEquals("", $value->content); - { - $this->assertInstanceOf(Polygon::class, $value->boundingBox); - $this->assertEquals(4, count($value->boundingBox->getCoordinates())); - $this->assertNotEquals(0.0, $value->confidence); - } - } - } - foreach ($documentPrediction->classifications as $classificationName => $classification) { - $this->assertNotEquals(0, strlen($classificationName)); - $this->assertInstanceOf(ClassificationField::class, $classification); - $this->assertNotEquals("", $classification->value); - } - $this->assertEquals(strval($this->customV1CompleteDoc), $docStr); - } -} diff --git a/tests/Product/Custom/CustomV1V2Test.php b/tests/Product/Custom/CustomV1V2Test.php deleted file mode 100644 index 283de967..00000000 --- a/tests/Product/Custom/CustomV1V2Test.php +++ /dev/null @@ -1,81 +0,0 @@ -customV1CompleteDoc = new Document(CustomV1::class, $rawDataV1Complete["document"]); - - $jsonV1Empty = file_get_contents( - ProductSharedData::getProductDataDir() . "custom/response_v2/empty.json" - ); - $rawDataV1Empty = json_decode($jsonV1Empty, true); - $this->customV1EmptyDoc = new Document(CustomV1::class, $rawDataV1Empty["document"]); - } - - public function testEmptyDoc(): void - { - $documentPrediction = $this->customV1EmptyDoc->inference->prediction; - assert($documentPrediction instanceof CustomV1Document); - foreach ($documentPrediction->fields as $fieldName => $field) { - $this->assertGreaterThan(0, strlen($fieldName)); - $this->assertInstanceOf(ListField::class, $field); - $this->assertEquals(0, count($field->values)); - } - foreach ($documentPrediction->classifications as $classificationName => $classification) { - $this->assertGreaterThan(0, strlen($classificationName)); - $this->assertInstanceOf(ClassificationField::class, $classification); - $this->assertNull($classification->value); - } - } - - public function testCompleteDoc() - { - $documentPrediction = $this->customV1CompleteDoc->inference->prediction; - assert($documentPrediction instanceof CustomV1Document); - $docStr = file_get_contents(ProductSharedData::getProductDataDir() . "custom/response_v2/summary_full.rst"); - foreach ($documentPrediction->fields as $fieldName => $field) { - $this->assertGreaterThan(0, strlen($fieldName)); - $this->assertInstanceOf(ListField::class, $field); - $this->assertGreaterThan(0, count($field->values)); - $this->assertEquals(count($field->values), count($field->contentsList())); - foreach ($field->values as $value) { - $this->assertInstanceOf(ListFieldValue::class, $value); - $this->assertNotEquals("", $value->content); - { - $this->assertInstanceOf(Polygon::class, $value->boundingBox); - $this->assertEquals(4, count($value->boundingBox->getCoordinates())); - $this->assertNotEquals(0.0, $value->confidence); - } - } - } - foreach ($documentPrediction->classifications as $classificationName => $classification) { - $this->assertNotEquals(0, strlen($classificationName)); - $this->assertInstanceOf(ClassificationField::class, $classification); - $this->assertNotEquals("", $classification->value); - } - $this->assertEquals(strval($this->customV1CompleteDoc), $docStr); - } -} diff --git a/tests/test_code_samples.sh b/tests/test_code_samples.sh index 3b6300a8..d000d605 100755 --- a/tests/test_code_samples.sh +++ b/tests/test_code_samples.sh @@ -52,10 +52,10 @@ do sed "s/my-api-key/$API_KEY/" "${f}" > $OUTPUT_FILE sed -i "s/\/path\/to\/the\/file.ext/..\/mindee-api-php\/tests\/resources\/file_types\/pdf\/blank_1.pdf/" $OUTPUT_FILE + # Only keeping the sample for display in the UI if echo "$f" | grep -q "custom_v1.txt" then - sed -i "s/my-account/$ACCOUNT/g" $OUTPUT_FILE - sed -i "s/my-endpoint/$ENDPOINT/g" $OUTPUT_FILE + continue fi if echo "${f}" | grep -q "default.txt"