Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
TwoDAbstract
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
3 / 3
9
100.00% covered (success)
100.00%
1 / 1
 get
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 generateCodeArray
n/a
0 / 0
n/a
0 / 0
0
 createImage
100.00% covered (success)
100.00%
25 / 25
100.00% covered (success)
100.00%
1 / 1
7
 calculateDimensions
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Jingga
4 *
5 * PHP Version 8.1
6 *
7 * @package   phpOMS\Utils\Barcode
8 * @author    Nicola Asuni - Tecnick.com LTD - www.tecnick.com <info@tecnick.com>
9 * @copyright Copyright (C) 2010 - 2014  Nicola Asuni - Tecnick.com LTD
10 * @license   GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
11 * @version   1.0.0
12 * @link      https://jingga.app
13 */
14declare(strict_types=1);
15
16namespace phpOMS\Utils\Barcode;
17
18/**
19 * 2DAbstract class.
20 *
21 * @package phpOMS\Utils\Barcode
22 * @license GNU-LGPL v3 (http://www.gnu.org/copyleft/lesser.html)
23 * @link    https://jingga.app
24 * @since   1.0.0
25 */
26abstract class TwoDAbstract extends CodeAbstract
27{
28    /**
29     * {@inheritdoc}
30     */
31    public function get() : mixed
32    {
33        $codeArray = $this->generateCodeArray();
34
35        return $this->createImage($codeArray);
36    }
37
38    /**
39     * Generate code array
40     *
41     * @return array
42     *
43     * @since 1.0.0
44     */
45    abstract public function generateCodeArray() : array;
46
47    /**
48     * Create barcode image
49     *
50     * @param array $codeArray Code array to render
51     *
52     * @return \GdImage
53     *
54     * @throws \Exception
55     *
56     * @since 1.0.0
57     */
58    protected function createImage(array $codeArray) : mixed
59    {
60        $dimensions = $this->calculateDimensions($codeArray);
61        $image      = \imagecreate($dimensions['width'], $dimensions['height']);
62
63        if ($image === false) {
64            throw new \Exception(); // @codeCoverageIgnore
65        }
66
67        $black = \imagecolorallocate($image, 0, 0, 0);
68        $white = \imagecolorallocate($image, 255, 255, 255);
69
70        if ($white === false || $black === false) {
71            throw new \Exception(); // @codeCoverageIgnore
72        }
73
74        \imagefill($image, 0, 0, $white);
75
76        $width  = \count($codeArray);
77        $height = \count(\reset($codeArray));
78
79        $multiplier = (int) (($dimensions['width'] - 2 * $this->margin) / $width);
80
81        $locationX = $this->margin;
82
83        // @todo: Allow manual dimensions
84        for ($posX = 0; $posX < $width; ++$posX) {
85            $locationY = $this->margin;
86
87            for ($posY = 0; $posY < $height; ++$posY) {
88                \imagefilledrectangle(
89                    $image,
90                    $locationX,
91                    $locationY,
92                    $locationX + $multiplier,
93                    $locationY + $multiplier,
94                    $codeArray[$posY][$posX] ? $black : $white
95                );
96
97                $locationY += $multiplier;
98            }
99
100            $locationX += $multiplier;
101        }
102
103        return $image;
104    }
105
106    /**
107     * Calculate the code dimensions
108     *
109     * @param array $codeArray Code string to render
110     *
111     * @return array<string, int>
112     *
113     * @since 1.0.0
114     */
115    private function calculateDimensions(array $codeArray) : array
116    {
117        $matrixDimension = \max(\count($codeArray), \count(\reset($codeArray)));
118        $imageDimension  = \max($this->dimension['width'], $this->dimension['width']);
119
120        $multiplier = (int) (($imageDimension - 2 * $this->margin) / $matrixDimension);
121
122        $dimensions['width']  = (int) ($matrixDimension * $multiplier + 2 * $this->margin);
123        $dimensions['height'] = (int) ($matrixDimension * $multiplier + 2 * $this->margin);
124
125        return $dimensions;
126    }
127}