Skip to content

Commit 93821ba

Browse files
authored
Merge pull request #32 from fawno/EAN-13-barcodes
EAN13 Barcode
2 parents 5505692 + 8efa75d commit 93821ba

10 files changed

Lines changed: 532 additions & 0 deletions

File tree

barcode/BarcodeException.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Fawno\Barcode;
5+
6+
use Exception;
7+
8+
class BarcodeException extends Exception {}

barcode/EAN13.php

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Fawno\Barcode;
5+
6+
use Fawno\Barcode\BarcodeException;
7+
8+
class EAN13 {
9+
// EAN Parity Encodig Table => EAN_pet
10+
protected const EAN_pet = [
11+
0 => ['O', 'O', 'O', 'O', 'O', 'O'],
12+
1 => ['O', 'O', 'E', 'O', 'E', 'E'],
13+
2 => ['O', 'O', 'E', 'E', 'O', 'E'],
14+
3 => ['O', 'O', 'E', 'E', 'E', 'O'],
15+
4 => ['O', 'E', 'O', 'O', 'E', 'E'],
16+
5 => ['O', 'E', 'E', 'O', 'O', 'E'],
17+
6 => ['O', 'E', 'E', 'E', 'O', 'O'],
18+
7 => ['O', 'E', 'E', 'E', 'O', 'E'],
19+
8 => ['O', 'E', 'O', 'E', 'E', 'O'],
20+
9 => ['O', 'E', 'E', 'O', 'E', 'O'],
21+
];
22+
23+
// EAN Character Set Encoding Table => EAN_cet
24+
protected const EAN_cet = [
25+
0 => ['O' => '0001101', 'E' => '0100111', 'R' => '1110010'],
26+
1 => ['O' => '0011001', 'E' => '0110011', 'R' => '1100110'],
27+
2 => ['O' => '0010011', 'E' => '0011011', 'R' => '1101100'],
28+
3 => ['O' => '0111101', 'E' => '0100001', 'R' => '1000010'],
29+
4 => ['O' => '0100011', 'E' => '0011101', 'R' => '1011100'],
30+
5 => ['O' => '0110001', 'E' => '0111001', 'R' => '1001110'],
31+
6 => ['O' => '0101111', 'E' => '0000101', 'R' => '1010000'],
32+
7 => ['O' => '0111011', 'E' => '0010001', 'R' => '1000100'],
33+
8 => ['O' => '0110111', 'E' => '0001001', 'R' => '1001000'],
34+
9 => ['O' => '0001011', 'E' => '0010111', 'R' => '1110100'],
35+
];
36+
37+
// UPC 2-Digit Parity Pattern => UPC_2dpp
38+
protected const UPC_2dpp = [
39+
0 => ['O', 'O'],
40+
1 => ['O', 'E'],
41+
2 => ['E', 'O'],
42+
3 => ['E', 'E'],
43+
];
44+
45+
// UPC 5-Digit Parity Pattern => UPC_5dpp
46+
protected const UPC_5dpp = [
47+
0 => ['E', 'E', 'O', 'O', 'O'],
48+
1 => ['E', 'O', 'E', 'O', 'O'],
49+
2 => ['E', 'O', 'O', 'E', 'O'],
50+
3 => ['E', 'O', 'O', 'O', 'E'],
51+
4 => ['O', 'E', 'E', 'O', 'O'],
52+
5 => ['O', 'O', 'E', 'E', 'O'],
53+
6 => ['O', 'O', 'O', 'E', 'E'],
54+
7 => ['O', 'E', 'O', 'E', 'O'],
55+
8 => ['O', 'E', 'O', 'O', 'E'],
56+
9 => ['O', 'O', 'E', 'O', 'E'],
57+
];
58+
59+
protected string $message;
60+
protected string $supplemental;
61+
62+
/**
63+
* Construct EAN13 with message and supplemental.
64+
*
65+
* @param null|string $message Message of EAN13 code
66+
* @param null|string $supplemental Supplemental code for EAN13
67+
* @return void
68+
* @throws BarcodeException If message or supplemental has invalid length BarcodeException is thrown.
69+
*/
70+
private function __construct (?string $message = null, ?string $supplemental = null) {
71+
if (is_null($this->setMessage($message))) {
72+
throw new BarcodeException('Message invalid', 1);
73+
}
74+
75+
if (is_null($this->setSupplemental($supplemental))) {
76+
throw new BarcodeException('Supplemental invalid', 1);
77+
}
78+
}
79+
80+
/**
81+
* Create EAN13 code with message and optional supplemental code.
82+
*
83+
* @param null|string $message Message of EAN13
84+
* @param null|string $supplemental Supplemental code
85+
* @return EAN13
86+
* @throws BarcodeException If message or supplemental has invalid length BarcodeException is thrown.
87+
*/
88+
public static function create (?string $message = null, ?string $supplemental = null) : EAN13 {
89+
return new EAN13($message, $supplemental);
90+
}
91+
92+
/**
93+
* Get message of EAN13 with checksum digit
94+
*
95+
* @return null|string EAN13 message
96+
*/
97+
public function getMessage () : ?string {
98+
return $this->message ?: null;
99+
}
100+
101+
/**
102+
* Set message of EAN13 code
103+
*
104+
* @param null|string $message Message of EAN13
105+
* @return null|int Checksum of EAN13. NULL is returned if message has invalid length. If message is cleared with void string or NULL, -1 is returned.
106+
*/
107+
public function setMessage (?string $message = null) : ?int {
108+
$this->message = substr(preg_replace('/\D/', '', (string) $message), 0, 12);
109+
110+
$checksum = self::getBarcodeChecksum();
111+
112+
$this->message = is_int($checksum) ? $this->message . $checksum : '';
113+
114+
if ($message and is_null($checksum)) {
115+
$this->message = '';
116+
return null;
117+
}
118+
119+
return $this->message ? $checksum : -1;
120+
}
121+
122+
/**
123+
* Get supplemental code
124+
*
125+
* @return null|string Supplemental
126+
*/
127+
public function getSupplemental () : ?string {
128+
return $this->supplemental ?: null;
129+
}
130+
131+
/**
132+
* Set the supplemental code for EAN13 code
133+
*
134+
* @param null|string $supplemental Supplemental code
135+
* @return null|int Checksum of supplemental. NULL is returned if supplemental has invalid length. If supplemental is cleared with void string or NULL, -1 is returned.
136+
*/
137+
public function setSupplemental (?string $supplemental = null) : ?int {
138+
$this->supplemental = preg_replace('/\D/', '', (string) $supplemental);
139+
140+
$checksum = self::getSupplementalChecksum();
141+
142+
if ($supplemental and is_null($checksum)) {
143+
$this->supplemental = '';
144+
return null;
145+
}
146+
147+
return $this->supplemental ? $checksum : -1;
148+
}
149+
150+
/**
151+
* Computes the EAN13 checksum
152+
*
153+
* @return null|int NULL is returned if mesage has invalid length
154+
*/
155+
public function getBarcodeChecksum () : ?int {
156+
$message = substr($this->message, 0, 12);
157+
158+
if (strlen($message) != 12) {
159+
return null;
160+
}
161+
162+
$checksum = 0;
163+
foreach (str_split(strrev($message)) as $pos => $val) {
164+
$checksum += $val * (3 - 2 * ($pos % 2));
165+
}
166+
167+
return ((10 - ($checksum % 10)) % 10);
168+
}
169+
170+
/**
171+
* Computes the UPC checksum for supplemental code of EAN13
172+
*
173+
* @return null|int NULL is returned if supplemental has invalid length
174+
*/
175+
public function getSupplementalChecksum () : ?int {
176+
if (strlen($this->supplemental) == 2) {
177+
return ($this->supplemental % 4);
178+
}
179+
180+
if (strlen($this->supplemental) == 5) {
181+
$supp_checksum = 0;
182+
foreach (str_split(strrev($this->supplemental)) as $pos => $val ) {
183+
$supp_checksum += $val * (3 + 6 * ($pos % 2));
184+
}
185+
return ($supp_checksum % 10);
186+
}
187+
188+
return null;
189+
}
190+
191+
/**
192+
* Get EAN13 left hand bars coded
193+
*
194+
* @return null|string Left hand bars of EAN13 code
195+
*/
196+
public function getBarcodeLeftHand () : ?string {
197+
$lh_coded = '';
198+
199+
foreach (str_split(substr($this->message, 1, 6)) as $pos => $val) {
200+
$lh_coded .= self::EAN_cet[$val][self::EAN_pet[$this->message[0]][$pos]];
201+
}
202+
203+
return $lh_coded ?: null;
204+
}
205+
206+
/**
207+
* Get EAN13 right hand bars coded
208+
*
209+
* @return null|string Right hand bars of EAN13 code
210+
*/
211+
public function getBarcodeRightHand () : ?string {
212+
$rh_coded = '';
213+
214+
foreach (str_split(substr($this->message, 7, 6)) as $pos => $val) {
215+
$rh_coded .= self::EAN_cet[$val]['R'];
216+
}
217+
218+
return $rh_coded ?: null;
219+
}
220+
221+
/**
222+
* Get EAN13 supplemental bars coded
223+
*
224+
* @return null|string EAN13 supplemental bars
225+
*/
226+
public function getBarcodeSupplemental () : ?string {
227+
$supp_coded = '';
228+
229+
$supp_checksum = $this->getSupplementalChecksum();
230+
231+
$table = (strlen($this->supplemental) == 2) ? self::UPC_2dpp : self::UPC_5dpp;
232+
foreach(str_split($this->supplemental) as $pos => $val) {
233+
$supp_coded .= self::EAN_cet[$val][$table[$supp_checksum][$pos]] . '01';
234+
}
235+
236+
return $supp_coded ? '1011' . substr($supp_coded, 0, -2) : null;
237+
}
238+
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"autoload": {
2828
"psr-4": {
2929
"Fawno\\FPDF\\": "src/",
30+
"Fawno\\Barcode\\": "barcode/",
3031
"FPDF\\Scripts\\": "scripts/"
3132
},
3233
"classmap": [

src/FawnoFPDF.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
use Fawno\FPDF\Traits\CMYKTrait;
77
use Fawno\FPDF\Traits\PDFMacroableTrait;
88
use Fawno\FPDF\PDFWrapper;
9+
use Fawno\FPDF\Traits\BasicFunctionsTrait;
10+
use Fawno\FPDF\Traits\EAN13Trait;
911
use Fawno\FPDF\Traits\FontsTrait;
1012
use FPDF\Scripts\Attachments\AttachmentsTrait;
1113
use FPDF\Scripts\PDFBookmark\PDFBookmarkTrait;
@@ -40,6 +42,8 @@ class FawnoFPDF extends PDFWrapper {
4042
use PDFMultiCellsTableTrait;
4143
use PDFTransformTrait;
4244
use PDFCircularTextTrait;
45+
use EAN13Trait;
46+
use BasicFunctionsTrait;
4347

4448
protected function _putresources () {
4549
parent::_putresources();

src/Traits/BasicFunctionsTrait.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Fawno\FPDF\Traits;
5+
6+
trait BasicFunctionsTrait {
7+
/**
8+
* Get the actual scale factor
9+
*
10+
* @return float Scale factor
11+
*/
12+
public function getScaleFactor () : float {
13+
return $this->k;
14+
}
15+
16+
/**
17+
* Converts a value from points to the document unit
18+
*
19+
* @param float $val Value in points
20+
* @return float Value in document units
21+
*/
22+
public function fromPt (float $val) : float {
23+
return $val / $this->k;
24+
}
25+
26+
/**
27+
* Converts a value from the document unit to points
28+
* @param float $val Value in document units
29+
* @return float Value in points
30+
*/
31+
public function toPt (float $val) : float {
32+
return $val * $this->k;
33+
}
34+
35+
/**
36+
* Converts a value from millimeters to points
37+
*
38+
* @param float $val Value in millemeters
39+
* @return float Value in points
40+
*/
41+
public function mm2Pt (float $val) : float {
42+
return $val * 720 / 254;
43+
}
44+
45+
/**
46+
* Converts a value from centimeters to points
47+
*
48+
* @param float $val Value in centimeters
49+
* @return float Value in points
50+
*/
51+
public function cm2Pt (float $val) : float {
52+
return $val * 7200 / 254;
53+
}
54+
55+
/**
56+
* Converts a value from inches to points
57+
*
58+
* @param float $val Value in inches
59+
* @return float Value in points
60+
*/
61+
public function in2Pt (float $val) : float {
62+
return $val * 72;
63+
}
64+
}

0 commit comments

Comments
 (0)