Skip to content

Commit b59e18d

Browse files
authored
Support other barcodes (#32)
* Support other barcodes * Add drawBarcode test * Fix QR, Code39 an others
1 parent 59eed46 commit b59e18d

6 files changed

Lines changed: 166 additions & 17 deletions

File tree

src/AbstractBuilder.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,23 @@ abstract public function drawCircle(
138138
bool $invert = false
139139
): void;
140140

141+
/**
142+
* @param string $type Barcode type, from Zpl\Enums\Barcode values
143+
* @param float $x X position in user units
144+
* @param float $y Y position in user units
145+
* @param float $height height of the barcode in user units
146+
* @param string $data Data to draw the barcode
147+
* @param bool $printData Whether to print the data or not
148+
* @param bool $labelAbove Text data position above or not
149+
* @param string $orientation The text orientation. Available options:
150+
* N = normal
151+
* R = rotated 90 degrees
152+
* I = inverted 180 degrees
153+
* B = bottom-up 270 degrees, read from bottom up
154+
* @param int $size Scale of the barcode (1-9)
155+
*/
156+
abstract public function drawBarcode(string $type, float $x, float $y, float $height, string $data, bool $printData = false, bool $labelAbove = false, string $orientation = 'N', int $size = 0): void;
157+
141158
/**
142159
* @param float $x X position in user units
143160
* @param float $y Y position in user units

src/Enums/Barcode.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
namespace Zpl\Enums;
4+
5+
class Barcode
6+
{
7+
const AZTEK = 'B0';
8+
const CODE11 = 'B1';
9+
const INTERLEAVED2 = 'B2';
10+
const CODE39 = 'B3';
11+
const CODE49 = 'B4';
12+
const PLANET = 'B5';
13+
const PDF417 = 'B7';
14+
const EAN8 = 'B8';
15+
const UPCE = 'B9';
16+
const CODE93 = 'BA';
17+
const CODABLOCK = 'BB';
18+
const CODE128 = 'BC';
19+
const UPS = 'BD';
20+
const EAN13 = 'BE';
21+
const MICROPDF417 = 'BF';
22+
const INDUSTRIAL2 = 'BI';
23+
const STANDARD2 = 'BJ';
24+
const ANSI = 'BK';
25+
const LOGMARS = 'BL';
26+
const MSI = 'BM';
27+
const PLESSEY = 'BP';
28+
const QR = 'BQ';
29+
const GS1 = 'BR';
30+
const UPC_EAN = 'BS';
31+
const TLC39 = 'BT';
32+
const UPCA = 'BU';
33+
const DATAMATRIX = 'BX';
34+
const DEFAULT = 'BY';
35+
const POSTAL = 'BZ';
36+
37+
/** @return array<string> **/
38+
public static function values(): array
39+
{
40+
return (new \ReflectionClass(static::class))->getConstants();
41+
}
42+
43+
public static function isValid(string $value): bool
44+
{
45+
return in_array($value, static::values(), true);
46+
}
47+
48+
/** @throws \InvalidArgumentException */
49+
public static function validate(string $value): void
50+
{
51+
$values = self::values();
52+
if (in_array($value, $values, true)) {
53+
return;
54+
}
55+
56+
throw new \InvalidArgumentException('Valid values for barcode type are: ' . implode(',', $values));
57+
}
58+
}

src/Enums/Orientation.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace Zpl\Enums;
4+
5+
class Orientation
6+
{
7+
const NORMAL = 'N'; // normal as default
8+
const ROTATED = 'R'; // rotated 90 degrees
9+
const INVERTED = 'I'; // inverted 180 degrees
10+
const BOTTOM_UP = 'B'; // bottom-up 270 degrees, read from bottom up
11+
12+
/** @return array<string> **/
13+
public static function values(): array
14+
{
15+
return ['N', 'R', 'I', 'B'];
16+
}
17+
18+
public static function isValid(string $value): bool
19+
{
20+
return in_array($value, static::values(), true);
21+
}
22+
23+
/** @throws \InvalidArgumentException */
24+
public static function validate(string $value): void
25+
{
26+
$values = self::values();
27+
if (in_array($value, $values, true)) {
28+
return;
29+
}
30+
31+
throw new \InvalidArgumentException('Valid values for orientation are: ' . implode(',', $values));
32+
}
33+
}

src/PdfBuilder.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,16 @@ public function drawCode39(float $x, float $y, float $height, string $data, bool
143143
throw new BuilderException('Method not yet implemented');
144144
}
145145

146+
/**
147+
* {@inheritDoc}
148+
*
149+
* @see \Zpl\AbstractBuilder::drawBarcode()
150+
*/
151+
public function drawBarcode(string $type, float $x, float $y, float $height, string $data, bool $printData = false, bool $labelAbove = false, string $orientation = 'N', int $size = 0): void
152+
{
153+
throw new BuilderException('Method not yet implemented');
154+
}
155+
146156
/**
147157
* {@inheritDoc}
148158
*

src/ZplBuilder.php

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Zpl;
44

55
use Zpl\Commands\GraphicField;
6+
use Zpl\Enums\Barcode;
7+
use Zpl\Enums\Orientation;
68

79
class ZplBuilder extends AbstractBuilder
810
{
@@ -163,6 +165,7 @@ public function setDarkness(float $value): void
163165
*/
164166
public function setOrientation(string $orientation = 'N'): void
165167
{
168+
Orientation::validate($orientation);
166169
$this->commands[] = '^FW' . $orientation;
167170
}
168171

@@ -182,7 +185,7 @@ public function invertLabelOrientation(bool $isInvert = true): void
182185
*/
183186
public function drawText(float $x, float $y, string $text, string $orientation = 'N', bool $invert = false): void
184187
{
185-
$this->commands[] = '^FW' . $orientation;
188+
$this->setOrientation($orientation);
186189
$this->commands[] = '^FO' . $this->toDots($x) . ',' . $this->toDots($y);
187190
if ($invert === true) {
188191
$this->commands[] = '^FR';
@@ -297,33 +300,57 @@ public function drawCell(
297300
/**
298301
* {@inheritDoc}
299302
*
300-
* @see \Zpl\AbstractBuilder::drawCode128()
303+
* @see \Zpl\AbstractBuilder::drawBarcode()
301304
*/
302-
public function drawCode128(float $x, float $y, float $height, string $data, bool $printData = false, string $orientation = 'N', int $size = 0): void
305+
public function drawBarcode(string $type, float $x, float $y, float $height, string $data, bool $printData = false, bool $labelAbove = false, string $orientation = 'N', int $size = 0): void
303306
{
304-
$validOrientations = ['N', 'R', 'I', 'B'];
305-
if (in_array($orientation, $validOrientations) === false) {
306-
throw new \InvalidArgumentException('Valid values for orientation are: ' . implode(',', $validOrientations));
307-
}
307+
Barcode::validate($type);
308+
Orientation::validate($orientation);
308309

309310
$this->commands[] = '^FO' . $this->toDots($x) . ',' . $this->toDots($y);
310311
if ($size > 0 && $size <= 9) {
311312
$this->commands[] = '^BY' . $size;
312313
}
313-
$this->commands[] = '^BC' . $orientation . ',' . $this->toDots($height) . ',' . ($printData === true ? 'Y' : 'N') . ',N,N,A';
314+
315+
$barcode = [strtoupper($type), $orientation, $this->toDots($height), $printData, $labelAbove, 'N', 'A'];
316+
if (in_array($barcode[0], [Barcode::CODE39, Barcode::CODE11, Barcode::ANSI, Barcode::PLESSEY])) {
317+
array_splice($barcode, 2, 0, 'N');
318+
} elseif ($barcode[0] === Barcode::QR) {
319+
array_splice($barcode, 2, 0, '2');
320+
$data = 'QA,' . $data;
321+
$barcode = array_slice($barcode, 0, 3);
322+
$barcode[] = $height;
323+
} elseif ($barcode[0] === Barcode::MSI) {
324+
array_splice($barcode, 2, 0, 'B');
325+
}
326+
if (in_array($barcode[0], ['B1', 'B2', 'B5', 'B8', 'BE', 'BI', 'BU', 'BS'])) {
327+
$barcode = array_slice($barcode, 0, 5);
328+
} elseif (in_array($barcode[0], ['B3', 'B4', 'BA', 'BB', 'BD', 'BF', 'BJ', 'BK', 'BL', 'BM', 'BP'])) {
329+
$barcode = array_slice($barcode, 0, 6);
330+
}
331+
332+
$this->commands[] = $this->command($barcode);
314333
$this->commands[] = '^FD' . $data . '^FS';
315334
}
316335

336+
/**
337+
* {@inheritDoc}
338+
*
339+
* @see \Zpl\AbstractBuilder::drawCode128()
340+
*/
341+
public function drawCode128(float $x, float $y, float $height, string $data, bool $printData = false, string $orientation = 'N', int $size = 0): void
342+
{
343+
$this->drawBarcode(Barcode::CODE128, $x, $y, $height, $data, $printData, false, $orientation, $size);
344+
}
345+
317346
/**
318347
* {@inheritDoc}
319348
*
320349
* @see \Zpl\AbstractBuilder::drawQrCode()
321350
*/
322351
public function drawQrCode(float $x, float $y, string $data, int $size = 10): void
323352
{
324-
$this->commands[] = '^FO' . $this->toDots($x) . ',' . $this->toDots($y);
325-
$this->commands[] = '^BQN,2,' . $size;
326-
$this->commands[] = '^FDQA,' . $data . '^FS';
353+
$this->drawBarcode(Barcode::QR, $x, $y, (float) $size, $data);
327354
}
328355

329356
/**
@@ -333,12 +360,7 @@ public function drawQrCode(float $x, float $y, string $data, int $size = 10): vo
333360
*/
334361
public function drawCode39(float $x, float $y, float $height, string $data, bool $printData = false, string $orientation = 'N', int $size = 0): void
335362
{
336-
$this->commands[] = '^FO' . $this->toDots($x) . ',' . $this->toDots($y);
337-
if ($size > 0 && $size <= 9) {
338-
$this->commands[] = '^BY' . $size;
339-
}
340-
$this->commands[] = '^B3' . $orientation . ',N,' . $this->toDots($height) . ',' . ($printData === true ? 'Y' : 'N') . ',N';
341-
$this->commands[] = '^FD' . $data . '^FS';
363+
$this->drawBarcode(Barcode::CODE39, $x, $y, $height, $data, $printData, false, $orientation, $size);
342364
}
343365

344366
/**

tests/ZplTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,15 @@ public function drawQr(): void
154154
$this->assertEquals($this->getZpl(), "^XA\n^FO50,50\n^BQN,2,6\n^FDQA,https://example.com/product/ABC-123^FS\n^XZ\n");
155155
}
156156

157+
#[Test]
158+
public function drawArbitraryBarcode(): void
159+
{
160+
$this->driver->drawBarcode('BC', 5, 50, 20, 'ABC123456789', true, true);
161+
$this->driver->drawBarcode('B3', 5, 50, 20, '123456789', false, false, 'R', 5);
162+
163+
$this->assertEquals($this->getZpl(), "^XA\n^FO5,50\n^BCN,20,Y,Y,N,A\n^FDABC123456789^FS\n^FO5,50\n^BY5\n^B3R,N,20,N,N\n^FD123456789^FS\n^XZ\n");
164+
}
165+
157166
#[Test]
158167
public function drawGraphic(): void
159168
{

0 commit comments

Comments
 (0)