TCPDFBarcode::barcode_eanupc()   F
last analyzed

Complexity

Conditions 27
Paths > 20000

Size

Total Lines 183
Code Lines 146

Duplication

Lines 17
Ratio 9.29 %

Importance

Changes 0
Metric Value
cc 27
eloc 146
nc 25664
nop 2
dl 17
loc 183
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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 if ( !defined( 'ABSPATH' ) ) exit;
2
//============================================================+
3
// File name   : barcodes.php
4
// Begin       : 2008-06-09
5
// Last Update : 2009-08-26
6
// Version     : 1.0.009
7
// License     : GNU LGPL (http://www.gnu.org/copyleft/lesser.html)
8
// 	----------------------------------------------------------------------------
9
//  Copyright (C) 2008-2009 Nicola Asuni - Tecnick.com S.r.l.
10
// 	
11
// 	This program is free software: you can redistribute it and/or modify
12
// 	it under the terms of the GNU Lesser General Public License as published by
13
// 	the Free Software Foundation, either version 2.1 of the License, or
14
// 	(at your option) any later version.
15
// 	
16
// 	This program is distributed in the hope that it will be useful,
17
// 	but WITHOUT ANY WARRANTY; without even the implied warranty of
18
// 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
// 	GNU Lesser General Public License for more details.
20
// 	
21
// 	You should have received a copy of the GNU Lesser General Public License
22
// 	along with this program.  If not, see <http://www.gnu.org/licenses/>.
23
// 	
24
// 	See LICENSE.TXT file for more information.
25
//  ----------------------------------------------------------------------------
26
//
27
// Description : PHP class to creates array representations for 
28
//               common 1D barcodes to be used with TCPDF.
29
//
30
// Author: Nicola Asuni
31
//
32
// (c) Copyright:
33
//               Nicola Asuni
34
//               Tecnick.com S.r.l.
35
//               Via della Pace, 11
36
//               09044 Quartucciu (CA)
37
//               ITALY
38
//               www.tecnick.com
39
//               [email protected]
40
//============================================================+
41
42
/**
43
 * PHP class to creates array representations for common 1D barcodes to be used with TCPDF.
44
 * @package com.tecnick.tcpdf
45
 * @abstract Functions for generating string representation of common 1D barcodes.
46
 * @author Nicola Asuni
47
 * @copyright 2008-2009 Nicola Asuni - Tecnick.com S.r.l (www.tecnick.com) Via Della Pace, 11 - 09044 - Quartucciu (CA) - ITALY - www.tecnick.com - [email protected]
48
 * @link http://www.tcpdf.org
49
 * @license http://www.gnu.org/copyleft/lesser.html LGPL
50
 * @version 1.0.008
51
 */
52
53
	/**
54
	* PHP class to creates array representations for common 1D barcodes to be used with TCPDF (http://www.tcpdf.org).<br>
55
	* @name TCPDFBarcode
56
	* @package com.tecnick.tcpdf
57
	* @version 1.0.008
58
	* @author Nicola Asuni
59
	* @link http://www.tcpdf.org
60
	* @license http://www.gnu.org/copyleft/lesser.html LGPL
61
	*/
62
class TCPDFBarcode {
63
	
64
	/**
65
	 * @var array representation of barcode.
66
	 * @access protected
67
	 */
68
	protected $barcode_array;
69
		
70
	/**
71
	 * This is the class constructor. 
72
	 * Return an array representations for common 1D barcodes:<ul>
73
	 * <li>$arrcode['code'] code to be printed on text label</li>
74
	 * <li>$arrcode['maxh'] max bar height</li>
75
	 * <li>$arrcode['maxw'] max bar width</li>
76
	 * <li>$arrcode['bcode'][$k] single bar or space in $k position</li>
77
	 * <li>$arrcode['bcode'][$k]['t'] bar type: true = bar, false = space.</li>
78
	 * <li>$arrcode['bcode'][$k]['w'] bar width in units.</li>
79
	 * <li>$arrcode['bcode'][$k]['h'] bar height in units.</li>
80
	 * <li>$arrcode['bcode'][$k]['p'] bar top position (0 = top, 1 = middle)</li></ul>
81
	 * @param string $code code to print
82
 	 * @param string $type type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extention</li><li>EAN5 : 5-Digits UPC-Based Extention</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
83
	 */
84
	public function __construct($code, $type) {
85
		$this->setBarcode($code, $type);
86
	}
87
	
88
	/** 
89
	 * Return an array representations of barcode.
90
 	 * @return array
91
	 */
92
	public function getBarcodeArray() {
93
		return $this->barcode_array;
94
	}
95
	
96
	/** 
97
	 * Set the barcode.
98
	 * @param string $code code to print
99
 	 * @param string $type type of barcode: <ul><li>C39 : CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.</li><li>C39+ : CODE 39 with checksum</li><li>C39E : CODE 39 EXTENDED</li><li>C39E+ : CODE 39 EXTENDED + CHECKSUM</li><li>C93 : CODE 93 - USS-93</li><li>S25 : Standard 2 of 5</li><li>S25+ : Standard 2 of 5 + CHECKSUM</li><li>I25 : Interleaved 2 of 5</li><li>I25+ : Interleaved 2 of 5 + CHECKSUM</li><li>C128A : CODE 128 A</li><li>C128B : CODE 128 B</li><li>C128C : CODE 128 C</li><li>EAN2 : 2-Digits UPC-Based Extention</li><li>EAN5 : 5-Digits UPC-Based Extention</li><li>EAN8 : EAN 8</li><li>EAN13 : EAN 13</li><li>UPCA : UPC-A</li><li>UPCE : UPC-E</li><li>MSI : MSI (Variation of Plessey code)</li><li>MSI+ : MSI + CHECKSUM (modulo 11)</li><li>POSTNET : POSTNET</li><li>PLANET : PLANET</li><li>RMS4CC : RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)</li><li>KIX : KIX (Klant index - Customer index)</li><li>IMB: Intelligent Mail Barcode - Onecode - USPS-B-3200</li><li>CODABAR : CODABAR</li><li>CODE11 : CODE 11</li><li>PHARMA : PHARMACODE</li><li>PHARMA2T : PHARMACODE TWO-TRACKS</li></ul>
100
 	 * @return array
101
	 */
102
	public function setBarcode($code, $type) {
103
		switch (strtoupper($type)) {
104
			case 'C39': { // CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
105
				$arrcode = $this->barcode_code39($code, false, false);
106
				break;
107
			}
108
			case 'C39+': { // CODE 39 with checksum
109
				$arrcode = $this->barcode_code39($code, false, true);
110
				break;
111
			}
112
			case 'C39E': { // CODE 39 EXTENDED
113
				$arrcode = $this->barcode_code39($code, true, false);
114
				break;
115
			}
116
			case 'C39E+': { // CODE 39 EXTENDED + CHECKSUM
117
				$arrcode = $this->barcode_code39($code, true, true);
118
				break;
119
			}
120
			case 'C93': { // CODE 93 - USS-93
121
				$arrcode = $this->barcode_code93($code);
122
				break;
123
			}
124
			case 'S25': { // Standard 2 of 5
125
				$arrcode = $this->barcode_s25($code, false);
126
				break;
127
			}
128
			case 'S25+': { // Standard 2 of 5 + CHECKSUM
129
				$arrcode = $this->barcode_s25($code, true);
130
				break;
131
			}
132
			case 'I25': { // Interleaved 2 of 5
133
				$arrcode = $this->barcode_i25($code, false);
134
				break;
135
			}
136
			case 'I25+': { // Interleaved 2 of 5 + CHECKSUM
137
				$arrcode = $this->barcode_i25($code, true);
138
				break;
139
			}
140
			case 'C128A': { // CODE 128 A
141
				$arrcode = $this->barcode_c128($code, 'A');
142
				break;
143
			}
144
			case 'C128B': { // CODE 128 B
145
				$arrcode = $this->barcode_c128($code, 'B');
146
				break;
147
			}
148
			case 'C128C': { // CODE 128 C
149
				$arrcode = $this->barcode_c128($code, 'C');
150
				break;
151
			}
152
			case 'EAN2': { // 2-Digits UPC-Based Extention
153
				$arrcode = $this->barcode_eanext($code, 2);
154
				break;
155
			}
156
			case 'EAN5': { // 5-Digits UPC-Based Extention
157
				$arrcode = $this->barcode_eanext($code, 5);
158
				break;
159
			}
160
			case 'EAN8': { // EAN 8
161
				$arrcode = $this->barcode_eanupc($code, 8);
162
				break;
163
			}
164
			case 'EAN13': { // EAN 13
165
				$arrcode = $this->barcode_eanupc($code, 13);
166
				break;
167
			}
168
			case 'UPCA': { // UPC-A
169
				$arrcode = $this->barcode_eanupc($code, 12);
170
				break;
171
			}
172
			case 'UPCE': { // UPC-E
173
				$arrcode = $this->barcode_eanupc($code, 6);
174
				break;
175
			}
176
			case 'MSI': { // MSI (Variation of Plessey code)
177
				$arrcode = $this->barcode_msi($code, false);
178
				break;
179
			}
180
			case 'MSI+': { // MSI + CHECKSUM (modulo 11)
181
				$arrcode = $this->barcode_msi($code, true);
182
				break;
183
			}
184
			case 'POSTNET': { // POSTNET
185
				$arrcode = $this->barcode_postnet($code, false);
186
				break;
187
			}
188
			case 'PLANET': { // PLANET
189
				$arrcode = $this->barcode_postnet($code, true);
190
				break;
191
			}
192
			case 'RMS4CC': { // RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code)
193
				$arrcode = $this->barcode_rms4cc($code, false);
194
				break;
195
			}
196
			case 'KIX': { // KIX (Klant index - Customer index)
197
				$arrcode = $this->barcode_rms4cc($code, true);
198
				break;
199
			}
200
			case 'IMB': { // IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
201
				$arrcode = $this->barcode_imb($code);
202
				break;
203
			}
204
			case 'CODABAR': { // CODABAR
205
				$arrcode = $this->barcode_codabar($code);
206
				break;
207
			}
208
			case 'CODE11': { // CODE 11
209
				$arrcode = $this->barcode_code11($code);
210
				break;
211
			}
212
			case 'PHARMA': { // PHARMACODE
213
				$arrcode = $this->barcode_pharmacode($code);
214
				break;
215
			}
216
			case 'PHARMA2T': { // PHARMACODE TWO-TRACKS
217
				$arrcode = $this->barcode_pharmacode2t($code);
218
				break;
219
			}
220
			default: {
221
				$this->barcode_array = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type array of property $barcode_array.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
222
				$arrcode = false;
223
				break;
224
			}
225
		}
226
		$this->barcode_array = $arrcode;
227
	}
228
	
229
	/**
230
	 * CODE 39 - ANSI MH10.8M-1983 - USD-3 - 3 of 9.
231
	 * General-purpose code in very wide use world-wide
232
	 * @param string $code code to represent.
233
	 * @param boolean $checksum if true add a checksum to the code
234
	 * @return array barcode representation.
235
	 * @access protected
236
	 */
237
	protected function barcode_code39($code, $extended=false, $checksum=false) {
238
		$chr['0'] = '111221211';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$chr was never initialized. Although not strictly required by PHP, it is generally a good practice to add $chr = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
239
		$chr['1'] = '211211112';
240
		$chr['2'] = '112211112';
241
		$chr['3'] = '212211111';
242
		$chr['4'] = '111221112';
243
		$chr['5'] = '211221111';
244
		$chr['6'] = '112221111';
245
		$chr['7'] = '111211212';
246
		$chr['8'] = '211211211';
247
		$chr['9'] = '112211211';
248
		$chr['A'] = '211112112';
249
		$chr['B'] = '112112112';
250
		$chr['C'] = '212112111';
251
		$chr['D'] = '111122112';
252
		$chr['E'] = '211122111';
253
		$chr['F'] = '112122111';
254
		$chr['G'] = '111112212';
255
		$chr['H'] = '211112211';
256
		$chr['I'] = '112112211';
257
		$chr['J'] = '111122211';
258
		$chr['K'] = '211111122';
259
		$chr['L'] = '112111122';
260
		$chr['M'] = '212111121';
261
		$chr['N'] = '111121122';
262
		$chr['O'] = '211121121';
263
		$chr['P'] = '112121121';
264
		$chr['Q'] = '111111222';
265
		$chr['R'] = '211111221';
266
		$chr['S'] = '112111221';
267
		$chr['T'] = '111121221';
268
		$chr['U'] = '221111112';
269
		$chr['V'] = '122111112';
270
		$chr['W'] = '222111111';
271
		$chr['X'] = '121121112';
272
		$chr['Y'] = '221121111';
273
		$chr['Z'] = '122121111';
274
		$chr['-'] = '121111212';
275
		$chr['.'] = '221111211';
276
		$chr[' '] = '122111211';
277
		$chr['$'] = '121212111';
278
		$chr['/'] = '121211121';
279
		$chr['+'] = '121112121';
280
		$chr['%'] = '111212121';
281
		$chr['*'] = '121121211';
282
		
283
		$code = strtoupper($code);
284
		if ($extended) {
285
			// extended mode
286
			$code = $this->encode_code39_ext($code);
287
		}
288
		if ($code === false) {
289
			return false;
290
		}
291
		if ($checksum) {
292
			// checksum
293
			$code .= $this->checksum_code39($code);
294
		}
295
		// add start and stop codes
296
		$code = '*'.$code.'*';
297
		
298
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
299
		$k = 0;
300
		$clen = strlen($code);
301
		for ($i = 0; $i < $clen; ++$i) {
302
			$char = $code{$i};
303
			if(!isset($chr[$char])) {
304
				// invalid character
305
				return false;
306
			}
307
			for ($j = 0; $j < 9; ++$j) {
308
				if (($j % 2) == 0) {
309
					$t = true; // bar
310
				} else {
311
					$t = false; // space
312
				}
313
				$w = $chr[$char]{$j};
314
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
315
				$bararray['maxw'] += $w;
316
				++$k;
317
			}
318
			$bararray['bcode'][$k] = array('t' => false, 'w' => 1, 'h' => 1, 'p' => 0);
319
			$bararray['maxw'] += 1;
320
			++$k;
321
		}
322
		return $bararray;
323
	}
324
	
325
	/**
326
	 * Encode a string to be used for CODE 39 Extended mode.
327
	 * @param string $code code to represent.
328
	 * @return encoded string.
329
	 * @access protected
330
	 */
331
	protected function encode_code39_ext($code) {
332
		$encode = array(
333
			chr(0) => '%U', chr(1) => '$A', chr(2) => '$B', chr(3) => '$C',
334
			chr(4) => '$D', chr(5) => '$E', chr(6) => '$F', chr(7) => '$G',
335
			chr(8) => '$H', chr(9) => '$I', chr(10) => '$J', chr(11) => '£K',
336
			chr(12) => '$L', chr(13) => '$M', chr(14) => '$N', chr(15) => '$O',
337
			chr(16) => '$P', chr(17) => '$Q', chr(18) => '$R', chr(19) => '$S',
338
			chr(20) => '$T', chr(21) => '$U', chr(22) => '$V', chr(23) => '$W',
339
			chr(24) => '$X', chr(25) => '$Y', chr(26) => '$Z', chr(27) => '%A',
340
			chr(28) => '%B', chr(29) => '%C', chr(30) => '%D', chr(31) => '%E',
341
			chr(32) => ' ', chr(33) => '/A', chr(34) => '/B', chr(35) => '/C',
342
			chr(36) => '/D', chr(37) => '/E', chr(38) => '/F', chr(39) => '/G',
343
			chr(40) => '/H', chr(41) => '/I', chr(42) => '/J', chr(43) => '/K',
344
			chr(44) => '/L', chr(45) => '-', chr(46) => '.', chr(47) => '/O',
345
			chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3',
346
			chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7',
347
			chr(56) => '8', chr(57) => '9', chr(58) => '/Z', chr(59) => '%F',
348
			chr(60) => '%G', chr(61) => '%H', chr(62) => '%I', chr(63) => '%J',
349
			chr(64) => '%V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C',
350
			chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G',
351
			chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K',
352
			chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O',
353
			chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S',
354
			chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W',
355
			chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => '%K',
356
			chr(92) => '%L', chr(93) => '%M', chr(94) => '%N', chr(95) => '%O',
357
			chr(96) => '%W', chr(97) => '+A', chr(98) => '+B', chr(99) => '+C',
358
			chr(100) => '+D', chr(101) => '+E', chr(102) => '+F', chr(103) => '+G',
359
			chr(104) => '+H', chr(105) => '+I', chr(106) => '+J', chr(107) => '+K',
360
			chr(108) => '+L', chr(109) => '+M', chr(110) => '+N', chr(111) => '+O',
361
			chr(112) => '+P', chr(113) => '+Q', chr(114) => '+R', chr(115) => '+S',
362
			chr(116) => '+T', chr(117) => '+U', chr(118) => '+V', chr(119) => '+W',
363
			chr(120) => '+X', chr(121) => '+Y', chr(122) => '+Z', chr(123) => '%P',
364
			chr(124) => '%Q', chr(125) => '%R', chr(126) => '%S', chr(127) => '%T');
365
		$code_ext = '';
366
		$clen = strlen($code);
367 View Code Duplication
		for ($i = 0 ; $i < $clen; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
368
			if (ord($code{$i}) > 127) {
369
				return false;
370
			}
371
			$code_ext .= $encode[$code{$i}];
372
		}
373
		return $code_ext;
374
	}
375
	
376
	/**
377
	 * Calculate CODE 39 checksum (modulo 43).
378
	 * @param string $code code to represent.
379
	 * @return char checksum.
380
	 * @access protected
381
	 */
382
	protected function checksum_code39($code) {
383
		$chars = array(
384
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
385
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
386
			'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
387
			'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%');
388
		$sum = 0;
389
		$clen = strlen($code);
390
		for ($i = 0 ; $i < $clen; ++$i) {
391
			$k = array_keys($chars, $code{$i});
392
			$sum += $k[0];
393
		}
394
		$j = ($sum % 43);
395
		return $chars[$j];
396
	}
397
	
398
	/**
399
	 * CODE 93 - USS-93
400
	 * Compact code similar to Code 39
401
	 * @param string $code code to represent.
402
	 * @param boolean $checksum if true add a checksum to the code
0 ignored issues
show
Bug introduced by
There is no parameter named $checksum. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
403
	 * @return array barcode representation.
404
	 * @access protected
405
	 */
406
	protected function barcode_code93($code) {
407
		$chr['0'] = '131112';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$chr was never initialized. Although not strictly required by PHP, it is generally a good practice to add $chr = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
408
		$chr['1'] = '111213';
409
		$chr['2'] = '111312';
410
		$chr['3'] = '111411';
411
		$chr['4'] = '121113';
412
		$chr['5'] = '121212';
413
		$chr['6'] = '121311';
414
		$chr['7'] = '111114';
415
		$chr['8'] = '131211';
416
		$chr['9'] = '141111';
417
		$chr['A'] = '211113';
418
		$chr['B'] = '211212';
419
		$chr['C'] = '211311';
420
		$chr['D'] = '221112';
421
		$chr['E'] = '221211';
422
		$chr['F'] = '231111';
423
		$chr['G'] = '112113';
424
		$chr['H'] = '112212';
425
		$chr['I'] = '112311';
426
		$chr['J'] = '122112';
427
		$chr['K'] = '132111';
428
		$chr['L'] = '111123';
429
		$chr['M'] = '111222';
430
		$chr['N'] = '111321';
431
		$chr['O'] = '121122';
432
		$chr['P'] = '131121';
433
		$chr['Q'] = '212112';
434
		$chr['R'] = '212211';
435
		$chr['S'] = '211122';
436
		$chr['T'] = '211221';
437
		$chr['U'] = '221121';
438
		$chr['V'] = '222111';
439
		$chr['W'] = '112122';
440
		$chr['X'] = '112221';
441
		$chr['Y'] = '122121';
442
		$chr['Z'] = '123111';
443
		$chr['-'] = '121131';
444
		$chr['.'] = '311112';
445
		$chr[' '] = '311211';
446
		$chr['$'] = '321111';
447
		$chr['/'] = '112131';
448
		$chr['+'] = '113121';
449
		$chr['%'] = '211131';
450
		$chr[128] = '121221'; // ($)
451
		$chr[129] = '311121'; // (/)
452
		$chr[130] = '122211'; // (+)
453
		$chr[131] = '312111'; // (%)
454
		$chr['*'] = '111141';
455
		$code = strtoupper($code);
456
		$encode = array(
457
			chr(0) => chr(131).'U', chr(1) => chr(128).'A', chr(2) => chr(128).'B', chr(3) => chr(128).'C',
458
			chr(4) => chr(128).'D', chr(5) => chr(128).'E', chr(6) => chr(128).'F', chr(7) => chr(128).'G',
459
			chr(8) => chr(128).'H', chr(9) => chr(128).'I', chr(10) => chr(128).'J', chr(11) => '£K',
460
			chr(12) => chr(128).'L', chr(13) => chr(128).'M', chr(14) => chr(128).'N', chr(15) => chr(128).'O',
461
			chr(16) => chr(128).'P', chr(17) => chr(128).'Q', chr(18) => chr(128).'R', chr(19) => chr(128).'S',
462
			chr(20) => chr(128).'T', chr(21) => chr(128).'U', chr(22) => chr(128).'V', chr(23) => chr(128).'W',
463
			chr(24) => chr(128).'X', chr(25) => chr(128).'Y', chr(26) => chr(128).'Z', chr(27) => chr(131).'A',
464
			chr(28) => chr(131).'B', chr(29) => chr(131).'C', chr(30) => chr(131).'D', chr(31) => chr(131).'E',
465
			chr(32) => ' ', chr(33) => chr(129).'A', chr(34) => chr(129).'B', chr(35) => chr(129).'C',
466
			chr(36) => chr(129).'D', chr(37) => chr(129).'E', chr(38) => chr(129).'F', chr(39) => chr(129).'G',
467
			chr(40) => chr(129).'H', chr(41) => chr(129).'I', chr(42) => chr(129).'J', chr(43) => chr(129).'K',
468
			chr(44) => chr(129).'L', chr(45) => '-', chr(46) => '.', chr(47) => chr(129).'O',
469
			chr(48) => '0', chr(49) => '1', chr(50) => '2', chr(51) => '3',
470
			chr(52) => '4', chr(53) => '5', chr(54) => '6', chr(55) => '7',
471
			chr(56) => '8', chr(57) => '9', chr(58) => chr(129).'Z', chr(59) => chr(131).'F',
472
			chr(60) => chr(131).'G', chr(61) => chr(131).'H', chr(62) => chr(131).'I', chr(63) => chr(131).'J',
473
			chr(64) => chr(131).'V', chr(65) => 'A', chr(66) => 'B', chr(67) => 'C',
474
			chr(68) => 'D', chr(69) => 'E', chr(70) => 'F', chr(71) => 'G',
475
			chr(72) => 'H', chr(73) => 'I', chr(74) => 'J', chr(75) => 'K',
476
			chr(76) => 'L', chr(77) => 'M', chr(78) => 'N', chr(79) => 'O',
477
			chr(80) => 'P', chr(81) => 'Q', chr(82) => 'R', chr(83) => 'S',
478
			chr(84) => 'T', chr(85) => 'U', chr(86) => 'V', chr(87) => 'W',
479
			chr(88) => 'X', chr(89) => 'Y', chr(90) => 'Z', chr(91) => chr(131).'K',
480
			chr(92) => chr(131).'L', chr(93) => chr(131).'M', chr(94) => chr(131).'N', chr(95) => chr(131).'O',
481
			chr(96) => chr(131).'W', chr(97) => chr(130).'A', chr(98) => chr(130).'B', chr(99) => chr(130).'C',
482
			chr(100) => chr(130).'D', chr(101) => chr(130).'E', chr(102) => chr(130).'F', chr(103) => chr(130).'G',
483
			chr(104) => chr(130).'H', chr(105) => chr(130).'I', chr(106) => chr(130).'J', chr(107) => chr(130).'K',
484
			chr(108) => chr(130).'L', chr(109) => chr(130).'M', chr(110) => chr(130).'N', chr(111) => chr(130).'O',
485
			chr(112) => chr(130).'P', chr(113) => chr(130).'Q', chr(114) => chr(130).'R', chr(115) => chr(130).'S',
486
			chr(116) => chr(130).'T', chr(117) => chr(130).'U', chr(118) => chr(130).'V', chr(119) => chr(130).'W',
487
			chr(120) => chr(130).'X', chr(121) => chr(130).'Y', chr(122) => chr(130).'Z', chr(123) => chr(131).'P',
488
			chr(124) => chr(131).'Q', chr(125) => chr(131).'R', chr(126) => chr(131).'S', chr(127) => chr(131).'T');
489
		$code_ext = '';
490
		$clen = strlen($code);
491 View Code Duplication
		for ($i = 0 ; $i < $clen; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
492
			if (ord($code{$i}) > 127) {
493
				return false;
494
			}
495
			$code_ext .= $encode[$code{$i}];
496
		}
497
		// checksum
498
		$code .= $this->checksum_code93($code);
499
		// add start and stop codes
500
		$code = '*'.$code.'*';
501
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
502
		$k = 0;
503
		$clen = strlen($code);
504 View Code Duplication
		for ($i = 0; $i < $clen; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
505
			$char = $code{$i};
506
			if(!isset($chr[$char])) {
507
				// invalid character
508
				return false;
509
			}
510
			for ($j = 0; $j < 6; ++$j) {
511
				if (($j % 2) == 0) {
512
					$t = true; // bar
513
				} else {
514
					$t = false; // space
515
				}
516
				$w = $chr[$char]{$j};
517
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
518
				$bararray['maxw'] += $w;
519
				++$k;
520
			}
521
		}
522
		$bararray['bcode'][$k] = array('t' => true, 'w' => 1, 'h' => 1, 'p' => 0);
523
		$bararray['maxw'] += 1;
524
		++$k;		
525
		return $bararray;
526
	}
527
	
528
	/**
529
	 * Calculate CODE 93 checksum (modulo 47).
530
	 * @param string $code code to represent.
531
	 * @return string checksum code.
532
	 * @access protected
533
	 */
534
	protected function checksum_code93($code) {
535
		$chars = array(
536
			'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
537
			'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
538
			'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
539
			'W', 'X', 'Y', 'Z', '-', '.', ' ', '$', '/', '+', '%');
540
		// translate special characters
541
		$code = strtr($code, chr(128).chr(129).chr(130).chr(131), '$/+%');	
542
		$len = strlen($code);
543
		// calculate check digit C
544
		$p = 1;
545
		$check = 0;
546 View Code Duplication
		for ($i = ($len - 1); $i >= 0; --$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
547
			$k = array_keys($chars, $code{$i});
548
			$check += ($k[0] * $p);
549
			++$p;
550
			if ($p > 20) {
551
				$p = 1;
552
			}
553
		}
554
		$check %= 47;
555
		$c = $chars[$check];
556
		$code .= $c;
557
		// calculate check digit K
558
		$p = 1;
559
		$check = 0;
560 View Code Duplication
		for ($i = $len; $i >= 0; --$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
561
			$k = array_keys($chars, $code{$i});
562
			$check += ($k[0] * $p);
563
			++$p;
564
			if ($p > 15) {
565
				$p = 1;
566
			}
567
		}
568
		$check %= 47;
569
		$k = $chars[$check];
570
		return $c.$k;
571
	}
572
	
573
	/**
574
	 * Checksum for standard 2 of 5 barcodes.
575
	 * @param string $code code to process.
576
	 * @return int checksum.
577
	 * @access protected
578
	 */
579
	protected function checksum_s25($code) {
580
		$len = strlen($code);
581
		$sum = 0;
582
		for ($i = 0; $i < $len; $i+=2) {
583
			$sum += $code{$i};
584
		}
585
		$sum *= 3;
586
		for ($i = 1; $i < $len; $i+=2) {
587
			$sum += ($code{$i});
588
		}
589
		$r = $sum % 10;
590
		if($r > 0) {
591
			$r = (10 - $r);
592
		}
593
		return $r;
594
	}
595
	
596
	/**
597
	 * MSI.
598
	 * Variation of Plessey code, with similar applications 
599
	 * Contains digits (0 to 9) and encodes the data only in the width of bars.
600
	 * @param string $code code to represent.
601
	 * @param boolean $checksum if true add a checksum to the code (modulo 11)
602
	 * @return array barcode representation.
603
	 * @access protected
604
	 */
605
	protected function barcode_msi($code, $checksum=false) {
606
		$chr['0'] = '100100100100';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$chr was never initialized. Although not strictly required by PHP, it is generally a good practice to add $chr = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
607
		$chr['1'] = '100100100110';
608
		$chr['2'] = '100100110100';
609
		$chr['3'] = '100100110110';
610
		$chr['4'] = '100110100100';
611
		$chr['5'] = '100110100110';
612
		$chr['6'] = '100110110100';
613
		$chr['7'] = '100110110110';
614
		$chr['8'] = '110100100100';
615
		$chr['9'] = '110100100110';
616
		$chr['A'] = '110100110100';
617
		$chr['B'] = '110100110110';
618
		$chr['C'] = '110110100100';
619
		$chr['D'] = '110110100110';
620
		$chr['E'] = '110110110100';
621
		$chr['F'] = '110110110110';
622
		if ($checksum) {
623
			// add checksum
624
			$clen = strlen($code);
625
			$p = 2;
626
			$check = 0;
627
			for ($i = ($clen - 1); $i >= 0; --$i) {
628
				$check += (hexdec($code{$i}) * $p);
629
				++$p;
630
				if ($p > 7) {
631
					$p = 2;
632
				}
633
			}
634
			$check %= 11;
635
			if ($check > 0) {
636
				$check = 11 - $check;
637
			}
638
			$code .= $check;
639
		}
640
		$seq = '110'; // left guard
641
		$clen = strlen($code);
642 View Code Duplication
		for ($i = 0; $i < $clen; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
643
			$digit = $code{$i};
644
			if (!isset($chr[$digit])) {
645
				// invalid character
646
				return false;
647
			}
648
			$seq .= $chr[$digit];
649
		}		
650
		$seq .= '1001'; // right guard
651
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
652
		return $this->binseq_to_array($seq, $bararray);
653
	}
654
	
655
	/**
656
	 * Standard 2 of 5 barcodes.
657
	 * Used in airline ticket marking, photofinishing
658
	 * Contains digits (0 to 9) and encodes the data only in the width of bars.
659
	 * @param string $code code to represent.
660
	 * @param boolean $checksum if true add a checksum to the code
661
	 * @return array barcode representation.
662
	 * @access protected
663
	 */
664
	protected function barcode_s25($code, $checksum=false) {
665
		$chr['0'] = '10101110111010';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$chr was never initialized. Although not strictly required by PHP, it is generally a good practice to add $chr = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
666
		$chr['1'] = '11101010101110';
667
		$chr['2'] = '10111010101110';
668
		$chr['3'] = '11101110101010';
669
		$chr['4'] = '10101110101110';
670
		$chr['5'] = '11101011101010';
671
		$chr['6'] = '10111011101010';
672
		$chr['7'] = '10101011101110';
673
		$chr['8'] = '10101110111010';
674
		$chr['9'] = '10111010111010';
675
		if ($checksum) {
676
			// add checksum
677
			$code .= $this->checksum_s25($code);
678
		}
679
		if((strlen($code) % 2) != 0) {
680
			// add leading zero if code-length is odd
681
			$code = '0'.$code;
682
		}
683
		$seq = '11011010';
684
		$clen = strlen($code);
685 View Code Duplication
		for ($i = 0; $i < $clen; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
686
			$digit = $code{$i};
687
			if (!isset($chr[$digit])) {
688
				// invalid character
689
				return false;
690
			}
691
			$seq .= $chr[$digit];
692
		}		
693
		$seq .= '1101011';
694
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
695
		return $this->binseq_to_array($seq, $bararray);
696
	}
697
	
698
	/**
699
	 * Convert binary barcode sequence to TCPDF barcode array
700
	 * @param string $seq barcode as binary sequence
701
	 * òparam array $bararray TCPDF barcode array to fill up
702
	 * @return array barcode representation.
703
	 * @access protected
704
	 */
705
	protected function binseq_to_array($seq, $bararray) {
706
		$len = strlen($seq);
707
		$w = 0;
708
		$k = 0;
709 View Code Duplication
		for ($i = 0; $i < $len; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
710
			$w += 1;
711
			if (($i == ($len - 1)) OR (($i < ($len - 1)) AND ($seq{$i} != $seq{($i+1)}))) {
712
				if ($seq{$i} == '1') {
713
					$t = true; // bar
714
				} else {
715
					$t = false; // space
716
				}
717
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
718
				$bararray['maxw'] += $w;
719
				++$k;
720
				$w = 0;
721
			}
722
		}
723
		return $bararray;
724
	}
725
	
726
	/**
727
	 * Interleaved 2 of 5 barcodes.
728
	 * Compact numeric code, widely used in industry, air cargo
729
	 * Contains digits (0 to 9) and encodes the data in the width of both bars and spaces.
730
	 * @param string $code code to represent.
731
	 * @param boolean $checksum if true add a checksum to the code
732
	 * @return array barcode representation.
733
	 * @access protected
734
	 */
735
	protected function barcode_i25($code, $checksum=false) {
736
		$chr['0'] = '11221';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$chr was never initialized. Although not strictly required by PHP, it is generally a good practice to add $chr = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
737
		$chr['1'] = '21112';
738
		$chr['2'] = '12112';
739
		$chr['3'] = '22111';
740
		$chr['4'] = '11212';
741
		$chr['5'] = '21211';
742
		$chr['6'] = '12211';
743
		$chr['7'] = '11122';
744
		$chr['8'] = '21121';
745
		$chr['9'] = '12121';
746
		$chr['A'] = '11';
747
		$chr['Z'] = '21';
748
		if ($checksum) {
749
			// add checksum
750
			$code .= $this->checksum_s25($code);
751
		}
752
		if((strlen($code) % 2) != 0) {
753
			// add leading zero if code-length is odd
754
			$code = '0'.$code;
755
		}
756
		// add start and stop codes
757
		$code = 'AA'.strtolower($code).'ZA';
758
			
759
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
760
		$k = 0;
761
		$clen = strlen($code);
762
		for ($i = 0; $i < $clen; $i = ($i + 2)) {
763
			$char_bar = $code{$i};
764
			$char_space = $code{$i+1};
765
			if((!isset($chr[$char_bar])) OR (!isset($chr[$char_space]))) {
766
				// invalid character
767
				return false;
768
			}
769
			// create a bar-space sequence
770
			$seq = '';
771
			$chrlen = strlen($chr[$char_bar]);
772
			for ($s = 0; $s < $chrlen; $s++){
773
				$seq .= $chr[$char_bar]{$s} . $chr[$char_space]{$s};
774
			}
775
			$seqlen = strlen($seq);
776
			for ($j = 0; $j < $seqlen; ++$j) {
777
				if (($j % 2) == 0) {
778
					$t = true; // bar
779
				} else {
780
					$t = false; // space
781
				}
782
				$w = $seq{$j};
783
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
784
				$bararray['maxw'] += $w;
785
				++$k;
786
			}
787
		}
788
		return $bararray;
789
	}
790
	
791
	/**
792
	 * C128 barcodes. 
793
	 * Very capable code, excellent density, high reliability; in very wide use world-wide
794
	 * @param string $code code to represent.
795
	 * @param string $type barcode type: A, B or C
796
	 * @return array barcode representation.
797
	 * @access protected
798
	 */
799
	protected function barcode_c128($code, $type='B') {
800
		$chr = array(
801
			'212222', /* 00 */
802
			'222122', /* 01 */
803
			'222221', /* 02 */
804
			'121223', /* 03 */
805
			'121322', /* 04 */
806
			'131222', /* 05 */
807
			'122213', /* 06 */
808
			'122312', /* 07 */
809
			'132212', /* 08 */
810
			'221213', /* 09 */
811
			'221312', /* 10 */
812
			'231212', /* 11 */
813
			'112232', /* 12 */
814
			'122132', /* 13 */
815
			'122231', /* 14 */
816
			'113222', /* 15 */
817
			'123122', /* 16 */
818
			'123221', /* 17 */
819
			'223211', /* 18 */
820
			'221132', /* 19 */
821
			'221231', /* 20 */
822
			'213212', /* 21 */
823
			'223112', /* 22 */
824
			'312131', /* 23 */
825
			'311222', /* 24 */
826
			'321122', /* 25 */
827
			'321221', /* 26 */
828
			'312212', /* 27 */
829
			'322112', /* 28 */
830
			'322211', /* 29 */
831
			'212123', /* 30 */
832
			'212321', /* 31 */
833
			'232121', /* 32 */
834
			'111323', /* 33 */
835
			'131123', /* 34 */
836
			'131321', /* 35 */
837
			'112313', /* 36 */
838
			'132113', /* 37 */
839
			'132311', /* 38 */
840
			'211313', /* 39 */
841
			'231113', /* 40 */
842
			'231311', /* 41 */
843
			'112133', /* 42 */
844
			'112331', /* 43 */
845
			'132131', /* 44 */
846
			'113123', /* 45 */
847
			'113321', /* 46 */
848
			'133121', /* 47 */
849
			'313121', /* 48 */
850
			'211331', /* 49 */
851
			'231131', /* 50 */
852
			'213113', /* 51 */
853
			'213311', /* 52 */
854
			'213131', /* 53 */
855
			'311123', /* 54 */
856
			'311321', /* 55 */
857
			'331121', /* 56 */
858
			'312113', /* 57 */
859
			'312311', /* 58 */
860
			'332111', /* 59 */
861
			'314111', /* 60 */
862
			'221411', /* 61 */
863
			'431111', /* 62 */
864
			'111224', /* 63 */
865
			'111422', /* 64 */
866
			'121124', /* 65 */
867
			'121421', /* 66 */
868
			'141122', /* 67 */
869
			'141221', /* 68 */
870
			'112214', /* 69 */
871
			'112412', /* 70 */
872
			'122114', /* 71 */
873
			'122411', /* 72 */
874
			'142112', /* 73 */
875
			'142211', /* 74 */
876
			'241211', /* 75 */
877
			'221114', /* 76 */
878
			'413111', /* 77 */
879
			'241112', /* 78 */
880
			'134111', /* 79 */
881
			'111242', /* 80 */
882
			'121142', /* 81 */
883
			'121241', /* 82 */
884
			'114212', /* 83 */
885
			'124112', /* 84 */
886
			'124211', /* 85 */
887
			'411212', /* 86 */
888
			'421112', /* 87 */
889
			'421211', /* 88 */
890
			'212141', /* 89 */
891
			'214121', /* 90 */
892
			'412121', /* 91 */
893
			'111143', /* 92 */
894
			'111341', /* 93 */
895
			'131141', /* 94 */
896
			'114113', /* 95 */
897
			'114311', /* 96 */
898
			'411113', /* 97 */
899
			'411311', /* 98 */
900
			'113141', /* 99 */
901
			'114131', /* 100 */
902
			'311141', /* 101 */
903
			'411131', /* 102 */
904
			'211412', /* 103 START A */
905
			'211214', /* 104 START B  */
906
			'211232', /* 105 START C  */
907
			'233111', /* STOP */
908
			'200000'  /* END */
909
		);
910
		$keys = '';
0 ignored issues
show
Unused Code introduced by
$keys is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
911
		switch(strtoupper($type)) {
912
			case 'A': {
913
				$startid = 103;
914
				$keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_';
915
				for ($i = 0; $i < 32; ++$i) {
916
					$keys .= chr($i);
917
				}
918
				break;
919
			}
920
			case 'B': {
921
				$startid = 104;
922
				$keys = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'.chr(127);
923
				break;
924
			}
925
			case 'C': {
926
				$startid = 105;
927
				$keys = '';
928
				if ((strlen($code) % 2) != 0) {
929
					// The length of barcode value must be even ($code). You must pad the number with zeros
930
					return false;
931
				}
932
				for ($i = 0; $i <= 99; ++$i) {
933
					$keys .= chr($i);
934
				}
935
				$new_code = '';
936
				$hclen = (strlen($code) / 2);
937
				for ($i = 0; $i < $hclen; ++$i) {
938
					$new_code .= chr(intval($code{(2 * $i)}.$code{(2 * $i + 1)}));
939
				}
940
				$code = $new_code;
941
				break;
942
			}
943
			default: {
944
				return false;
945
			}
946
		}
947
		// calculate check character
948
		$sum = $startid;
949
		$clen = strlen($code);
950
		for ($i = 0; $i < $clen; ++$i) {
951
			$sum +=  (strpos($keys, $code{$i}) * ($i+1));
952
		}
953
		$check = ($sum % 103);
954
		// add start, check and stop codes
955
		$code = chr($startid).$code.chr($check).chr(106).chr(107);
956
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
957
		$k = 0;
958
		$len = strlen($code);
959
		for ($i = 0; $i < $len; ++$i) {
960
			$ck = strpos($keys, $code{$i});
961
			if (($i == 0) OR ($i > ($len-4))) {
962
				$char_num = ord($code{$i});
963
				$seq = $chr[$char_num];
964
			} elseif(($ck >= 0) AND isset($chr[$ck])) {
965
					$seq = $chr[$ck];
966
			} else {
967
				// invalid character
968
				return false;
969
			}
970
			for ($j = 0; $j < 6; ++$j) {
971
				if (($j % 2) == 0) {
972
					$t = true; // bar
973
				} else {
974
					$t = false; // space
975
				}
976
				$w = $seq{$j};
977
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
978
				$bararray['maxw'] += $w;
979
				++$k;
980
			}
981
		}
982
		return $bararray;		
983
	}
984
	
985
	/**
986
	 * EAN13 and UPC-A barcodes.
987
	 * EAN13: European Article Numbering international retail product code
988
	 * UPC-A: Universal product code seen on almost all retail products in the USA and Canada
989
	 * UPC-E: Short version of UPC symbol
990
	 * @param string $code code to represent.
991
	 * @param string $len barcode type: 6 = UPC-E, 8 = EAN8, 13 = EAN13, 12 = UPC-A
992
	 * @return array barcode representation.
993
	 * @access protected
994
	 */
995
	protected function barcode_eanupc($code, $len=13) {
996
		$upce = false;
997
		if ($len == 6) {
998
			$len = 12; // UPC-A
999
			$upce = true; // UPC-E mode
1000
		}
1001
		$data_len = $len - 1;
1002
		//Padding
1003
		$code = str_pad($code, $data_len, '0', STR_PAD_LEFT);
1004
		$code_len = strlen($code);
1005
		// calculate check digit
1006
		$sum_a = 0;
1007
		for ($i = 1; $i < $data_len; $i+=2) {
1008
			$sum_a += $code{$i};
1009
		}
1010
		if ($len > 12) {
1011
			$sum_a *= 3;
1012
		}
1013
		$sum_b = 0;
1014
		for ($i = 0; $i < $data_len; $i+=2) {
1015
			$sum_b += ($code{$i});
1016
		}
1017
		if ($len < 13) {
1018
			$sum_b *= 3;
1019
		}
1020
		$r = ($sum_a + $sum_b) % 10;
1021
		if($r > 0) {
1022
			$r = (10 - $r);
1023
		}
1024
		if ($code_len == $data_len) {
1025
			// add check digit
1026
			$code .= $r;
1027
		} elseif ($r !== intval($code{$data_len})) {
1028
			// wrong checkdigit
1029
			return false;
1030
		}
1031
		if ($len == 12) {
1032
			// UPC-A
1033
			$code = '0'.$code;
1034
			++$len;
1035
		}
1036
		if ($upce) {
1037
			// convert UPC-A to UPC-E
1038
			$tmp = substr($code, 4, 3);
1039
			if (($tmp == '000') OR ($tmp == '100') OR ($tmp == '200')) {
1040
				// manufacturer code ends in 000, 100, or 200
1041
				$upce_code = substr($code, 2, 2).substr($code, 9, 3).substr($code, 4, 1);
1042
			} else {
1043
				$tmp = substr($code, 5, 2);
1044
				if ($tmp == '00') {
1045
					// manufacturer code ends in 00
1046
					$upce_code = substr($code, 2, 3).substr($code, 10, 2).'3';
1047
				} else {
1048
					$tmp = substr($code, 6, 1);
1049
					if ($tmp == '0') {
1050
						// manufacturer code ends in 0
1051
						$upce_code = substr($code, 2, 4).substr($code, 11, 1).'4';
1052
					} else {
1053
						// manufacturer code does not end in zero
1054
						$upce_code = substr($code, 2, 5).substr($code, 11, 1);
1055
					}
1056
				}
1057
			}
1058
		}
1059
		//Convert digits to bars
1060
		$codes = array(
1061
			'A'=>array( // left odd parity
1062
				'0'=>'0001101',
1063
				'1'=>'0011001',
1064
				'2'=>'0010011',
1065
				'3'=>'0111101',
1066
				'4'=>'0100011',
1067
				'5'=>'0110001',
1068
				'6'=>'0101111',
1069
				'7'=>'0111011',
1070
				'8'=>'0110111',
1071
				'9'=>'0001011'),
1072
			'B'=>array( // left even parity
1073
				'0'=>'0100111',
1074
				'1'=>'0110011',
1075
				'2'=>'0011011',
1076
				'3'=>'0100001',
1077
				'4'=>'0011101',
1078
				'5'=>'0111001',
1079
				'6'=>'0000101',
1080
				'7'=>'0010001',
1081
				'8'=>'0001001',
1082
				'9'=>'0010111'),
1083
			'C'=>array( // right
1084
				'0'=>'1110010',
1085
				'1'=>'1100110',
1086
				'2'=>'1101100',
1087
				'3'=>'1000010',
1088
				'4'=>'1011100',
1089
				'5'=>'1001110',
1090
				'6'=>'1010000',
1091
				'7'=>'1000100',
1092
				'8'=>'1001000',
1093
				'9'=>'1110100')
1094
		);
1095
		$parities = array(
1096
			'0'=>array('A','A','A','A','A','A'),
1097
			'1'=>array('A','A','B','A','B','B'),
1098
			'2'=>array('A','A','B','B','A','B'),
1099
			'3'=>array('A','A','B','B','B','A'),
1100
			'4'=>array('A','B','A','A','B','B'),
1101
			'5'=>array('A','B','B','A','A','B'),
1102
			'6'=>array('A','B','B','B','A','A'),
1103
			'7'=>array('A','B','A','B','A','B'),
1104
			'8'=>array('A','B','A','B','B','A'),
1105
			'9'=>array('A','B','B','A','B','A')
1106
		);
1107
		$upce_parities = array();
1108
		$upce_parities[0] = array(
1109
			'0'=>array('B','B','B','A','A','A'),
1110
			'1'=>array('B','B','A','B','A','A'),
1111
			'2'=>array('B','B','A','A','B','A'),
1112
			'3'=>array('B','B','A','A','A','B'),
1113
			'4'=>array('B','A','B','B','A','A'),
1114
			'5'=>array('B','A','A','B','B','A'),
1115
			'6'=>array('B','A','A','A','B','B'),
1116
			'7'=>array('B','A','B','A','B','A'),
1117
			'8'=>array('B','A','B','A','A','B'),
1118
			'9'=>array('B','A','A','B','A','B')
1119
		);
1120
		$upce_parities[1] = array(
1121
			'0'=>array('A','A','A','B','B','B'),
1122
			'1'=>array('A','A','B','A','B','B'),
1123
			'2'=>array('A','A','B','B','A','B'),
1124
			'3'=>array('A','A','B','B','B','A'),
1125
			'4'=>array('A','B','A','A','B','B'),
1126
			'5'=>array('A','B','B','A','A','B'),
1127
			'6'=>array('A','B','B','B','A','A'),
1128
			'7'=>array('A','B','A','B','A','B'),
1129
			'8'=>array('A','B','A','B','B','A'),
1130
			'9'=>array('A','B','B','A','B','A')
1131
		);
1132
		$k = 0;
1133
		$seq = '101'; // left guard bar
1134
		if ($upce) {
1135
			$bararray = array('code' => $upce_code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
0 ignored issues
show
Bug introduced by
The variable $upce_code does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1136
			$p = $upce_parities[$code{1}][$r];
1137
			for ($i = 0; $i < 6; ++$i) {
1138
				$seq .= $codes[$p[$i]][$upce_code{$i}];
1139
			}
1140
			$seq .= '010101'; // right guard bar
1141
		} else {
1142
			$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1143
			$half_len = ceil($len / 2);
1144
			if ($len == 8) {
1145
				for ($i = 0; $i < $half_len; ++$i) {
1146
					$seq .= $codes['A'][$code{$i}];
1147
				}
1148
			} else {
1149
				$p = $parities[$code{0}];
1150 View Code Duplication
				for ($i = 1; $i < $half_len; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1151
					$seq .= $codes[$p[$i-1]][$code{$i}];
1152
				}
1153
			}
1154
			$seq .= '01010'; // center guard bar
1155
			for ($i = $half_len; $i < $len; ++$i) {
1156
				$seq .= $codes['C'][$code{$i}];
1157
			}
1158
			$seq .= '101'; // right guard bar
1159
		}
1160
		$clen = strlen($seq);
1161
		$w = 0;
1162 View Code Duplication
		for ($i = 0; $i < $clen; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1163
			$w += 1;
1164
			if (($i == ($clen - 1)) OR (($i < ($clen - 1)) AND ($seq{$i} != $seq{($i+1)}))) {
1165
				if ($seq{$i} == '1') {
1166
					$t = true; // bar
1167
				} else {
1168
					$t = false; // space
1169
				}
1170
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
1171
				$bararray['maxw'] += $w;
1172
				++$k;
1173
				$w = 0;
1174
			}
1175
		}
1176
		return $bararray;
1177
	}
1178
	
1179
	/**
1180
	 * UPC-Based Extentions
1181
	 * 2-Digit Ext.: Used to indicate magazines and newspaper issue numbers
1182
	 * 5-Digit Ext.: Used to mark suggested retail price of books
1183
	 * @param string $code code to represent.
1184
	 * @param string $len barcode type: 2 = 2-Digit, 5 = 5-Digit
1185
	 * @return array barcode representation.
1186
	 * @access protected
1187
	 */
1188
	protected function barcode_eanext($code, $len=5) {
1189
		//Padding
1190
		$code = str_pad($code, $len, '0', STR_PAD_LEFT);
1191
		// calculate check digit
1192
		if ($len == 2) {
1193
			$r = $code % 4;
1194
		} elseif ($len == 5) {
1195
			$r = (3 * ($code{0} + $code{2} + $code{4})) + (9 * ($code{1} + $code{3}));
1196
			$r %= 10;
1197
		} else {
1198
			return false;
1199
		}
1200
		//Convert digits to bars
1201
		$codes = array(
1202
			'A'=>array( // left odd parity
1203
				'0'=>'0001101',
1204
				'1'=>'0011001',
1205
				'2'=>'0010011',
1206
				'3'=>'0111101',
1207
				'4'=>'0100011',
1208
				'5'=>'0110001',
1209
				'6'=>'0101111',
1210
				'7'=>'0111011',
1211
				'8'=>'0110111',
1212
				'9'=>'0001011'),
1213
			'B'=>array( // left even parity
1214
				'0'=>'0100111',
1215
				'1'=>'0110011',
1216
				'2'=>'0011011',
1217
				'3'=>'0100001',
1218
				'4'=>'0011101',
1219
				'5'=>'0111001',
1220
				'6'=>'0000101',
1221
				'7'=>'0010001',
1222
				'8'=>'0001001',
1223
				'9'=>'0010111')
1224
		);
1225
		$parities = array();
1226
		$parities[2] = array(
1227
			'0'=>array('A','A'),
1228
			'1'=>array('A','B'),
1229
			'2'=>array('B','A'),
1230
			'3'=>array('B','B')
1231
		);
1232
		$parities[5] = array(
1233
			'0'=>array('B','B','A','A','A'),
1234
			'1'=>array('B','A','B','A','A'),
1235
			'2'=>array('B','A','A','B','A'),
1236
			'3'=>array('B','A','A','A','B'),
1237
			'4'=>array('A','B','B','A','A'),
1238
			'5'=>array('A','A','B','B','A'),
1239
			'6'=>array('A','A','A','B','B'),
1240
			'7'=>array('A','B','A','B','A'),
1241
			'8'=>array('A','B','A','A','B'),
1242
			'9'=>array('A','A','B','A','B')
1243
		);	
1244
		$p = $parities[$len][$r];
1245
		$seq = '1011'; // left guard bar
1246
		$seq .= $codes[$p[0]][$code{0}];
1247 View Code Duplication
		for ($i = 1; $i < $len; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1248
			$seq .= '01'; // separator
1249
			$seq .= $codes[$p[$i]][$code{$i}];
1250
		}
1251
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1252
		return $this->binseq_to_array($seq, $bararray);
1253
	}
1254
	
1255
	/**
1256
	 * POSTNET and PLANET barcodes.
1257
	 * Used by U.S. Postal Service for automated mail sorting
1258
	 * @param string $code zip code to represent. Must be a string containing a zip code of the form DDDDD or DDDDD-DDDD.
1259
	 * @param boolean $planet if true print the PLANET barcode, otherwise print POSTNET
1260
	 * @return array barcode representation.
1261
	 * @access protected
1262
	 */
1263
	protected function barcode_postnet($code, $planet=false) {
1264
		// bar lenght
1265
		if ($planet) {
1266
			$barlen = Array(
1267
				0 => Array(1,1,2,2,2),
1268
				1 => Array(2,2,2,1,1),
1269
				2 => Array(2,2,1,2,1),
1270
				3 => Array(2,2,1,1,2),
1271
				4 => Array(2,1,2,2,1),
1272
				5 => Array(2,1,2,1,2),
1273
				6 => Array(2,1,1,2,2),
1274
				7 => Array(1,2,2,2,1),
1275
				8 => Array(1,2,2,1,2),
1276
				9 => Array(1,2,1,2,2)
1277
			);
1278
		} else {
1279
			$barlen = Array(
1280
				0 => Array(2,2,1,1,1),
1281
				1 => Array(1,1,1,2,2),
1282
				2 => Array(1,1,2,1,2),
1283
				3 => Array(1,1,2,2,1),
1284
				4 => Array(1,2,1,1,2),
1285
				5 => Array(1,2,1,2,1),
1286
				6 => Array(1,2,2,1,1),
1287
				7 => Array(2,1,1,1,2),
1288
				8 => Array(2,1,1,2,1),
1289
				9 => Array(2,1,2,1,1)
1290
			);
1291
		}
1292
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array());
1293
		$k = 0;
1294
		$code = str_replace('-', '', $code);
1295
		$code = str_replace(' ', '', $code);
1296
		$len = strlen($code);
1297
		// calculate checksum
1298
		$sum = 0;
1299
		for ($i = 0; $i < $len; ++$i) {
1300
			$sum += intval($code{$i});
1301
		}
1302
		$chkd = ($sum % 10);
1303
		if($chkd > 0) {
1304
			$chkd = (10 - $chkd);
1305
		}
1306
		$code .= $chkd;
1307
		$len = strlen($code);
1308
		// start bar
1309
		$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0);
1310
		$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1311
		$bararray['maxw'] += 2;
1312
		for ($i = 0; $i < $len; ++$i) {
1313
			for ($j = 0; $j < 5; ++$j) {
1314
				$h = $barlen[$code{$i}][$j];
1315
				$p = floor(1 / $h);
1316
				$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
1317
				$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1318
				$bararray['maxw'] += 2;
1319
			}
1320
		}
1321
		// end bar
1322
		$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0);
1323
		$bararray['maxw'] += 1;
1324
		return $bararray;
1325
	}
1326
	
1327
	/**
1328
	 * RMS4CC - CBC - KIX
1329
	 * RMS4CC (Royal Mail 4-state Customer Code) - CBC (Customer Bar Code) - KIX (Klant index - Customer index)
1330
	 * RM4SCC is the name of the barcode symbology used by the Royal Mail for its Cleanmail service.
1331
	 * @param string $code code to print
1332
	 * @param boolean $kix if true prints the KIX variation (doesn't use the start and end symbols, and the checksum) - in this case the house number must be sufficed with an X and placed at the end of the code.
1333
	 * @return array barcode representation.
1334
	 * @access protected
1335
	 */
1336
	protected function barcode_rms4cc($code, $kix=false) {
1337
		$notkix = !$kix;
1338
		// bar mode
1339
		// 1 = pos 1, length 2
1340
		// 2 = pos 1, length 3
1341
		// 3 = pos 2, length 1
1342
		// 4 = pos 2, length 2
1343
		$barmode = array(
1344
			'0' => array(3,3,2,2),
1345
			'1' => array(3,4,1,2),
1346
			'2' => array(3,4,2,1),
1347
			'3' => array(4,3,1,2),
1348
			'4' => array(4,3,2,1),
1349
			'5' => array(4,4,1,1),
1350
			'6' => array(3,1,4,2),
1351
			'7' => array(3,2,3,2),
1352
			'8' => array(3,2,4,1),
1353
			'9' => array(4,1,3,2),
1354
			'A' => array(4,1,4,1),
1355
			'B' => array(4,2,3,1),
1356
			'C' => array(3,1,2,4),
1357
			'D' => array(3,2,1,4),
1358
			'E' => array(3,2,2,3),
1359
			'F' => array(4,1,1,4),
1360
			'G' => array(4,1,2,3),
1361
			'H' => array(4,2,1,3),
1362
			'I' => array(1,3,4,2),
1363
			'J' => array(1,4,3,2),
1364
			'K' => array(1,4,4,1),
1365
			'L' => array(2,3,3,2),
1366
			'M' => array(2,3,4,1),
1367
			'N' => array(2,4,3,1),
1368
			'O' => array(1,3,2,4),
1369
			'P' => array(1,4,1,4),
1370
			'Q' => array(1,4,2,3),
1371
			'R' => array(2,3,1,4),
1372
			'S' => array(2,3,2,3),
1373
			'T' => array(2,4,1,3),
1374
			'U' => array(1,1,4,4),
1375
			'V' => array(1,2,3,4),
1376
			'W' => array(1,2,4,3),
1377
			'X' => array(2,1,3,4),
1378
			'Y' => array(2,1,4,3),
1379
			'Z' => array(2,2,3,3)		
1380
		);
1381
		$code = strtoupper($code);
1382
		$len = strlen($code);
1383
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array());
1384
		if ($notkix) {
1385
			// table for checksum calculation (row,col)
1386
			$checktable = array(
1387
				'0' => array(1,1),
1388
				'1' => array(1,2),
1389
				'2' => array(1,3),
1390
				'3' => array(1,4),
1391
				'4' => array(1,5),
1392
				'5' => array(1,0),
1393
				'6' => array(2,1),
1394
				'7' => array(2,2),
1395
				'8' => array(2,3),
1396
				'9' => array(2,4),
1397
				'A' => array(2,5),
1398
				'B' => array(2,0),
1399
				'C' => array(3,1),
1400
				'D' => array(3,2),
1401
				'E' => array(3,3),
1402
				'F' => array(3,4),
1403
				'G' => array(3,5),
1404
				'H' => array(3,0),
1405
				'I' => array(4,1),
1406
				'J' => array(4,2),
1407
				'K' => array(4,3),
1408
				'L' => array(4,4),
1409
				'M' => array(4,5),
1410
				'N' => array(4,0),
1411
				'O' => array(5,1),
1412
				'P' => array(5,2),
1413
				'Q' => array(5,3),
1414
				'R' => array(5,4),
1415
				'S' => array(5,5),
1416
				'T' => array(5,0),
1417
				'U' => array(0,1),
1418
				'V' => array(0,2),
1419
				'W' => array(0,3),
1420
				'X' => array(0,4),
1421
				'Y' => array(0,5),
1422
				'Z' => array(0,0)
1423
			);
1424
			$row = 0;
1425
			$col = 0;
1426
			for ($i = 0; $i < $len; ++$i) {
1427
				$row += $checktable[$code{$i}][0];
1428
				$col += $checktable[$code{$i}][1];
1429
			}
1430
			$row %= 6;
1431
			$col %= 6;
1432
			$chk = array_keys($checktable, array($row,$col));
1433
			$code .= $chk[0];
1434
			++$len;
1435
		}
1436
		$k = 0;
1437
		if ($notkix) {
1438
			// start bar
1439
			$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 2, 'p' => 0);
1440
			$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1441
			$bararray['maxw'] += 2;
1442
		}
1443
		for ($i = 0; $i < $len; ++$i) {
1444
			for ($j = 0; $j < 4; ++$j) {
1445
				switch ($barmode[$code{$i}][$j]) {
1446
					case 1: {
1447
						$p = 0;
1448
						$h = 2;
1449
						break;
1450
					}
1451
					case 2: {
1452
						$p = 0;
1453
						$h = 3;
1454
						break;
1455
					}
1456
					case 3: {
1457
						$p = 1;
1458
						$h = 1;
1459
						break;
1460
					}
1461
					case 4: {
1462
						$p = 1;
1463
						$h = 2;
1464
						break;
1465
					}
1466
				}
1467
				$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
0 ignored issues
show
Bug introduced by
The variable $h does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $p does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1468
				$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1469
				$bararray['maxw'] += 2;
1470
			}
1471
		}
1472
		if ($notkix) {
1473
			// stop bar
1474
			$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => 3, 'p' => 0);
1475
			$bararray['maxw'] += 1;
1476
		}
1477
		return $bararray;
1478
	}
1479
	
1480
	/**
1481
	 * CODABAR barcodes.
1482
	 * Older code often used in library systems, sometimes in blood banks
1483
	 * @param string $code code to represent.
1484
	 * @return array barcode representation.
1485
	 * @access protected
1486
	 */
1487
	protected function barcode_codabar($code) {
1488
		$chr = array(
1489
			'0' => '11111221',
1490
			'1' => '11112211',
1491
			'2' => '11121121',
1492
			'3' => '22111111',
1493
			'4' => '11211211',
1494
			'5' => '21111211',
1495
			'6' => '12111121',
1496
			'7' => '12112111',
1497
			'8' => '12211111',
1498
			'9' => '21121111',
1499
			'-' => '11122111',
1500
			'$' => '11221111',
1501
			':' => '21112121',
1502
			'/' => '21211121',
1503
			'.' => '21212111',
1504
			'+' => '11222221',
1505
			'A' => '11221211',
1506
			'B' => '12121121',
1507
			'C' => '11121221',
1508
			'D' => '11122211'
1509
		);
1510
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1511
		$k = 0;
1512
		$w = 0;
0 ignored issues
show
Unused Code introduced by
$w is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1513
		$seq = '';
0 ignored issues
show
Unused Code introduced by
$seq is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1514
		$code = 'A'.strtoupper($code).'A';
1515
		$len = strlen($code);
1516 View Code Duplication
		for ($i = 0; $i < $len; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1517
			if (!isset($chr[$code{$i}])) {
1518
				return false;
1519
			}
1520
			$seq = $chr[$code{$i}];
1521
			for ($j = 0; $j < 8; ++$j) {
1522
				if (($j % 2) == 0) {
1523
					$t = true; // bar
1524
				} else {
1525
					$t = false; // space
1526
				}
1527
				$w = $seq{$j};
1528
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
1529
				$bararray['maxw'] += $w;
1530
				++$k;
1531
			}
1532
		}
1533
		return $bararray;
1534
	}
1535
	
1536
	/**
1537
	 * CODE11 barcodes.
1538
	 * Used primarily for labeling telecommunications equipment
1539
	 * @param string $code code to represent.
1540
	 * @return array barcode representation.
1541
	 * @access protected
1542
	 */
1543
	protected function barcode_code11($code) {
1544
		$chr = array(
1545
			'0' => '111121',
1546
			'1' => '211121',
1547
			'2' => '121121',
1548
			'3' => '221111',
1549
			'4' => '112121',
1550
			'5' => '212111',
1551
			'6' => '122111',
1552
			'7' => '111221',
1553
			'8' => '211211',
1554
			'9' => '211111',
1555
			'-' => '112111',
1556
			'S' => '112211'
1557
		);
1558
		
1559
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1560
		$k = 0;
1561
		$w = 0;
0 ignored issues
show
Unused Code introduced by
$w is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1562
		$seq = '';
0 ignored issues
show
Unused Code introduced by
$seq is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1563
		$len = strlen($code);
1564
		// calculate check digit C
1565
		$p = 1;
1566
		$check = 0;
1567 View Code Duplication
		for ($i = ($len - 1); $i >= 0; --$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1568
			$digit = $code{$i};
1569
			if ($digit == '-') {
1570
				$dval = 10;
1571
			} else {
1572
				$dval = intval($digit);
1573
			}
1574
			$check += ($dval * $p);
1575
			++$p;
1576
			if ($p > 10) {
1577
				$p = 1;
1578
			}
1579
		}
1580
		$check %= 11;
1581
		if ($check == 10) {
1582
			$check = '-';
1583
		} 
1584
		$code .= $check;
1585
		if ($len > 10) {
1586
			// calculate check digit K
1587
			$p = 1;
1588
			$check = 0;
1589 View Code Duplication
			for ($i = $len; $i >= 0; --$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1590
				$digit = $code{$i};
1591
				if ($digit == '-') {
1592
					$dval = 10;
1593
				} else {
1594
					$dval = intval($digit);
1595
				}
1596
				$check += ($dval * $p);
1597
				++$p;
1598
				if ($p > 9) {
1599
					$p = 1;
1600
				}
1601
			}
1602
			$check %= 11;
1603
			$code .= $check;
1604
			++$len;
1605
		}
1606
		$code = 'S'.$code.'S';
1607
		$len += 3;
1608 View Code Duplication
		for ($i = 0; $i < $len; ++$i) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1609
			if (!isset($chr[$code{$i}])) {
1610
				return false;
1611
			}
1612
			$seq = $chr[$code{$i}];
1613
			for ($j = 0; $j < 6; ++$j) {
1614
				if (($j % 2) == 0) {
1615
					$t = true; // bar
1616
				} else {
1617
					$t = false; // space
1618
				}
1619
				$w = $seq{$j};
1620
				$bararray['bcode'][$k] = array('t' => $t, 'w' => $w, 'h' => 1, 'p' => 0);
1621
				$bararray['maxw'] += $w;
1622
				++$k;
1623
			}
1624
		}
1625
		return $bararray;
1626
	}
1627
	
1628
	/**
1629
	 * Pharmacode
1630
	 * Contains digits (0 to 9)
1631
	 * @param string $code code to represent.
1632
	 * @return array barcode representation.
1633
	 * @access protected
1634
	 */
1635
	protected function barcode_pharmacode($code) {
1636
		$seq = '';
1637
		$code = intval($code);
1638
		while ($code > 0) {
1639
			if (($code % 2) == 0) {
1640
				$seq .= '11100';
1641
				$code -= 2;
1642
			} else {
1643
				$seq .= '100';
1644
				$code -= 1;
1645
			}
1646
			$code /= 2;
1647
		}
1648
		$seq = substr($seq, 0, -2);
1649
		$seq = strrev($seq);
1650
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 1, 'bcode' => array());
1651
		return $this->binseq_to_array($seq, $bararray);
1652
	}
1653
	
1654
	/**
1655
	 * Pharmacode two-track
1656
	 * Contains digits (0 to 9)
1657
	 * @param string $code code to represent.
1658
	 * @return array barcode representation.
1659
	 * @access protected
1660
	 */
1661
	protected function barcode_pharmacode2t($code) {
1662
		$seq = '';
1663
		$code = intval($code);
1664
		do {
1665
			switch ($code % 3) {
1666
				case 0: {
1667
					$seq .= '3';
1668
					$code = ($code - 3) / 3;
1669
					break;
1670
				}
1671
				case 1: {
1672
					$seq .= '1';
1673
					$code = ($code - 1) / 3;
1674
					break;
1675
				}
1676
				case 2: {
1677
					$seq .= '2';
1678
					$code = ($code - 2) / 3;
1679
					break;
1680
				}
1681
			}
1682
		} while($code != 0);
1683
		$seq = strrev($seq);
1684
		$k = 0;
1685
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 2, 'bcode' => array());
1686
		$len = strlen($seq);
1687
		for ($i = 0; $i < $len; ++$i) {
1688
			switch ($seq{$i}) {
1689
				case '1': {
1690
					$p = 1;
1691
					$h = 1;
1692
					break;
1693
				}
1694
				case '2': {
1695
					$p = 0;
1696
					$h = 1;
1697
					break;
1698
				}
1699
				case '3': {
1700
					$p = 0;
1701
					$h = 2;
1702
					break;
1703
				}
1704
			}
1705
			$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
0 ignored issues
show
Bug introduced by
The variable $h does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $p does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1706
			$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1707
			$bararray['maxw'] += 2;
1708
		}
1709
		unset($bararray['bcode'][($k - 1)]);
1710
		--$bararray['maxw'];
1711
		return $bararray;
1712
	}
1713
	
1714
	
1715
	/**
1716
	 * IMB - Intelligent Mail Barcode - Onecode - USPS-B-3200
1717
	 * (requires PHP bcmath extension) 
1718
	 * Intelligent Mail barcode is a 65-bar code for use on mail in the United States.
1719
	 * The fields are described as follows:<ul><li>The Barcode Identifier shall be assigned by USPS to encode the presort identification that is currently printed in human readable form on the optional endorsement line (OEL) as well as for future USPS use. This shall be two digits, with the second digit in the range of 0–4. The allowable encoding ranges shall be 00–04, 10–14, 20–24, 30–34, 40–44, 50–54, 60–64, 70–74, 80–84, and 90–94.</li><li>The Service Type Identifier shall be assigned by USPS for any combination of services requested on the mailpiece. The allowable encoding range shall be 000http://it2.php.net/manual/en/function.dechex.php–999. Each 3-digit value shall correspond to a particular mail class with a particular combination of service(s). Each service program, such as OneCode Confirm and OneCode ACS, shall provide the list of Service Type Identifier values.</li><li>The Mailer or Customer Identifier shall be assigned by USPS as a unique, 6 or 9 digit number that identifies a business entity. The allowable encoding range for the 6 digit Mailer ID shall be 000000- 899999, while the allowable encoding range for the 9 digit Mailer ID shall be 900000000-999999999.</li><li>The Serial or Sequence Number shall be assigned by the mailer for uniquely identifying and tracking mailpieces. The allowable encoding range shall be 000000000–999999999 when used with a 6 digit Mailer ID and 000000-999999 when used with a 9 digit Mailer ID. e. The Delivery Point ZIP Code shall be assigned by the mailer for routing the mailpiece. This shall replace POSTNET for routing the mailpiece to its final delivery point. The length may be 0, 5, 9, or 11 digits. The allowable encoding ranges shall be no ZIP Code, 00000–99999,  000000000–999999999, and 00000000000–99999999999.</li></ul>
1720
	 * @param string $code code to print, separate the ZIP (routing code) from the rest using a minus char '-' (BarcodeID_ServiceTypeID_MailerID_SerialNumber-RoutingCode)
1721
	 * @return array barcode representation.
1722
	 * @access protected
1723
	 */
1724
	protected function barcode_imb($code) {
1725
		$asc_chr = array(4,0,2,6,3,5,1,9,8,7,1,2,0,6,4,8,2,9,5,3,0,1,3,7,4,6,8,9,2,0,5,1,9,4,3,8,6,7,1,2,4,3,9,5,7,8,3,0,2,1,4,0,9,1,7,0,2,4,6,3,7,1,9,5,8);
1726
		$dsc_chr = array(7,1,9,5,8,0,2,4,6,3,5,8,9,7,3,0,6,1,7,4,6,8,9,2,5,1,7,5,4,3,8,7,6,0,2,5,4,9,3,0,1,6,8,2,0,4,5,9,6,7,5,2,6,3,8,5,1,9,8,7,4,0,2,6,3);
1727
		$asc_pos = array(3,0,8,11,1,12,8,11,10,6,4,12,2,7,9,6,7,9,2,8,4,0,12,7,10,9,0,7,10,5,7,9,6,8,2,12,1,4,2,0,1,5,4,6,12,1,0,9,4,7,5,10,2,6,9,11,2,12,6,7,5,11,0,3,2);
1728
		$dsc_pos = array(2,10,12,5,9,1,5,4,3,9,11,5,10,1,6,3,4,1,10,0,2,11,8,6,1,12,3,8,6,4,4,11,0,6,1,9,11,5,3,7,3,10,7,11,8,2,10,3,5,8,0,3,12,11,8,4,5,1,3,0,7,12,9,8,10);
1729
		$code_arr = explode('-', $code);
1730
		$tracking_number = $code_arr[0];
1731
		if (isset($code_arr[1])) {
1732
			$routing_code = $code_arr[1];
1733
		} else {
1734
			$routing_code = '';
1735
		}
1736
		// Conversion of Routing Code
1737
		switch (strlen($routing_code)) {
1738
			case 0: {
1739
				$binary_code = 0;
1740
				break;
1741
			}
1742
			case 5: {
1743
				$binary_code = bcadd($routing_code, '1');
1744
				break;
1745
			}
1746
			case 9: {
1747
				$binary_code = bcadd($routing_code, '100001');
1748
				break;
1749
			}
1750
			case 11: {
1751
				$binary_code = bcadd($routing_code, '1000100001');
1752
				break;
1753
			}
1754
			default: {
1755
				return false;
1756
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
1757
			}
1758
		}
1759
		$binary_code = bcmul($binary_code, 10);
1760
		$binary_code = bcadd($binary_code, $tracking_number{0});
1761
		$binary_code = bcmul($binary_code, 5);
1762
		$binary_code = bcadd($binary_code, $tracking_number{1});
1763
		$binary_code .= substr($tracking_number, 2, 18);
1764
		// convert to hexadecimal
1765
		$binary_code = $this->dec_to_hex($binary_code);
1766
		// pad to get 13 bytes
1767
		$binary_code = str_pad($binary_code, 26, '0', STR_PAD_LEFT);
1768
		// convert string to array of bytes
1769
		$binary_code_arr = chunk_split($binary_code, 2, "\r");
1770
		$binary_code_arr = substr($binary_code_arr, 0, -1);
1771
		$binary_code_arr = explode("\r", $binary_code_arr);
1772
		// calculate frame check sequence
1773
		$fcs = $this->imb_crc11fcs($binary_code_arr);
0 ignored issues
show
Documentation introduced by
$binary_code_arr is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1774
		// exclude first 2 bits from first byte
1775
		$first_byte = sprintf('%2s', dechex((hexdec($binary_code_arr[0]) << 2) >> 2));
1776
		$binary_code_102bit = $first_byte.substr($binary_code, 2);
1777
		// convert binary data to codewords
1778
		$codewords = array();
1779
		$data = $this->hex_to_dec($binary_code_102bit);
1780
		$codewords[0] = bcmod($data, 636) * 2;
1781
		$data = bcdiv($data, 636);
1782
		for ($i = 1; $i < 9; ++$i) {
1783
			$codewords[$i] = bcmod($data, 1365);
1784
			$data = bcdiv($data, 1365);
1785
		}
1786
		$codewords[9] = $data;
1787
		if (($fcs >> 10) == 1) {
1788
			$codewords[9] += 659;
1789
		}
1790
		// generate lookup tables
1791
		$table2of13 = $this->imb_tables(2, 78);
1792
		$table5of13 = $this->imb_tables(5, 1287);
1793
		// convert codewords to characters
1794
		$characters = array();
1795
		$bitmask = 512;
1796
		foreach($codewords as $k => $val) {
1797
			if ($val <= 1286) {
1798
				$chrcode = $table5of13[$val];
1799
			} else {
1800
				$chrcode = $table2of13[($val - 1287)];
1801
			}
1802
			if (($fcs & $bitmask) > 0) {
1803
				// bitwise invert
1804
				$chrcode = ((~$chrcode) & 8191);
1805
			}
1806
			$characters[] = $chrcode;
1807
			$bitmask /= 2;
1808
		}
1809
		$characters = array_reverse($characters);
1810
		// build bars
1811
		$k = 0;
1812
		$bararray = array('code' => $code, 'maxw' => 0, 'maxh' => 3, 'bcode' => array());
1813
		for ($i = 0; $i < 65; ++$i) {
1814
			$asc = (($characters[$asc_chr[$i]] & pow(2, $asc_pos[$i])) > 0);
1815
			$dsc = (($characters[$dsc_chr[$i]] & pow(2, $dsc_pos[$i])) > 0);
1816
			if ($asc AND $dsc) {
1817
				// full bar (F)
1818
				$p = 0;
1819
				$h = 3;
1820
			} elseif ($asc) {
1821
				// ascender (A)
1822
				$p = 0;
1823
				$h = 2;
1824
			} elseif ($dsc) {
1825
				// descender (D)
1826
				$p = 1;
1827
				$h = 2;
1828
			} else {
1829
				// tracker (T)
1830
				$p = 1;
1831
				$h = 1;
1832
			}
1833
			$bararray['bcode'][$k++] = array('t' => 1, 'w' => 1, 'h' => $h, 'p' => $p);
1834
			$bararray['bcode'][$k++] = array('t' => 0, 'w' => 1, 'h' => 2, 'p' => 0);
1835
			$bararray['maxw'] += 2;
1836
		}
1837
		unset($bararray['bcode'][($k - 1)]);
1838
		--$bararray['maxw'];
1839
		return $bararray;
1840
	}
1841
	
1842
	/**
1843
	 * Convert large integer number to hexadecimal representation.
1844
	 * (requires PHP bcmath extension) 
1845
	 * @param string $number number to convert specified as a string
1846
	 * @return string hexadecimal representation
1847
	 */
1848
	public function dec_to_hex($number) {
1849
		$i = 0;
0 ignored issues
show
Unused Code introduced by
$i is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1850
		$hex = array();
1851
		if($number == 0) {
1852
			return '00';
1853
		}
1854
		while($number > 0) {
1855
			if($number == 0) {
1856
				array_push($hex, '0');
1857
			} else {
1858
				array_push($hex, strtoupper(dechex(bcmod($number, '16'))));
1859
				$number = bcdiv($number, '16', 0);
1860
			}
1861
		}
1862
		$hex = array_reverse($hex);
1863
		return implode($hex);
1864
	}
1865
	
1866
	/**
1867
	 * Convert large hexadecimal number to decimal representation (string).
1868
	 * (requires PHP bcmath extension) 
1869
	 * @param string $hex hexadecimal number to convert specified as a string
1870
	 * @return string hexadecimal representation
1871
	 */
1872
	public function hex_to_dec($hex) {
1873
		$dec = 0;
1874
		$bitval = 1;
1875
		$len = strlen($hex);
1876
		for($pos = ($len - 1); $pos >= 0; --$pos) {
1877
			$dec = bcadd($dec, bcmul(hexdec($hex{$pos}), $bitval));
1878
			$bitval = bcmul($bitval, 16);
1879
		}
1880
		return $dec;
1881
	}	
1882
	
1883
	/**
1884
	 * Intelligent Mail Barcode calculation of Frame Check Sequence
1885
	 * @param string $code_arr array of hexadecimal values (13 bytes holding 102 bits right justified).
1886
	 * @return int 11 bit Frame Check Sequence as integer (decimal base)
1887
	 * @access protected
1888
	 */
1889
	protected function imb_crc11fcs($code_arr) {
1890
		$genpoly = 0x0F35; // generator polynomial
1891
		$fcs = 0x07FF; // Frame Check Sequence
1892
		// do most significant byte skipping the 2 most significant bits
1893
		$data = hexdec($code_arr[0]) << 5;
1894 View Code Duplication
		for ($bit = 2; $bit < 8; ++$bit) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1895
			if (($fcs ^ $data) & 0x400) {
1896
				$fcs = ($fcs << 1) ^ $genpoly;
1897
			} else {
1898
				$fcs = ($fcs << 1);
1899
			}
1900
			$fcs &= 0x7FF;
1901
			$data <<= 1;
1902
		}
1903
		// do rest of bytes
1904
		for ($byte = 1; $byte < 13; ++$byte) {
1905
			$data = hexdec($code_arr[$byte]) << 3;
1906 View Code Duplication
			for ($bit = 0; $bit < 8; ++$bit) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1907
				if (($fcs ^ $data) & 0x400) {
1908
					$fcs = ($fcs << 1) ^ $genpoly;
1909
				} else {
1910
					$fcs = ($fcs << 1);
1911
				}
1912
				$fcs &= 0x7FF;
1913
				$data <<= 1;
1914
			}
1915
		}
1916
		return $fcs;		
1917
	}
1918
	
1919
	/**
1920
	 * Reverse unsigned short value
1921
	 * @param int $num value to reversr
1922
	 * @return int reversed value
1923
	 * @access protected
1924
	 */
1925
	protected function imb_reverse_us($num) {
1926
		$rev = 0;
1927
		for ($i = 0; $i < 16; ++$i) {
1928
			$rev <<= 1;
1929
			$rev |= ($num & 1);
1930
			$num >>= 1;
1931
		}
1932
		return $rev;
1933
	}
1934
	
1935
	/**
1936
	 * generate Nof13 tables used for Intelligent Mail Barcode
1937
	 * @param int $n is the type of table: 2 for 2of13 table, 5 for 5of13table
1938
	 * @param int $size size of table (78 for n=2 and 1287 for n=5)
1939
	 * @return array requested table
1940
	 * @access protected
1941
	 */
1942
	protected function imb_tables($n, $size) {
1943
		$table = array();
1944
		$lli = 0; // LUT lower index
1945
		$lui = $size - 1; // LUT upper index
1946
		for ($count = 0; $count < 8192; ++$count) {
1947
			$bit_count = 0;
1948
			for ($bit_index = 0; $bit_index < 13; ++$bit_index) {
1949
				$bit_count += intval(($count & (1 << $bit_index)) != 0);
1950
			}
1951
			// if we don't have the right number of bits on, go on to the next value
1952
			if ($bit_count == $n) {
1953
				$reverse = ($this->imb_reverse_us($count) >> 3);
1954
				// if the reverse is less than count, we have already visited this pair before
1955
				if ($reverse >= $count) {
1956
					// If count is symmetric, place it at the first free slot from the end of the list.
1957
					// Otherwise, place it at the first free slot from the beginning of the list AND place $reverse ath the next free slot from the beginning of the list
1958
					if ($reverse == $count) {
1959
						$table[$lui] = $count;
1960
						--$lui;
1961
					} else {
1962
						$table[$lli] = $count;
1963
						++$lli;
1964
						$table[$lli] = $reverse;
1965
						++$lli;
1966
					}
1967
				}
1968
			}
1969
		}
1970
		return $table;
1971
	}
1972
	
1973
} // end of class
1974
1975
//============================================================+
1976
// END OF FILE                                                 
1977
//============================================================+
1978
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
1979