Completed
Push — master ( 0c99ca...63ab58 )
by Roberto
05:23 queued 03:13
created

DefaultPrinter::barcodePDF417()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 42
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.893

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 42
ccs 1
cts 27
cp 0.037
rs 8.8571
cc 1
eloc 15
nc 1
nop 5
crap 1.893
1
<?php
2
3
namespace Posprint\Printers;
4
5
/*
6
 * Default class for POS thermal printers.
7
 * 
8
 * From this class all other are extended.
9
 * In the child classes should be included all the commands that are different
10
 * from those in this class, especially those specific to particular brand and 
11
 * model of printer
12
 * 
13
 * NOTE: It was built around the commands of the Epson TM-T20,
14
 * so in theory the Epson class will be almost empty just extending this class.
15
 * 
16
 * CodePage default CP437
17
 * CountyPage default LATIN
18
 * 
19
 * @category   NFePHP
20
 * @package    Posprint
21
 * @copyright  Copyright (c) 2016
22
 * @license    http://www.gnu.org/licenses/lesser.html LGPL v3
23
 * @author     Roberto L. Machado <linux.rlm at gmail dot com>
24
 * @link       http://github.com/nfephp-org/posprint for the canonical source repository
25
 */
26
27
use Posprint\Connectors\ConnectorInterface;
28
use Posprint\Connectors\Buffer;
29
use Posprint\Graphics\Graphics;
30
use Posprint\Printers\Barcodes\Barcode1DAnalysis;
31
use RuntimeException;
32
use InvalidArgumentException;
33
34
abstract class DefaultPrinter implements PrinterInterface
35
{
36
    //set standards
37
    const NUL = "\x0"; //Nulo
38
    const EOT = "\x4"; //EOT fim da transmissão
39
    const ENQ = "\x5"; //ENQ colocar na fila Pedido de status 1
40
    const HT = "\x9"; //tabulação horizontal
41
    const VT = "\xb"; //tabulação vertical
42
    const LF = "\x0a"; //Inicia a impressão e avança uma linha
43
    const FF = "\x0c"; //avança pagina
44
    const CR = "\x0d"; //retorno de carro
45
    const DLE = "\x10"; //Data Link Escape
46
    const CAN = "\x18"; //CAN Cancela linha enviada
47
    const BEL = "\x07"; //BEL sinal sonoro
48
    const ESC = "\x1b"; //escape
49
    const FS = "\x1c"; //FS
50
    const GS = "\x1d"; //GS
51
    const SO = "\x0e"; //SO Inicia modo expandido
52
    const DC1 = "\x11"; //DC1 Inicia modo enfatizado
53
    const DC2 = "\x12"; //DC2 Cancela modo condensado
54
    const DC3 = "\x13"; //DC3 Cancela modo enfatizado
55
    const DC4 = "\x14"; //DC4 Controle de dispositivo 4 Inicia modo normal
56
    const SI = "\x0f"; //Seleciona modo condensado
57
    const EM = "\x19"; //Avança 4 linhas
58
    const DEL = "\x7f"; //Cancela último caracter
59
    const NAK = "\x15"; //
60
    const SYN = "\x16"; //Sincronismo
61
    const NOTRANS = false; //not translate characters codepage
62
    const TRANS = true; //perform a character convertion to codepage
63
64
    //Cut types
65
    const CUT_FULL = 65;
66
    const CUT_PARTIAL = 66;
67
    
68
    //Image sizing options
69
    const IMG_DEFAULT = 0;
70
    const IMG_DOUBLE_WIDTH = 1;
71
    const IMG_DOUBLE_HEIGHT = 2;
72
73
    /**
74
     * List all available region pages.
75
     *
76
     * @var array
77
     */
78
    protected $aRegion = array(
79
        'USA',
80
        'FRANCE',
81
        'GERMANY',
82
        'UK',
83
        'DENMARK',
84
        'SWEDEN',
85
        'ITALY',
86
        'SPAIN',
87
        'JAPAN',
88
        'NORWAY',
89
        'DENMARK2',
90
        'SPAIN2',
91
        'LATIN',
92
        'KOREA',
93
        'SLOVENIA',
94
        'CHINA',
95
        'VIETNAM',
96
        'ARABIA'
97
    );
98
99
    /**
100
     * List all available code pages.
101
     *
102
     * @var array
103
     */
104
    protected $aCodePage = array(
105
        'CP437' => array('conv' => '437', 'table' => '0', 'desc' => 'PC437: USA, Standard Europe'),
106
        'CP850' => array('conv' => '850', 'table' => '2', 'desc' => 'PC850: Multilingual'),
107
        'CP860' => array('conv' => '860', 'table' => '3', 'desc' => 'PC860: Portuguese'),
108
        'CP863' => array('conv' => '863', 'table' => '4', 'desc' => 'PC863: Canadian-French'),
109
        'CP865' => array('conv' => '865', 'table' => '5', 'desc' => 'PC865: Nordic'),
110
        'CP851' => array('conv' => '851', 'table' => '11', 'desc' => 'PC851: Greek'),
111
        'CP853' => array('conv' => '853', 'table' => '12', 'desc' => 'PC853: Turkish'),
112
        'CP857' => array('conv' => '857', 'table' => '13', 'desc' => 'PC857: Turkish'),
113
        'CP737' => array('conv' => '737', 'table' => '14', 'desc' => 'PC737: Greek'),
114
        'ISO8859-7' => array('conv' => 'ISO8859-7', 'table' => '15', 'desc' => 'ISO8859-7: Greek'),
115
        'CP866' => array('conv' => '866', 'table' => '17', 'desc' => 'PC866: Cyrillic #2'),
116
        'CP852' => array('conv' => '852', 'table' => '18', 'desc' => 'PC852: Latin2'),
117
        'CP858' => array('conv' => '858', 'table' => '19', 'desc' => 'PC858: Euro'),
118
        'CP720' => array('conv' => '720', 'table' => '32', 'desc' => 'PC720: Arabic'),
119
        'CP855' => array('conv' => '855', 'table' => '34', 'desc' => 'PC855: Cyrillic'),
120
        'CP861' => array('conv' => '861', 'table' => '35', 'desc' => 'PC861: Icelandic'),
121
        'CP862' => array('conv' => '862', 'table' => '36', 'desc' => 'PC862: Hebrew'),
122
        'CP864' => array('conv' => '864', 'table' => '37', 'desc' => 'PC864: Arabic'),
123
        'CP869' => array('conv' => '869', 'table' => '38', 'desc' => 'PC869: Greek'),
124
        'ISO8859-2' => array('conv' => 'ISO8859-2', 'table' => '39', 'desc' => 'ISO8859-2: Latin2'),
125
        'ISO8859-15' => array('conv' => 'ISO8859-15', 'table' => '40', 'desc' => 'ISO8859-15: Latin9'),
126
        'WINDOWS-1250' => array('conv' => 'WINDOWS-1250', 'table' => '45', 'desc' => 'WPC1250: Latin2'),
127
        'WINDOWS-1251' => array('conv' => 'WINDOWS-1251', 'table' => '46', 'desc' => 'WPC1251: Cyrillic'),
128
        'WINDOWS-1252' => array('conv' => 'WINDOWS-1252', 'table' => '47', 'desc' => 'WPC1253: Greek'),
129
        'WINDOWS-1254' => array('conv' => 'WINDOWS-1254', 'table' => '48', 'desc' => 'WPC1254: Turkish'),
130
        'WINDOWS-1255' => array('conv' => 'WINDOWS-1255', 'table' => '49', 'desc' => 'WPC1255: Hebrew'),
131
        'WINDOWS-1256' => array('conv' => 'WINDOWS-1256', 'table' => '50', 'desc' => 'WPC1256: Arabic'),
132
        'WINDOWS-1257' => array('conv' => 'WINDOWS-1257', 'table' => '51', 'desc' => 'WPC1257: Baltic Rim'),
133
        'WINDOWS-1258' => array('conv' => 'WINDOWS-1258', 'table' => '52', 'desc' => 'WPC1258: Vietnamese'),
134
    );
135
    
136
    /**
137
     * Seleted code page
138
     * Defined in printer class.
139
     *
140
     * @var string
141
     */
142
    protected $codepage = 'CP437';
143
    /**
144
     * Number of codpage in printer memory.
145
     *
146
     * @var int
147
     */
148
    protected $charsetTableNum = 0;
149
    /**
150
     * Selected Region character page
151
     * Defined in printer class.
152
     *
153
     * @var string
154
     */
155
    protected $region = 'LATIN';
156
    /**
157
     * List all avaiable fonts
158
     *
159
     * @var array
160
     */
161
    protected $aFont = array(0 => 'A', 1 => 'B', 2 => 'C', 3 => 'D', 4 => 'E', 97 => 'SA', 98 => 'SB');
162
    /**
163
     * Selected internal font.
164
     *
165
     * @var string
166
     */
167
    protected $font = 'A';
168
    /**
169
     * Resolution in dpi.
170
     *
171
     * @var int
172
     */
173
    public $dpi = 203; //dots per inch
174
    /**
175
     * Resolution in dpmm.
176
     *
177
     * @var int
178
     */
179
    public $dpmm = 8; //dots per mm
180
    /**
181
     * Maximum width paper.
182
     *
183
     * @var int
184
     */
185
    public $widthMaxmm = 80;//mm
186
    /**
187
     * Selected Width paper.
188
     *
189
     * @var int
190
     */
191
    public $widthPaper = 80;//mm
192
    /**
193
     * Maximum width for printed area.
194
     *
195
     * @var int
196
     */
197
    public $widthPrint = 72;//mm
198
    /**
199
     * Maximum width for printed area in dots.
200
     *
201
     * @var int
202
     */
203
    public $widthMaxdots = 576;//dots
204
    /**
205
     * Maximum number of characters per line.
206
     *
207
     * @var int
208
     */
209
    public $maxchars = 48;//max characters per line
210
211
    //protected property standards
212
    /**
213
     * Connector to printer.
214
     *
215
     * @var ConnectosInterface
216
     */
217
    protected $connector = null;
218
    /**
219
     * Seleted printer mode.
220
     *
221
     * @var string
222
     */
223
    protected $printerMode = 'normal';
224
    /**
225
     * Selected bold mode.
226
     *
227
     * @var bool
228
     */
229
    protected $boldMode = false;
230
    /**
231
     * Selected italic mode.
232
     *
233
     * @var bool
234
     */
235
    protected $italicMode = false;
236
    /**
237
     * Selected condenced mode.
238
     *
239
     * @var bool
240
     */
241
    protected $condensedMode = false;
242
    /**
243
     * Selected expanded mode.
244
     * @var bool
245
     */
246
    protected $expandedMode = false;
247
    /**
248
     * Seleted double higth mode.
249
     * @var bool
250
     */
251
    protected $doubleHeigth = false;
252
    /**
253
     * Selected reverse colors mode.
254
     *
255
     * @var bool
256
     */
257
    protected $reverseColors = false;
258
    /**
259
     * Selected under lined mode.
260
     *
261
     * @var bool
262
     */
263
    protected $underlineMode = false;
264
    /**
265
     * Selected rotate 90 degrees mode
266
     *
267
     * @var bool
268
     */
269
    protected $rotateMode = false;
270
    /**
271
     * Buffer class.
272
     *
273
     * @var Connectors\Buffer
274
     */
275 27
    protected $buffer = null;
276
    /**
277 27
     * Acceptable barcodes list
278
     * @var array
279
     */
280 27
    protected $barcode1Dlist = [
281 27
        'UPC_A' => 65,
282
        'UPC_E' => 66,
283
        'EAN13' => 67,
284
        'EAN8' => 68,
285
        'CODE39' => 69,
286
        'I25' => 70,
287
        'CODABAR' => 71,
288
        'CODE93' => 72,
289
        'CODE128' => 73,
290
        'GS1128' => 74,
291
        'GS1DATABAROMINI' => 75,
292
        'GS1DATABARTRUNC' => 76,
293 2
        'GS1DATABARLIMIT' => 77,
294
        'GS1DATABAREXPAN' => 78
295 2
    ];
296 2
    /**
297 2
     * List of supported models
298 1
     * @var array
299
     */
300 2
    protected $modelList = [
301 2
        'T20'
302 2
    ];
303 2
    /**
304 2
     * Selected model
305 2
     * @var string
306
     */
307
    protected $printerModel = 'T20';
308
309
    /**
310
     * Class constructor
311
     * Instantiates the data buffer.
312
     *
313
     * @param ConnectorInterface $conn
314
     */
315
    public function __construct(ConnectorInterface $conn = null)
316
    {
317
        if (!is_null($conn)) {
318 21
            $this->connector = $conn;
0 ignored issues
show
Documentation Bug introduced by
It seems like $conn of type object<Posprint\Connectors\ConnectorInterface> is incompatible with the declared type object<Posprint\Printers\ConnectosInterface> of property $connector.

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...
319
        }
320 21
        $this->buffer = new Buffer();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \Posprint\Connectors\Buffer() of type object<Posprint\Connectors\Buffer> is incompatible with the declared type object<Posprint\Printers\Connectors\Buffer> of property $buffer.

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...
321 21
    }
322 21
    
323 1
    /**
324
     * Return default printer model
325 21
     * @param string $model
326 3
     * @return string|array
327 3
     */
328 3
    public function defaultModel($model = 'T20')
329 3
    {
330 21
        if (!is_null($model)) {
331 21
            $model = strtoupper(trim($model));
332
            if ($model == 'ALL') {
333
                return $this->modelList;
334
            }
335
        }
336
        if (array_key_exists($model, $this->modelList)) {
337
            $this->printerModel = $model;
338
        }
339 2
        return $model;
340
    }
341 2
    
342 2
    /**
343 2
     * Returns a default region for codepage
344
     * if param $region is null will return actual default region from class
345
     * if param $region is 'all' will return a array with all avaiable regions
346
     * if param $region is a string will set the region parameter of class and returns it.
347
     * NOTE: This command do not set the printer, only class parameters
348
     *
349
     * @param  string $region
350
     * @return string|array
351 1
     */
352
    public function defaultRegionPage($region = null)
353 1
    {
354 1
        if (!is_null($region)) {
355 1
            $region = strtoupper(trim($region));
356 1
            if ($region == 'ALL') {
357
                return $this->aRegion;
358
            }
359
            $reg = array_search($region, $this->aRegion, true);
360
            if ($reg !== false) {
361
                $this->region = $region;
362
            }
363
        }
364
        return $this->region;
365
    }
366
367
    /**
368
     * Returns a default codepage
369
     * if param $codepage is null will return actual default codepage from class
370
     * if param $codepage is 'all' will return a array with all avaiable codepages
371
     * if param $codepage is a string will set the codepage parameter of class and returns it.
372
     * NOTE: This command do not set the printer, only class parameters
373
     *
374
     * @param  string $codepage
375
     * @return string|array
376 3
     */
377
    public function defaultCodePage($codepage = null)
378 3
    {
379 3
        if (!is_null($codepage)) {
380 3
            $codepage = strtoupper(trim($codepage));
381
            if ($codepage == 'ALL') {
382 1
                return array_keys($this->aCodePage);
383
            }
384
            if (array_key_exists($codepage, $this->aCodePage)) {
385 2
                $this->codepage = $codepage;
386 2
                $table = $this->aCodePage[$codepage];
387 2
                $this->charsetTableNum = $table['table'];
388 2
            }
389 2
        }
390 2
        return $this->codepage;
391 2
    }
392 2
393
    /**
394
     * Returns the default printer font
395
     * A - Font A (12 x 24)
396
     * B - Font B (9 x 17)
397
     * C - Font C
398
     * D - Font D
399
     * E - Font E
400
     * Special A
401 1
     * Special B
402
     * Default Font A.
403 1
     * if param $font is null will return actual default font from class
404 1
     * if param $font is 'all' will return a array with all avaiable printer fonts
405 1
     * if param $font is a string will set the font parameter of class and returns it.
406 1
     * NOTE: This command do not set the printer, only class parameters
407
     *
408
     * @param  string $font
409
     * @return array|string
410
     */
411 1
    public function defaultFont($font = null)
412
    {
413 1
        if (!is_null($font)) {
414 1
            $font = strtoupper(trim($font));
415 1
            if ($font == 'ALL') {
416 1
                //return array
417 1
                return $this->aFont;
418 1
            }
419
            //set $this->font
420 1
            $fonts = array_flip($this->aFont);
421 1
            $keys = array_keys($fonts);
422
            $reg = array_search($font, $keys, true);
423
            if ($reg !== false) {
424
                $this->font = $font;
425
            }
426 1
        }
427
        return $this->font;
428 1
    }
429 1
430 1
    /**
431 1
     * initialize printer
432 1
     * Clears the data in the print buffer and resets the printer modes to
433 1
     * the modes that were in effect when the power was turned on.
434
     */
435 1
    public function initialize()
436 1
    {
437
        $this->rotateMode = false;
438
        $this->boldMode = false;
439
        $this->italicMode = false;
440
        $this->underlineMode = false;
441
        $this->printerMode = 'normal';
442
        $this->defaultModel();
443
        $this->defaultCodePage();
444
        $this->defaultRegionPage();
445
        $this->defaultFont();
446
        $this->buffer->write(self::ESC.'@');
447
        $this->setPrintMode();
448
        $this->setFont();
449
        $this->setCodePage();
450
        $this->setRegionPage();
451
    }
452
453
    /**
454 1
     * Set the printer mode.
455
     */
456 1
    abstract public function setPrintMode($mode = null);
457
    
458
    /**
459 1
     * Set a codepage table in printer.
460
     *
461 1
     * @param string $codepage
462 1
     */
463 1
    public function setCodePage($codepage = null)
464 1
    {
465
        $codepage = $this->defaultCodePage($codepage);
0 ignored issues
show
Unused Code introduced by
$codepage 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...
466
        $this->buffer->write(self::ESC.'t'.chr($this->charsetTableNum));
467 1
    }
468 1
469 1
    /**
470 1
     * Set a region page.
471 1
     * The numeric key of array $this->aRegion is the command parameter.
472
     *
473
     * @param string $region
474
     */
475
    public function setRegionPage($region = null)
476
    {
477 1
        $region = $this->defaultRegionPage($region);
478
        $mode = array_keys($this->aRegion, $region, true);
479 1
        $this->buffer->write(self::ESC.'R'.chr($mode[0]));
480 1
    }
481 1
    
482 1
    /**
483 1
     * Set a printer font
484 1
     * If send a valid font name will set the printer otherelse a default font is selected
485
     *
486 1
     * @param string $font
487 1
     */
488
    public function setFont($font = null)
489
    {
490
        $font = $this->defaultFont($font);
491
        $mode = array_keys($this->aFont, $font, true);
492
        $this->buffer->write(self::ESC.'M'.chr($mode[0]));
493
    }
494 1
495
    /**
496 1
     * Set emphasys mode on or off.
497
     */
498 1
    public function setBold()
499 1
    {
500 1
        $mode = 1;
501 1
        if ($this->boldMode) {
502 1
            $mode = 0;
503 1
        }
504 1
        $this->boldMode = ! $this->boldMode;
505 1
        $this->buffer->write(self::ESC . 'E' . chr($mode));
506 1
    }
507 1
508 1
    /**
509 1
     * Set underline mode on or off.
510
     */
511
    public function setUnderlined()
512
    {
513
        $mode = 1;
514
        if ($this->underlineMode) {
515
            $mode = 0;
516
        }
517
        $this->underlineMode = ! $this->underlineMode;
518
        $this->buffer->write(self::ESC . '-' . chr($mode));
519
    }
520
    
521
    /**
522
     * Set italic mode on or off
523
     *
524
     * @return bool
525
     */
526
    public function setItalic()
527
    {
528
        //dont exists in this printer
529 1
    }
530
    
531 1
    /**
532 1
     * Aligns all data in one line to the selected layout in standard mode.
533 1
     * L - left  C - center  R - rigth
534 1
     *
535 1
     * @param string $align
536 1
     */
537
    public function setAlign($align = null)
538 1
    {
539 1
        if (is_null($align)) {
540
            $align = 'L';
541
        }
542
        $value = strtoupper($align);
543
        switch ($value) {
544
            case 'C':
545
                $mode = 1;
546 21
                break;
547
            case 'R':
548 21
                $mode = 2;
549 21
                break;
550 21
            default:
551 21
                $mode = 0;
552 21
        }
553 21
        $this->buffer->write(self::ESC . 'a' . chr($mode));
554 21
    }
555 21
    
556
    /**
557
     * Turns white/black reverse print On or Off for characters.
558
     * n = odd: On, n = even: Off.
559
     */
560
    public function setReverseColors()
561
    {
562
        $mode = 0;
563
        $this->reverseColors = ! $this->reverseColors;
564 1
        if ($this->reverseColors) {
565
            $mode = 1;
566 1
        }
567 1
        $this->buffer->write(self::GS.'B'.chr($mode));
568 1
    }
569
    
570
    /**
571
     * Set expanded mode.
572
     *
573
     * @param int $size multiplies normal size 1 - 8
574
     */
575
    public function setExpanded($size = null)
576
    {
577
        $size = self::validateInteger($size, 1, 8, 1);
578 1
        $aSize = [
579
            [0, 0],
580 1
            [16, 1],
581 1
            [32, 2],
582 1
            [48, 3],
583 1
            [64, 4],
584
            [80, 5],
585
            [96, 6],
586
            [112, 7]
587
        ];
588
        $mode = $aSize[$size-1][0] + $aSize[$size-1][1];
589
        $this->buffer->write(self::ESC.'!'.chr($mode));
590
    }
591 1
592
    /**
593 1
     * Set condensed mode.
594 1
     */
595 1
    public function setCondensed()
596
    {
597
        $this->setExpanded(1);
598
        $this->setFont('B');
599
    }
600
    
601
    /**
602
     * Set rotate 90 degrees.
603
     */
604
    public function setRotate90()
605
    {
606 1
        $this->rotateMode = !$this->rotateMode;
607
        $mode = 0;
608 1
        if ($this->rotateMode) {
609 1
            $mode = 1;
610 1
        }
611 1
        $this->buffer->write(self::ESC.'V'.chr($mode));
612 1
    }
613
    
614 1
    /**
615
     * Send message or command to buffer
616 1
     * when sending commands is not required to convert characters,
617
     * so the variable may translate by false.
618
     *
619 1
     * @param string $text
620 1
     */
621
    public function text($text = '')
622
    {
623
        $text = $this->translate($text);
624
        $this->buffer->write($text);
625
    }
626
627
    /**
628 1
     * Set horizontal and vertical motion units
629
     * $horizontal => character spacing 1/x"
630 1
     * $vertical => line spacing 1/y".
631 1
     *
632 1
     * @param int $horizontal
633 1
     * @param int $vertical
634
     */
635 1
    public function setSpacing($horizontal = 30, $vertical = 30)
636 1
    {
637
        $horizontal = self::validateInteger($horizontal, 0, 255, 30);
638
        $vertical = self::validateInteger($vertical, 0, 255, 30);
639
        $this->buffer->write(self::GS.'P'.chr($horizontal).chr($vertical));
640
    }
641
642
    /**
643
     * Set right-side character spacing
644 1
     * 0 ≤ n ≤ 255 => 1/x".
645
     *
646 1
     * @param int $value
647 1
     */
648 1
    public function setCharSpacing($value = 3)
649
    {
650
        $value = self::validateInteger($value, 0, 255, 0);
651
        $this->buffer->write(self::ESC.' '.chr($value));
652
    }
653
654
    /**
655
     * Line spacing
656
     * The default is set to zero and 30/180 "
657
     * any different number of zero will generate multiples of.
658 1
     * n  1/180-inch vertical motion
659
     * normal paragraph 30/180" => 4.23 mm
660 1
     *
661 1
     * @param int $paragraph
0 ignored issues
show
Bug introduced by
There is no parameter named $paragraph. 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...
662 1
     */
663 1
    public function setParagraph($value = 0)
664 1
    {
665
        $value = self::validateInteger($value, 0, 255, 0);
666
        $paragraph = ceil($value);
667
        if ($paragraph == 0) {
668
            $this->buffer->write(self::ESC.'2');
669
            return;
670
        }
671
        if ($paragraph < 25) {
672 1
            $paragraph = 25;
673
        } elseif ($paragraph > 255) {
674 1
            $paragraph = 255;
675 1
        }
676 1
        $this->buffer->write(self::ESC.'3'.chr($paragraph));
677 1
    }
678 1
679
    /**
680 1
     * Prints data and feeds paper n lines
681 1
     * ESC d n Prints data and feeds paper n lines.
682
     *
683
     * @param integer $lines
684
     */
685
    public function lineFeed($lines = 1)
686
    {
687
        $lines = self::validateInteger($lines, 0, 255, 1);
688
        if ($lines == 1) {
689
            $this->buffer->write(self::LF);
690
            return;
691
        }
692
        $this->buffer->write(self::ESC.'d'.chr($lines));
693
    }
694
695
    /**
696
     * Prints data and feeds paper n dots
697
     * ESC J n Prints data and feeds paper n dots.
698
     *
699
     * @param int $dots
700
     */
701
    public function dotFeed($dots = 1)
702
    {
703
        $dots = self::validateInteger($dots, 0, 80, 0);
704
        $this->buffer->write(self::ESC.'J'.chr($dots));
705
    }
706
707
    /**
708
     * Generate a pulse, for opening a cash drawer if one is connected.
709
     * The default settings should open an Epson drawer.
710
     *
711
     * @param int $pin    0 or 1, for pin 2 or pin 5 kick-out connector respectively.
712
     * @param int $on_ms  pulse ON time, in milliseconds.
713
     * @param int $off_ms pulse OFF time, in milliseconds.
714
     */
715
    public function pulse($pin = 0, $on_ms = 120, $off_ms = 240)
716
    {
717
        $pin = self::validateInteger($pin, 0, 1, 0);
718
        $on_ms = self::validateInteger($on_ms, 1, 511, 120);
719
        $off_ms = self::validateInteger($off_ms, 1, 511, 240);
720
        $this->buffer->write(self::ESC.'p'.chr($pin + 48).chr($on_ms / 2).chr($off_ms / 2));
721 1
    }
722
723
    /**
724
     * Cut the paper.
725
     *
726
     * @param int $mode  FULL or PARTIAL. If not specified, FULL will be used.
727
     * @param int $lines Number of lines to feed after cut
728
     */
729
    public function cut($mode = 'PARTIAL', $lines = 3)
730 1
    {
731
        $lines = self::validateInteger($lines, 1, 10, 3);
732
        if ($mode == 'FULL') {
733 1
            $mode = self::CUT_FULL;
734
        } else {
735
            $mode = self::CUT_PARTIAL;
736 1
        }
737
        $this->buffer->write(self::GS.'V'.chr($mode).chr($lines));
738
    }
739 1
740
    /**
741 1
     * Implements barcodes 1D
742 1
     * GS k m n d1...dn
743 1
     * Prints bar code. n specifies the data length.
744 1
     *   m    bar code system             number of d (=k)
745
     *  "A"     UPC-A                       11 or 12
746
     *  "B"     UPC-E                       6, 7, 8, 11 or 12
747 1
     *  "C"     JAN13 / EAN13               12 or 13
748 1
     *  "D"     JAN8 / EAN8                 7 or 8
749
     *  "E"     CODE39                      1 or more
750
     *  "F"     ITF                         even
751 1
     *  "G"     CODABAR (NW-7)              2 or more
752 1
     *  "H"     CODE93                      1–255
753 1
     *  "I"     CODE128                     2–255
754
     *  "J"     GS1-128                     2–255
755 1
     *  "K"     GS1 DataBar Omnidirectional 13
756
     *  "L"     GS1 DataBar Truncated       13
757 1
     *  "M"     GS1 DataBar Limited         13
758
     *  "N"     GS1 DataBar Expanded        2–255.
759 1
     *
760
     *  GS h n Sets bar code height to n dots.
761 1
     *  GS w n Sets bar width of bar code. n = 2–6 (thin–thick)
762
     *  GS H n Selects print position of HRI characters.
763 1
     *           n = 0, "0": Not printed
764 1
     *           n = 1, "1": Above the bar code
765
     *           n = 2, "2": Below the bar code
766
     *           n = 3, "3": Both above and below the bar code
767
     *  GS f n Selects font for the HRI characters.
768
     *           n = 0, "0": Font A,
769
     *           n = 1, "1": Font B
770
     *
771
     * @param string $data
772
     * @param int    $type        Default CODE128
773
     * @param int    $height
774 1
     * @param int    $lineWidth
775
     * @param string $txtPosition
776
     * @param string $txtFont
777 1
     */
778 1
    public function barcode(
779
        $data = '123456',
780
        $type = 'CODE128',
781
        $height = 162,
782 1
        $lineWidth = 2,
783
        $txtPosition = 'none',
784 1
        $txtFont = ''
785
    ) {
786 1
        switch ($txtPosition) {
787
            case 'Above':
788 1
                $tPos = 1;
789
                break;
790
            case 'Below':
791 1
                $tPos = 2;
792 1
                break;
793 1
            case 'Both':
794
                $tPos = 3;
795
                break;
796
            default:
797
                //none
798
                $tPos = 0;
799
        }
800
        $font = 0;
801
        if ($txtFont === 'B') {
802
            $font = 1;
803 1
        }
804
        if (! $data = Barcodes\Barcode1DAnalysis::validate($data, $type)) {
805 1
            throw new \InvalidArgumentException('Data or barcode type is incorrect.');
806 1
        }
807 1
        if (! array_key_exists($type, $this->barcode1Dlist)) {
808 1
            throw new \InvalidArgumentException('This barcode type is not listed.');
809
        }
810 1
        $id = $this->barcode1Dlist[$type];
811 1
        if (is_null($id)) {
812
            return;
813
        }
814
        $height = self::validateInteger($height, 1, 255, 4);
815
        $lineWidth = self::validateInteger($lineWidth, 1, 6, 2);
816
        $nlen = strlen($data);
817
        //set barcode height
818
        $this->buffer->write(self::GS.'h'.chr($height));
819
        //set barcode bar width
820
        $this->buffer->write(self::GS.'w'.chr($lineWidth));
821
        //Selects print position of HRI characters.
822
        $this->buffer->write(self::GS.'H'.chr($tPos));
823
        //Selects font for the HRI characters.
824
        $this->buffer->write(self::GS.'f'.chr($font));
825
        //Print barcode
826
        $this->buffer->write(self::GS.'k'.chr($id).chr($nlen).$data);
827 20
    }
828
    
829
    /**
830 20
     * Print PDF 417 2D barcode
831
     * @param string $data
832
     * @param integer $ecc
833
     * @param integer $pheight
834 20
     * @param integer $pwidth
835
     * @param integer $colunms
836 20
     * @return boolean
837 20
     */
838
    public function barcodePDF417($data, $ecc = 5, $pheight = 2, $pwidth = 2, $colunms = 3)
839
    {
840
        $ecc = self::validateInteger($ecc, 0, 8, 5);
841
        $pheight = self::validateInteger($pheight, 1, 8, 2);
842
        $n = $ecc + 48;
843
        $length = strlen($data);
844
        $pH = intval($length / 256);
845
        $pL = ($length % 256);
846
        //Set the number of columns in the data region
847
        //GS (   k  pL pH cn fn n
848
        //29 40 107 3   0 48 65 n
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
849
        $this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(65).chr(0));
850
        //Set the number of rows
851
        //GS  (      k   pL  pH  cn fn n
852
        //29  40    107  3    0  48 66 n
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
853
        $this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(66).chr(0));
854
        //Set the width of the module
855
        //GS  (   k   pL   pH  cn  fn n
856
        //29  40 107  3    0   48  67 n
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
857
        $this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(67).chr(0));
858
        //Set the row height
859
        //GS  (    k   pL  pH  cn  fn n
860 20
        //29  40  107  3   0   48  68 n
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
861
        //pheight 3 or 5 time pwidth
862
        $this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(68).chr($pheight));
863
        //Set the error correction level
864
        //GS  (    k    pL  pH     cn fn m n
865
        //29  40  107    4   0     48 69 m n n = 48 - 56
866
        $this->buffer->write(self::GS."(k".chr(4).chr(0).chr(48).chr(69).chr(58).chr($n));
867
        //Select the options
868
        //GS  (    k    pL   pH   cn   fn   n
869
        //29  40  107   3     0   48   70   n
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
870
        $this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(70).chr(0));
871
        //Store the data in the symbol storage area
872
        //GS  (   k   pL  pH   cn  fn  m   d1...dk
873
        //29  40 107  pL  pH   48  80  48  d1...dk
0 ignored issues
show
Unused Code Comprehensibility introduced by
37% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
874
        $this->buffer->write(self::GS."(k".chr($pL).chr($pH).chr(48).chr(80).chr(48).$data);
875
        //Print the symbol data in the symbol storage area
876
        //GS  (   k   pL  pH  cn  fn m
877
        //29  40 107  3    0   48  81 m
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
878
        $this->buffer->write(self::GS."(k".chr(3).chr(0).chr(48).chr(81).chr(0));
879
    }
880
    
881
    /**
882
     * Imprime o QR Code
883
     *
884
     * @param string $data   Dados a serem inseridos no QRCode
885
     * @param string $level  Nivel de correção L,M,Q ou H
886
     * @param int    $modelo modelo de QRCode 1, 2 ou 0 Micro
887
     * @param int    $wmod   largura da barra 3 ~ 16
888 1
     */
889
    public function barcodeQRCode($data = '', $level = 'L', $modelo = 2, $wmod = 4)
890
    {
891 1
        //set model of QRCode
892 1
        $n1 = 50;
893 1
        if ($modelo == 1) {
894 1
            $n1 = 49;
895 1
        }
896 1
        //select QR model
897 1
        $this->buffer->write(self::GS."(k".chr(4).chr(0).chr(49).chr(65).chr($n1).chr(0));
898 1
        //set module bar width
899 1
        $this->buffer->write(self::GS."(k".chr(3).chr(0).chr(49).chr(67).chr($wmod));
900 1
        //set error correction level
901 1
        $level = strtoupper($level);
902 1
        switch ($level) {
903 1
            case 'L':
904 1
                $n = 48;
905 1
                break;
906 1
            case 'M':
907
                $n = 49;
908
                break;
909 1
            case 'Q':
910 1
                $n = 50;
911 1
                break;
912 1
            case 'H':
913
                $n = 51;
914
                break;
915
            default:
916
                $n = 49;
917
        }
918 1
        $this->buffer->write(self::GS."(k".chr(3).chr(0).chr(49).chr(69).chr($n));
919
        //set data for QR Code assuming print only alphanumeric data
920
        $len = strlen($data) + 3;
921
        $pH = ($len / 256);
922
        $pL = $len % 256;
923
        $this->buffer->write(self::GS."(k".chr($pL).chr($pH).chr(49).chr(80).chr(48).$data);
924
        //Print QR Code
925
        $this->buffer->write(self::GS."(k".chr(3).chr(0).chr(49).chr(81).chr(48));
926
    }
927
928
    /**
929
     * Return all data buffer.
930 1
     *
931
     * @param string $type specifies the return format
932
     */
933 1
    public function getBuffer($type = '')
934 1
    {
935
        switch ($type) {
936
            case 'binA':
937
                //returns a binary array of buffer
938
                $resp = $this->buffer->getDataBinary(true);
939 1
                break;
940 1
            case 'binS':
941 1
                //returns a binary string of buffer
942 1
                $resp = $this->buffer->getDataBinary(false);
943 1
                break;
944 1
            case 'b64A':
945 1
                //returns a base64 encoded array of buffer
946 1
                $resp = $this->buffer->getDataBase64(true);
947 1
                break;
948 1
            case 'b64S':
949
                //returns a base64 encoded string of buffer
950
                $resp = $this->buffer->getDataBase64(false);
951
                break;
952
            case 'json':
953
                //returns a json encoded of array buffer
954
                $resp = $this->buffer->getDataJson();
955
                break;
956
            case 'readA':
957 1
                //returns a human readable format of array buffer
958
                //only for debug reasons
959 1
                $resp = $this->buffer->getDataReadable(true);
960 1
                break;
961 1
            default:
962
                //returns a human readable format of string buffer
963
                //only for debug reasons
964
                $resp = $this->buffer->getDataReadable(false);
965
        }
966
        return $resp;
967
    }
968
969
    /**
970 1
     * Send commands from buffer to connector printer.
971
     */
972 1
    public function send(ConnectorInterface $conn = null)
973 1
    {
974 1
        if (!is_null($conn)) {
975 1
            $this->connector = $conn;
0 ignored issues
show
Documentation Bug introduced by
It seems like $conn of type object<Posprint\Connectors\ConnectorInterface> is incompatible with the declared type object<Posprint\Printers\ConnectosInterface> of property $connector.

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...
976 1
        }
977 1
        if (is_null($this->connector)) {
978 1
            return $this->getBuffer();
979
        }
980
        $aCmds = $this->getBuffer('binA');
981
        foreach ($aCmds as $cmd) {
982
            $this->connector->write($cmd);
983
        }
984
    }
985
986
    /**
987
     * Insert a image.
988
     *
989 1
     * @param  string $filename Path to image file
990
     * @param  float  $width
991 1
     * @param  float  $height
992 1
     * @param  int    $size     0-normal 1-Double Width 2-Double Heigth
993 1
     * @throws RuntimeException
994 1
     */
995 1
    public function putImage($filename = '', $width = null, $height = null, $size = 0)
996
    {
997
        try {
998
            $img = new Graphics($filename, $width, $height);
999 1
        } catch (RuntimeException $e) {
1000 1
            throw new RuntimeException($e->getMessage());
1001
        } catch (InvalidArgumentException $e) {
1002
            throw new RuntimeException($e->getMessage());
1003
        }
1004
        $size = self::validateInteger($size, 0, 3, 0);
1005
        $imgHeader = self::dataHeader(array($img->getWidth(), $img->getHeight()), true);
1006
        $tone = '0';
1007
        $colors = '1';
1008
        $xm = (($size & self::IMG_DOUBLE_WIDTH) == self::IMG_DOUBLE_WIDTH) ? chr(2) : chr(1);
1009
        $ym = (($size & self::IMG_DOUBLE_HEIGHT) == self::IMG_DOUBLE_HEIGHT) ? chr(2) : chr(1);
1010
        $header = $tone.$xm.$ym.$colors.$imgHeader;
1011
        $this->sendGraphicsData('0', 'p', $header.$img->getRasterImage());
1012
        $this->sendGraphicsData('0', '2');
1013
    }
1014
1015
    /**
1016
     * Close and clean buffer
1017
     * All data will be lost.
1018
     */
1019
    public function close()
1020
    {
1021
        $this->buffer->close();
1022
    }
1023
    
1024
    /**
1025
     * Wrapper for GS ( L, to calculate and send correct data length.
1026
     *
1027
     * @param string $m    Modifier/variant for function. Usually '0'.
1028 10
     * @param string $fn   Function number to use, as character.
1029
     * @param string $data Data to send.
1030 10
     */
1031 1
    protected function sendGraphicsData($m, $fn, $data = '')
1032
    {
1033 10
        $header = $this->intLowHigh(strlen($data) + 2, 2);
1034
        $this->buffer->write(self::GS.'(L'.$header.$m.$fn.$data);
1035
    }
1036
1037
    /**
1038
     * Generate two characters for a number:
1039
     * In lower and higher parts, or more parts as needed.
1040
     *
1041
     * @param int $int    Input number
0 ignored issues
show
Bug introduced by
There is no parameter named $int. 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...
1042
     * @param int $length The number of bytes to output (1 - 4).
1043
     */
1044
    protected static function intLowHigh($input, $length)
1045
    {
1046
        $maxInput = (256 << ($length * 8) - 1);
0 ignored issues
show
Unused Code introduced by
$maxInput 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...
1047
        $outp = '';
1048
        for ($i = 0; $i < $length; ++$i) {
1049
            $outp .= chr($input % 256);
1050
            $input = (int) ($input / 256);
1051
        }
1052
        return $outp;
1053
    }
1054
1055
    /**
1056
     * Convert widths and heights to characters.
1057
     * Used before sending graphics to set the size.
1058 1
     *
1059
     * @param  array $inputs
1060 1
     * @param  bool  $long   True to use 4 bytes, false to use 2
1061 1
     * @return string
1062 1
     */
1063 1
    protected static function dataHeader(array $inputs, $long = true)
1064 1
    {
1065 1
        $outp = array();
1066 1
        foreach ($inputs as $input) {
1067 1
            if ($long) {
1068
                $outp[] = self::intLowHigh($input, 2);
1069
            } else {
1070
                $input = self::validateInteger($input, 0, 255, 0);
1071
                $outp[] = chr($input);
1072
            }
1073
        }
1074
        return implode('', $outp);
1075
    }
1076
1077
    /**
1078
     * Verify if the argument given is not a boolean.
1079
     *
1080
     * @param  bool $test    the input to test
1081
     * @param  bool $default the default value
1082
     * @return bool
1083
     */
1084
    protected static function validateBoolean($test, $default)
1085
    {
1086
        if (!($test === true || $test === false)) {
1087
            return $default;
1088
        }
1089
        return $test;
1090
    }
1091
1092
    /**
1093
     * Verify if the argument given is not an integer within the specified range.
1094
     * will return default instead
1095
     *
1096
     * @param  int $test    the input to test
1097
     * @param  int $min     the minimum allowable value (inclusive)
1098
     * @param  int $max     the maximum allowable value (inclusive)
1099
     * @param  int $default the default value
1100
     * @return int
1101
     */
1102
    protected static function validateInteger($test, $min, $max, $default)
1103
    {
1104
        if (!is_integer($test) || $test < $min || $test > $max) {
1105
            return $default;
1106
        }
1107
        return $test;
1108
    }
1109
1110
    /**
1111
     * Verify if the argument given can't be cast to a string.
1112
     *
1113
     * @param  string $test    the input to test
1114
     * @param  string $default the default value
1115
     * @return string
1116
     */
1117
    protected static function validateString($test, $default)
1118
    {
1119
        if (is_object($test) && !method_exists($test, '__toString')) {
1120
            return $default;
1121
        }
1122
        return $test;
1123
    }
1124
    
1125
    /**
1126
     * Translate the text from UTF-8 for the specified codepage
1127
     * this translation uses "iconv" and admits texts ONLY in UTF-8.
1128
     *
1129
     * @param  string $text
1130
     * @return string
1131
     */
1132
    protected function translate($text = '')
1133
    {
1134
        $indCode = $this->defaultCodePage();
1135
        if (!empty($indCode)) {
1136
            $codep = $this->aCodePage[$indCode];
1137
            if (!empty($codep)) {
1138
                $text = iconv('UTF-8', $codep['conv'], $text);
1139
            }
1140
        }
1141
        return $text;
1142
    }
1143
}
1144