1<?php
2
3namespace Mpdf\Barcode;
4
5/**
6 * Standard 2 of 5 barcodes.
7 * Used in airline ticket marking, photofinishing
8 * Contains digits (0 to 9) and encodes the data only in the width of bars.
9 */
10class S25 extends \Mpdf\Barcode\AbstractBarcode implements \Mpdf\Barcode\BarcodeInterface
11{
12
13	/**
14	 * @param string $code
15	 * @param bool $checksum
16	 */
17	public function __construct($code, $checksum = false, $quiet_zone_left = null, $quiet_zone_right = null)
18	{
19		$this->init($code, $checksum);
20
21		$this->data['nom-X'] = 0.381; // Nominal value for X-dim (bar width) in mm (2 X min. spec.)
22		$this->data['nom-H'] = 10;  // Nominal value for Height of Full bar in mm (non-spec.)
23		$this->data['lightmL'] = ($quiet_zone_left !== null ? $quiet_zone_left : 10); // LEFT light margin =  x X-dim (spec.)
24		$this->data['lightmR'] = ($quiet_zone_right !== null ? $quiet_zone_right : 10); // RIGHT light margin =  x X-dim (spec.)
25		$this->data['lightTB'] = 0; // TOP/BOTTOM light margin =  x X-dim (non-spec.)
26	}
27
28	/**
29	 * @param string $code
30	 * @param bool $checksum
31	 */
32	private function init($code, $checksum)
33	{
34		$chr = [
35			'0' => '10101110111010',
36			'1' => '11101010101110',
37			'2' => '10111010101110',
38			'3' => '11101110101010',
39			'4' => '10101110101110',
40			'5' => '11101011101010',
41			'6' => '10111011101010',
42			'7' => '10101011101110',
43			'8' => '10101110111010',
44			'9' => '10111010111010',
45		];
46
47		$checkdigit = '';
48
49		if ($checksum) {
50			// add checksum
51			$checkdigit = $this->checksum($code);
52			$code .= $checkdigit;
53		}
54
55		if ((strlen($code) % 2) != 0) {
56			// add leading zero if code-length is odd
57			$code = '0' . $code;
58		}
59
60		$seq = '11011010';
61		$clen = strlen($code);
62		for ($i = 0; $i < $clen; ++$i) {
63			$digit = $code[$i];
64			if (!isset($chr[$digit])) {
65				// invalid character
66				throw new \Mpdf\Barcode\BarcodeException(sprintf('Invalid character "%s" in S25 barcode value "%s"', $digit, $code));
67			}
68			$seq .= $chr[$digit];
69		}
70
71		$seq .= '1101011';
72		$bararray = ['code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => []];
73		$bararray['checkdigit'] = $checkdigit;
74
75		$this->data = $this->binseqToArray($seq, $bararray);
76	}
77
78	/**
79	 * Checksum for standard 2 of 5 barcodes.
80	 *
81	 * @param string $code
82	 *
83	 * @return int
84	 */
85	private function checksum($code)
86	{
87		$len = strlen($code);
88		$sum = 0;
89		for ($i = 0; $i < $len; $i += 2) {
90			$sum += $code[$i];
91		}
92		$sum *= 3;
93		for ($i = 1; $i < $len; $i += 2) {
94			$sum += ($code[$i]);
95		}
96		$r = $sum % 10;
97		if ($r > 0) {
98			$r = (10 - $r);
99		}
100		return $r;
101	}
102
103	/**
104	 * @inheritdoc
105	 */
106	public function getType()
107	{
108		return 'S25';
109	}
110
111}
112