Completed
Push — master ( c5f597...2e83ef )
by John
10s
created

BarcodeRenderer::convertToFontCode()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 63
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 22
CRAP Score 2

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 63
ccs 22
cts 22
cp 1
rs 9.4347
cc 2
eloc 22
nc 2
nop 1
crap 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Graze\CiffRenderer\Field\Renderer;
4
5
use Graze\CiffRenderer\Field\Renderer\FixedTextRenderer;
6
use Graze\CiffRenderer\Field\Renderer\Font\FontFace;
7
8
class BarcodeRenderer extends FixedTextRenderer
9
{
10
    const FONT_SIZE_MULTIPLIER = 6.2;
11
12
    /**
13
     * @return string
14
     */
15
    public function getFontFace()
16
    {
17
        return FontFace::FACE_BARCODE;
18
    }
19
20
    /**
21
     * @return int
0 ignored issues
show
Documentation introduced by
Should the return type not be double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
22
     */
23
    protected function getFontSize()
24
    {
25
        return parent::getFontSize() * self::FONT_SIZE_MULTIPLIER;
26
    }
27
28
    /**
29
     * @return Intervention/Image/Image
0 ignored issues
show
Documentation introduced by
The doc-type Intervention/Image/Image could not be parsed: Unknown type name "Intervention/Image/Image" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
30
     */
31 1
    public function render()
32
    {
33 1
        $canvas = $this->getImageManager()->canvas($this->getWidth(), $this->getHeight(), '#000');
34
35 1
        $fontResolver = $this->getFontResolver();
36
37 1
        $fontPath = $fontResolver($this->getFontFace());
38
39 1
        $fontCallback = function ($font) use ($fontPath) {
40
            $font->file($fontPath);
41
            $font->size($this->getFontSize());
42
            $font->color('#fff');
43
            $font->align('center');
44
            $font->valign('middle');
45 1
        };
46
47 1
        $canvas->text($this->getBarcode(), $this->getWidth() / 2, $this->getHeight(), $fontCallback);
48
49 1
        return $canvas;
50
    }
51
52
    /**
53
     * Only EAN13 currently supported.
54
     *
55
     * @return string
56
     */
57 1
    private function getBarcode()
58
    {
59 1
        $barcode = $this->getText();
60
61
        // add up each digit in the barcode - odd digits counting
62
        // from the right are tripled before being added
63 1
        $sum = 0;
64 1
        $triple = true;
65 1
        for ($i = strlen($barcode)-1; $i >= 0; $i--) {
66 1
            $sum += ($triple ? 3 : 1) * $barcode[$i];
67 1
            $triple = !$triple;
68 1
        }
69
70
        //check digit is the inverse remainder after / by 10
71
        //e.g. 4 becomes 6, 8 becomes 2 etc...
72 1
        $remainder = $sum % 10;
73
74 1
        if ($remainder > 0) {
75
            $remainder = 10 - $remainder;
76
        }
77
78 1
        return $this->convertToFontCode($barcode . $remainder);
79
    }
80
81
    /**
82
     * @param string $barcode
83
     * @return string
84
     */
85 1
    private function convertToFontCode($barcode)
86
    {
87
        /**
88
         * The barcode is split into the following sections:
89
         *  First digit
90
         *  First group of 6 digits (2nd-7th)
91
         *  Last group of 6 digits (8th-13th)
92
         *      e.g.        1234567890128
93
         *      becomes     1   234567  890128
94
         *
95
         * The font converts the first digit to a char between q-z
96
         *
97
         * The first group of digits are converted to chars starting at either A or Q,
98
         * the first digit affects the format of the first group as follows:
99
         *  1st digit     First group format
100
         *      0           AAAAAA
101
         *      1           AAQAQQ
102
         *      2           AAQQAQ
103
         *      3           AAQQQA
104
         *      4           AQAAQQ
105
         *      5           AQQAAQ
106
         *      6           AQQQAA
107
         *      7           AQAQAQ
108
         *      8           AQAQQA
109
         *      9           AQQAQA
110
         *
111
         * The last group of digits remain unchanged
112
         *
113
         * The actual format used by the font is:
114
         *       firstDigit  {{{{{|  firstGroup  {|{  secondGroup  |
115
         */
116
117
        // convert first digit
118 1
        $firstDigit = (int)substr($barcode, 0, 1);
119 1
        $firstDigitChar = chr(113 + $firstDigit);
120
121
        // convert first group
122 1
        $firstGroup = '';
123
        $firstGroupFormats = [
124 1
            'AAAAAA',
125 1
            'AAQAQQ',
126 1
            'AAQQAQ',
127 1
            'AAQQQA',
128 1
            'AQAAQQ',
129 1
            'AQQAAQ',
130 1
            'AQQQAA',
131 1
            'AQAQAQ',
132 1
            'AQAQQA',
133
            'AQQAQA'
134 1
        ];
135 1
        $firstGroupFormat = $firstGroupFormats[$firstDigit];
136 1
        for ($i = 1; $i <= 6; $i++) {
137 1
            $digit = (int) substr($barcode, $i, 1);
138 1
            $startingChar = substr($firstGroupFormat, $i - 1, 1);
139 1
            $firstGroup .= chr(ord($startingChar) + $digit);
140 1
        }
141
142
        // extract second group
143 1
        $secondGroup = substr($barcode, 7);
144
145
        // combine the barcode with the special chars used by the font
146 1
        return $firstDigitChar.'{{{{{|'.$firstGroup.'{|{'.$secondGroup.'|';
147
    }
148
}
149