Issues (61)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

src/Printers/Bematech.php (17 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Posprint\Printers;
4
5
/**
6
 * Bematech class for POS printer
7
 * Model: MP 4200TH
8
 *
9
 * @category   NFePHP
10
 * @package    Posprint
11
 * @copyright  Copyright (c) 2016
12
 * @license    http://www.gnu.org/licenses/lesser.html LGPL v3
13
 * @author     Roberto L. Machado <linux.rlm at gmail dot com>
14
 * @link       http://github.com/nfephp-org/posprint for the canonical source repository
15
 */
16
17
use Posprint\Printers\DefaultPrinter;
18
use Posprint\Printers\PrinterInterface;
19
use Posprint\Graphics\Graphics;
20
use InvalidArgumentException;
21
use RuntimeException;
22
23
class Bematech extends DefaultPrinter implements PrinterInterface
24
{
25
    
26
    /**
27
     * List all available code pages.
28
     * @var array
29
     */
30
    protected $aCodePage = array(
31
        'CP437' => array('conv' => '437', 'table' => '3', 'desc' => 'PC437: USA, Standard Europe'),
32
        'CP850' => array('conv' => '850', 'table' => '2', 'desc' => 'PC850: Multilingual'),
33
        'CP858' => array('conv' => '858', 'table' => '5', 'desc' => 'PC858: Multilingual'),
34
        'CP860' => array('conv' => '860', 'table' => '4', 'desc' => 'PC860: Portuguese'),
35
        'CP864' => array('conv' => '864', 'table' => '7', 'desc' => 'PC864: Arabic'),
36
        'CP866' => array('conv' => '866', 'table' => '6', 'desc' => 'PC866: Cyrillic'),
37
        'UTF8'  => array('conv' => 'UTF8', 'table' => '8', 'desc' => 'UTF-8: Unicode')
38
    );
39
    
40
    /**
41
     * List all available region pages.
42
     * @var array
43
     */
44
    protected $aRegion = array(
45
        'LATIN'
46
    );
47
    
48
    /**
49
     * Seleted printer mode.
50
     * @var string
51
     */
52
    protected $printerMode = 'ESCBEMA';
53
    
54
    /**
55
     * List all avaiable fonts
56
     * @var array
57
     */
58
    protected $aFont = array(0 => 'C', 1 => 'D');
59
    
60
    /**
61
     * Selected internal font.
62
     * @var string
63
     */
64
    protected $font = 'C';
65
    
66
    /**
67
     * Seleted code page
68
     * Defined in printer class.
69
     * @var string
70
     */
71
    protected $codepage = 'CP850';
72
    
73
    /**
74
     * Acceptable barcodes list
75
     * @var array
76
     */
77
    protected $barcode1Dlist = [
78
        'UPC_A' => 65,
79
        'UPC_E' => 66,
80
        'EAN13' => 67,
81
        'EAN8' => 68,
82
        'CODE39' => 69,
83
        'I25' => 70,
84
        'CODABAR' => 71,
85
        'CODE93' => 72,
86
        'CODE128' => 73,
87
        'ISBN' => null,
88
        'MSI' => null
89
    ];
90
    
91
    /**
92
     * List of supported models
93
     * @var array
94
     */
95
    protected $modelList = [
96
        '4200TH'
97
    ];
98
    
99
    /**
100
     * Selected model
101
     * @var string
102
     */
103
    protected $printerModel = '4200TH';
104
105
    //public function __construct(); vide DefaultPrinter
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
106
    //public function defaultCodePage(); vide DefaultPrinter
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
107
    //public function defaultRegionPage(); vide DefaultPrinter
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
108
    //public function defaultFont(); vide DefaultPrinter
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
109
    //public function defaultModel(); vide DefaultPrinter
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
110
    //public function initialize(); vide DefaultPrinter
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
111
    
112
    /**
113
     * Select printer mode
114
     * @param string $mode
115
     */
116
    public function setPrintMode($mode = 'ESCBEMA')
117
    {
118
        if ($mode != $this->printerMode) {
119
            switch ($mode) {
120
                case 'ESCBEMA':
121
                    $this->printerMode = 'ESCBEMA';
122
                    break;
123
                default:
124
                    $this->printerMode = 'ESCPOS';
125
            }
126
        }
127
        $nmod = 0;
128
        if ($this->printerMode == 'ESCPOS') {
129
            $nmod = 1;
130
        }
131
        $this->buffer->write(self::GS . chr(249) . chr(53) . $nmod);
132
    }
133
    
134
    /**
135
     * Set a codepage table in printer.
136
     *
137
     * @param string $codepage
138
     */
139
    public function setCodePage($codepage = null)
140
    {
141
        if ($this->printerMode == 'ESCPOS') {
142
            parent::setCodePage($codepage);
143
            return;
144
        }
145
        $codepage = $this->defaultCodePage($codepage);
0 ignored issues
show
$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...
146
        $this->buffer->write(self::GS . chr(249) . chr(55) . chr($this->charsetTableNum));
147
    }
148
    
149
    /**
150
     * Set a region page.
151
     * The numeric key of array $this->aRegion is the command parameter.
152
     *
153
     * @param string $region
154
     */
155
    public function setRegionPage($region = null)
156
    {
157
        //not used for this printer
158
    }
159
    
160
    /**
161
     * Set a printer font
162
     * If send a valid font name will set the printer otherelse a default font is selected
163
     * @param string $font
164
     */
165
    public function setFont($font = null)
166
    {
167
        if ($this->printerMode == 'ESCPOS') {
168
            parent::setFont($this->codepage);
169
        }
170
    }
171
172
    /**
173
     * Set emphasys mode on or off.
174
     */
175
    public function setBold()
176
    {
177
        if ($this->printerMode == 'ESCPOS') {
178
            parent::setBold();
179
            return;
180
        }
181
        $this->boldMode = ! $this->boldMode;
182
        if ($this->boldMode) {
183
            $this->buffer->write(self::ESC . 'E');
184
        } else {
185
            $this->buffer->write(self::ESC . 'F');
186
        }
187
    }
188
189
    /**
190
     * Set Italic mode
191
     */
192
    public function setItalic()
193
    {
194
        $this->italicMode = ! $this->italicMode;
195
        if ($this->printerMode == 'ESCPOS') {
196
            return;
197
        }
198
        if ($this->italicMode) {
199
            $this->buffer->write(self::ESC . '4');
200
        } else {
201
            $this->buffer->write(self::ESC . '5');
202
        }
203
    }
204
205
    //public function setUnderlined(); vide DefaultPrinter
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
206
207
    /**
208
     * Set or unset condensed mode.
209
     */
210
    public function setCondensed()
211
    {
212
        if ($this->printerMode == 'ESCPOS') {
213
            return;
214
        }
215
        $this->condensedMode = ! $this->condensedMode;
216
        if ($this->condensedMode) {
217
            $this->buffer->write(self::SI);
218
        } else {
219
            $this->buffer->write(self::DC2);
220
        }
221
    }
222
    
223
    /**
224
     * Set or unset expanded mode.
225
     *
226
     * @param integer $size not used
227
     */
228
    public function setExpanded($size = null)
229
    {
230
        $this->expandedMode = ! $this->expandedMode;
231
        if ($this->printerMode == 'ESCPOS') {
232
            return;
233
        }
234
        $n = 0;
235
        if ($this->expandedMode) {
236
            $n = 1;
237
        }
238
        $this->buffer->write(self::ESC . 'W' . chr($n));
239
    }
240
    
241
    //public function setAlign(); vide DefaultPrinter
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
242
    
243
    /**
244
     * Turns white/black reverse print On or Off for characters.
245
     */
246
    public function setReverseColors()
247
    {
248
        if ($this->printerMode == 'ESCPOS') {
249
            parent::setReverseColors();
250
        }
251
    }
252
    
253
    /**
254
     * Set rotate 90 degrees.
255
     */
256
    public function setRotate90()
257
    {
258
        if ($this->printerMode == 'ESCPOS') {
259
            parent::setRotate90();
260
        }
261
    }
262
    
263
    /**
264
     * Set horizontal and vertical motion units
265
     * $horizontal => character spacing 1/x"
266
     * $vertical => line spacing 1/y".
267
     */
268
    public function setSpacing($horizontal = 30, $vertical = 30)
269
    {
270
        //not used for this printer
271
    }
272
    
273
    /**
274
     * Set right-side character spacing
275
     * 0 ≤ n ≤ 255 => 1/x".
276
     *
277
     * @param int $value
278
     */
279
    public function setCharSpacing($value = 3)
280
    {
281
        //not used for this printer
282
    }
283
    
284
    //public function setParagraph(); vide DefaultPrinter
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
285
    //public function text(); vide default
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
286
287
    /**
288
     * Prints data and feeds paper n lines
289
     * ESC d n Prints data and feeds paper n lines.
290
     * @param int|null $lines
291
     */
292
    public function lineFeed($lines = 1)
293
    {
294
        if ($this->printerMode == 'ESCPOS') {
295
            parent::lineFeed($lines);
296
            return;
297
        }
298
        $lines = self::validateInteger($lines, 0, 255, 1);
299
        for ($lin = 1; $lin <= $lines; $lin++) {
300
            $this->buffer->write(self::LF);
301
        }
302
    }
303
    
304
    //public function dotFeed(); vide default
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% 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...
305
306
    /**
307
     * Put a image
308
     * GS v0 m xL xH yL yH d1 ... dk
309
     *
310
     * @param string $filename
311
     * @param integer $width
312
     * @param integer $height
313
     * @param integer $size resolution relation
314
     * @throws RuntimeException
315
     */
316
    public function putImage($filename = '', $width = null, $height = null, $size = 0)
317
    {
318
        try {
319
            $img = new Graphics($filename, $width, $height);
320
        } catch (RuntimeException $e) {
321
            throw new RuntimeException($e->getMessage());
322
        } catch (InvalidArgumentException $e) {
323
            throw new RuntimeException($e->getMessage());
324
        }
325
        $size = self::validateInteger($size, 0, 3, 0);
326
        //get xL xH yL yH
327
        $imgHeader = self::dataHeader(array($img->getWidth(), $img->getHeight()), true);
328
        //send graphics command to printer
329
        $this->buffer->write(self::GS.'v0'.chr($size).$imgHeader.$img->getRasterImage());
330
    }
331
332
    /**
333
     * Generate a pulse, for opening a cash drawer if one is connected.
334
     *
335
     *
336
     * @param int $pin    0 or 1, for pin 2 or pin 5 kick-out connector respectively.
337
     * @param int $on_ms  pulse ON time, in milliseconds.
338
     * @param int $off_ms pulse OFF time, in milliseconds.
339
     */
340
    public function pulse($pin = 0, $on_ms = 120, $off_ms = 240)
341
    {
342
        if ($this->printerMode == 'ESCPOS') {
343
            parent::pulse($pin, $on_ms, $off_ms);
344
            return;
345
        }
346
        $on_ms = self::validateInteger($on_ms, 50, 250, 50);
347
        if ($pin == 0 || $pin == 1) {
348
            $this->buffer->write(self::ESC.'v'. chr($on_ms));
349
        } else {
350
            $this->buffer->write(self::ESC. chr(128) . chr($on_ms));
351
        }
352
    }
353
354
    /**
355
     * Cut the paper.
356
     *
357
     * @param int $mode  FULL or PARTIAL. If not specified, FULL will be used.
358
     * @param int $lines Number of lines to feed after cut
359
     */
360
    public function cut($mode = 'PARTIAL', $lines = 3)
361
    {
362
        if ($this->printerMode == 'ESCPOS') {
363
            parent::cut($mode, $lines);
364
        }
365
        $lines = self::validateInteger($lines, 1, 10, 3);
366
        if ($mode == 'FULL') {
367
            $this->buffer->write(self::ESC.'w');
368
        } else {
369
            $this->buffer->write(self::ESC.'m');
370
        }
371
        $this->lineFeed($lines);
372
    }
373
374
    /**
375
     * Implements barcodes 1D
376
     * @param string $type Default CODE128
377
     * @param int $height
378
     * @param int $lineWidth
379
     * @param string $txtPosition
380
     * @param string $txtFont
381
     * @param string $data
382
     */
383
    public function barcode(
384
        $data = '123456',
385
        $type = 'CODE128',
386
        $height = 162,
387
        $lineWidth = 2,
388
        $txtPosition = 'none',
389
        $txtFont = ''
390
    ) {
391
        if ($this->printerMode == 'ESCPOS') {
392
            parent::barcode($data, $type, $height, $lineWidth, $txtPosition, $txtFont);
393
            return;
394
        }
395
        if (! $data = Barcodes\Barcode1DAnalysis::validate($data, $type)) {
396
            throw new \InvalidArgumentException('Data or barcode type is incorrect.');
397
        }
398
        if (! array_key_exists($type, $this->barcode1Dlist)) {
399
            throw new \InvalidArgumentException('This barcode type is not listed.');
400
        }
401
        $n = strlen($data);
402
        $id = $this->barcode1Dlist[$type];
0 ignored issues
show
$id 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...
403
        $height = self::validateInteger($height, 50, 200, 50);
0 ignored issues
show
$height 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...
404
        $lineWidth = self::validateInteger($lineWidth, 2, 5, 2);
0 ignored issues
show
$lineWidth 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...
405
        $n4 = 0;
0 ignored issues
show
$n4 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...
406
        if ($txtPosition != 'none') {
407
            $n4 = 1;
0 ignored issues
show
$n4 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...
408
        }
409
        switch ($type) {
410
            case 'UPC_A':
411
                $this->buffer->write(self::GS . 'kA' .self::VT . $data);
412
                break;
413
            case 'UPC_E':
414
                $this->buffer->write(self::GS . 'kB' .self::ACK . $data);
415
                break;
416
            case 'EAN13':
417
                $this->buffer->write(self::GS . 'kC' .self::FF . $data);
418
                break;
419
            case 'EAN8':
420
                $this->buffer->write(self::GS . 'kD' .self::BEL . $data);
421
                break;
422
            case 'CODE39':
423
                $this->buffer->write(self::GS . 'kE' . chr($n) . $data);
424
                break;
425
            case 'I25':
426
                $this->buffer->write(self::GS . 'kF' . chr($n) . $data);
427
                break;
428
            case 'CODABAR':
429
                $this->buffer->write(self::GS . 'kG' . chr($n) . $data);
430
                break;
431
            case 'CODE93':
432
                $this->buffer->write(self::GS . 'kH' . chr($n) . $data);
433
                break;
434
            case 'CODE128':
435
                $this->buffer->write(self::GS . 'kI' . chr($n) . $data);
436
                break;
437
            case 'ISBN':
438
                $this->buffer->write(self::GS . 'k' . self::NAK . $data . self::NUL);
439
                break;
440
            case 'MSI':
441
                $this->buffer->write(self::GS . 'k' . self::SYN . $data . self::NUL);
442
                break;
443
        }
444
    }
445
    
446
    /**
447
     * Print PDF 417 2D barcode
448
     * @param string $data
449
     * @param integer $ecc
450
     * @param integer $pheight
451
     * @param integer $pwidth
452
     * @param integer $colunms
453
     * @return boolean
454
     */
455
    public function barcodePDF417($data = '', $ecc = 5, $pheight = 2, $pwidth = 2, $colunms = 3)
456
    {
457
        if (empty($data)) {
458
            return false;
459
        }
460
        if ($this->printerMode == 'ESCPOS') {
461
            parent::barcodePDF417($data, $ecc, $pheight, $pwidth, $colunms);
462
        }
463
        $ecc = self::validateInteger($ecc, 0, 8, 5);
464
        $pheight = self::validateInteger($pheight, 1, 8, 2);
465
        $pwidth = self::validateInteger($pwidth, 1, 4, 2);
466
        $length = strlen($data);
467
        $n6 = intval($length / 256);
468
        $n5 = ($length % 256);
469
        $this->buffer->write(
470
            self::GS
471
            . 'k'
472
            . chr(128)
473
            . chr($ecc)
474
            . chr($pheight)
475
            . chr($pwidth)
476
            . chr(0)
477
            . chr($n5)
478
            . chr($n6)
479
            . $data
480
        );
481
    }
482
483
    
484
    /**
485
     * Imprime o QR Code
486
     *
487
     * @param string $data   Dados a serem inseridos no QRCode
488
     * @param string $level  Nivel de correção L,M,Q ou H
489
     * @param int    $modelo modelo de QRCode 0 QRCode ou 1 microQR
490
     * @param int    $wmod   largura da barra 3 ~ 16
491
     */
492
    public function barcodeQRCode($data = '', $level = 'M', $modelo = 0, $wmod = 4)
493
    {
494
        $aModels = array();
495
        //essa matriz especifica o numero máximo de caracteres alfanumericos que o
496
        //modelo de QRCode suporta dependendo no nivel de correção.
497
        //Cada matriz representa um nivel de correção e cada uma das 40 posições nessas
498
        //matrizes indicam o numero do modelo do QRCode e o numero máximo de caracteres
499
        //alfamunéricos suportados
500
        //Quanto maior o nivel de correção menor é a quantidade de caracteres suportada
501
        $aModels[0]=[25,47,77,114,154,195,224,279,335,395,468,535,619,667,
502
            758,854,938,1046,1153,1249,1352,1460,1588,1704,1853,1990,2132,
503
            2223,2369,2520,2677,2840,3009,3183,3351,3537,3729,3927,4087,4296];
504
        $aModels[1]=[20,38,61,90,122,154,178,221,262,311,366,419,483,528,600,
505
            656,734,816,909,970,1035,1134,1248,1326,1451,1542,1637,1732,1839,
506
            1994,2113,2238,2369,2506,2632,2780,2894,3054,3220,3391];
507
        $aModels[2]=[16,29,47,67,87,108,125,157,189,221,259,296,352,376,426,
508
            470,531,574,644,702,742,823,890,963,1041,1094,1172,1263,1322,1429,
509
            1499,1618,1700,1787,1867,1966,2071,2181,2298,2420];
510
        $aModels[3]=[10,20,35,50,64,84,93,122,143,174,200,227,259,283,321,365,
511
            408,452,493,557,587,640,672,744,779,864,910,958,1016,1080,1150,1226,
512
            1307,1394,1431,1530,1591,1658,1774,1852];
513
        //n1 Error correction level (data restoration)
514
        switch ($level) {
515
            case 'L':
516
                $n1 = 0;
517
                break;
518
            case "M":
519
                $n1 = 1;
520
                break;
521
            case "Q":
522
                $n1 = 2;
523
                break;
524
            case "H":
525
                $n1 = 3;
526
                break;
527
            default:
528
                $n1 = 0;
529
        }
530
        if ($modelo != 0 && $modelo != 1) {
531
            $modelo = 0;
532
        }
533
        //se for mucroQR sua capacidade é bem reduzida
534
        if ($modelo == 1) {
535
            $aModels[0] = [6,14,21];
536
            $aModels[1] = [5,11,18];
537
            $aModels[2] = [0,0,13];
538
            $aModels[3] = [0,0,0];
539
        }
540
        //n2 Module/cell size in pixels MSB 1 ≤ module size ≤ 127 LSB 0 QR or 1 MicroQR
541
        $n2 = $wmod << 1;//shift 1 é o mesmo que multiplicar por 2
542
        $n2 += $modelo;//seleciona QRCode ou microQR
543
        //comprimento da mensagem
544
        $length = strlen($data);
545
        //seleciona matriz de modelos aplicavel pelo nivel de correção
546
        $am = $aModels[$n1];
547
        $i = 0;
548
        $flag = false;
549
        foreach ($am as $size) {
550
            //verifica se o tamanho maximo é maior ou igual ao comprimento da mensagem
551
            if ($size >= $length) {
552
                $flag = true;
553
                break;
554
            }
555
            $i++;
556
        }
557
        if (! $flag) {
558
            throw new InvalidArgumentException(
559
                'O numero de caracteres da mensagem é maior que a capacidade do QRCode'
560
            );
561
        }
562
        //n3 Version QRCode
563
        //depende do comprimento dos dados e do nivel de correção
564
        $n3 = ($i + 1);
565
        //n4 Encoding modes
566
        //0 – Numeric only              Max. 7,089 characters
567
        //1 – Alphanumeric              Max. 4,296 characters
568
        //2 – Binary (8 bits)           Max. 2,953 bytes
569
        //3 – Kanji, full-width Kana    Max. 1,817 characters
570
        $n4 = 1;//sempre será 1 apenas caracteres alfanumericos nesse caso
571
        //n5 e n6 Indicate the number of bytes that will be coded, where total = n5 + n6 x 256,
572
        //and total must be less than 7089.
573
        $n6 = intval($length / 256);
574
        $n5 = ($length % 256);
575
        $this->buffer->write(self::GS."kQ" . chr($n1) . chr($n2) . chr($n3) . chr($n4) . chr($n5) . chr($n6) . $data);
576
    }
577
}
578