From 59b30b9cecd49d19e014a5a386b1ba3610227f58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 2 Nov 2019 21:15:48 +0100 Subject: [PATCH 01/10] wip ticket printer --- htdocs/admin/receiptprinter.php | 54 +- htdocs/core/class/dolreceiptprinter.class.php | 46 +- .../includes/mike42/escpos-php/.coveralls.yml | 4 + htdocs/includes/mike42/escpos-php/.gitignore | 4 + htdocs/includes/mike42/escpos-php/.travis.yml | 46 + .../mike42/escpos-php/CONTRIBUTING.md | 65 + .../mike42/escpos-php/CONTRIBUTORS.md | 25 + htdocs/includes/mike42/escpos-php/Escpos.php | 853 -------- htdocs/includes/mike42/escpos-php/LICENSE.md | 15 +- htdocs/includes/mike42/escpos-php/README.md | 451 ++++- .../includes/mike42/escpos-php/autoload.php | 26 + .../includes/mike42/escpos-php/composer.json | 70 +- .../includes/mike42/escpos-php/composer.lock | 615 ++++-- htdocs/includes/mike42/escpos-php/doc/FAQ.md | 142 ++ .../includes/mike42/escpos-php/doc/Makefile | 19 +- .../doc/{escpos.conf => escpos.doxyfile} | 18 +- .../mike42/escpos-php/example/README.md | 2 +- .../mike42/escpos-php/example/barcode.php | 366 ++-- .../mike42/escpos-php/example/bit-image.php | 50 +- .../character-encodings-with-images.php | 88 +- .../example/character-encodings.php | 74 +- .../escpos-php/example/character-tables.php | 94 +- .../escpos-php/example/customer-display.php | 51 + .../mike42/escpos-php/example/demo.php | 154 +- .../mike42/escpos-php/example/graphics.php | 52 +- .../escpos-php/example/interface/cups.php | 19 + .../escpos-php/example/interface/ethernet.php | 28 +- .../example/interface/linux-usb.php | 32 +- .../escpos-php/example/interface/smb.php | 69 +- .../example/interface/windows-lpt.php | 37 +- .../example/interface/windows-usb.php | 40 +- .../example/margins-and-spacing.php | 48 + .../mike42/escpos-php/example/pdf417-code.php | 95 + .../escpos-php/example/print-from-html.php | 105 +- .../escpos-php/example/print-from-pdf.php | 55 +- .../mike42/escpos-php/example/qr-code.php | 87 +- .../escpos-php/example/rawbt-receipt.html | 76 + .../escpos-php/example/rawbt-receipt.php | 145 ++ .../escpos-php/example/receipt-with-logo.php | 82 +- .../character-encoding-test-strings.inc | 44 +- .../example/resources/document.html | 40 + .../escpos-php/example/resources/document.z | Bin 20320 -> 18900 bytes .../example/resources/rawbtlogo.png | Bin 0 -> 1358 bytes .../escpos-php/example/resources/tulips.png | Bin 0 -> 379443 bytes .../example/specific/123-code128-barcode.php | 21 + .../example/specific/141-custom-command.php | 55 + .../example/specific/148-data-uri.php | 35 + .../example/specific/235-get-data.php | 28 + .../specific/29-latvian-star-tup592.php | 14 +- .../32-german-tm-t20-ii-custom-command.php | 15 +- .../specific/33-spanish-seypos-prp-300.php | 11 +- .../example/specific/37-chinese.php | 24 + .../example/specific/39-currency-symbols.php | 56 +- .../specific/44-pound-symbol-star-tsp650.php | 10 +- .../example/specific/50-P-822D-greek.php | 9 +- .../example/specific/54-gfx-sidebyside.php | 72 +- .../specific/6-arabic-epos-tep-220m.php | 55 +- .../example/specific/62-greek-symbol-swap.php | 15 + .../example/specific/68-redblack.php | 21 + .../example/specific/97-dithering.php | 28 + .../mike42/escpos-php/example/text-size.php | 39 +- htdocs/includes/mike42/escpos-php/phpunit.xml | 21 + .../src/AbstractCapabilityProfile.php | 61 - .../mike42/escpos-php/src/CodePage.php | 181 -- .../src/DefaultCapabilityProfile.php | 103 - .../escpos-php/src/DummyPrintConnector.php | 78 - .../src/EposTepCapabilityProfile.php | 4 - .../mike42/escpos-php/src/EscposImage.php | 405 ---- .../escpos-php/src/EscposPrintBuffer.php | 304 --- .../escpos-php/src/FilePrintConnector.php | 80 - .../escpos-php/src/ImagePrintBuffer.php | 99 - .../src/Mike42/Escpos/CapabilityProfile.php | 348 ++++ .../DefaultCapabilityProfile.php | 22 + .../EposTepCapabilityProfile.php | 22 + .../P822DCapabilityProfile.php | 22 + .../SimpleCapabilityProfile.php | 22 + .../StarCapabilityProfile.php | 22 + .../escpos-php/src/Mike42/Escpos/CodePage.php | 181 ++ .../Escpos/Devices/AuresCustomerDisplay.php | 150 ++ .../src/Mike42/Escpos/EscposImage.php | 460 +++++ .../src/Mike42/Escpos/GdEscposImage.php | 86 + .../src/Mike42/Escpos/ImagickEscposImage.php | 273 +++ .../src/Mike42/Escpos/NativeEscposImage.php | 24 + .../Escpos/PrintBuffers/EscposPrintBuffer.php | 300 +++ .../Escpos/PrintBuffers/ImagePrintBuffer.php | 135 ++ .../Escpos/PrintBuffers/PrintBuffer.php | 63 + .../cache/Characters-OCD-300.ser.z | Bin 0 -> 6934 bytes .../PrintBuffers/cache/Characters-P822D.ser.z | Bin 0 -> 12251 bytes .../cache/Characters-POS-5890.ser.z | Bin 0 -> 12537 bytes .../cache/Characters-SP2000.ser.z | Bin 0 -> 9267 bytes .../cache/Characters-TEP-200M.ser.z | Bin 0 -> 13740 bytes .../cache/Characters-default.ser.z | Bin 0 -> 13740 bytes .../cache/Characters-simple.ser.z | Bin 0 -> 1099 bytes .../PrintConnectors/ApiPrintConnector.php | 102 + .../PrintConnectors/CupsPrintConnector.php | 182 ++ .../PrintConnectors/DummyPrintConnector.php | 78 + .../PrintConnectors/FilePrintConnector.php | 82 + .../PrintConnectors/NetworkPrintConnector.php | 41 + .../Escpos/PrintConnectors/PrintConnector.php | 47 + .../PrintConnectors/RawbtPrintConnector.php | 81 + .../PrintConnectors/UriPrintConnector.php | 44 + .../PrintConnectors/WindowsPrintConnector.php | 391 ++++ .../escpos-php/src/Mike42/Escpos/Printer.php | 1217 ++++++++++++ .../Mike42/Escpos/resources/capabilities.json | 1760 +++++++++++++++++ .../escpos-php/src/NetworkPrintConnector.php | 39 - .../escpos-php/src/P822DCapabilityProfile.php | 90 - .../mike42/escpos-php/src/PrintBuffer.php | 75 - .../mike42/escpos-php/src/PrintConnector.php | 56 - .../src/SimpleCapabilityProfile.php | 17 - .../escpos-php/src/StarCapabilityProfile.php | 82 - .../escpos-php/src/WindowsPrintConnector.php | 356 ---- ...Characters-DefaultCapabilityProfile.ser.gz | Bin 12928 -> 0 bytes .../Characters-SimpleCapabilityProfile.ser.gz | Bin 1116 -> 0 bytes .../Characters-StarCapabilityProfile.ser.gz | Bin 9416 -> 0 bytes .../mike42/escpos-php/test/bootstrap.php | 47 +- .../test/integration/ExampleTest.php | 303 +-- .../integration/resources/output/barcode.bin | Bin 2342 -> 2667 bytes .../resources/output/character-encodings.bin | Bin 1780 -> 1930 bytes .../resources/output/character-tables.bin | Bin 8174 -> 7969 bytes .../resources/output/interface.bin | 2 - .../resources/output/margins-and-spacing.bin | Bin 0 -> 339 bytes .../resources/output/pdf417-code.bin | Bin 0 -> 2366 bytes .../resources/output/print-from-pdf.bin.z | Bin 17081 -> 0 bytes .../mike42/escpos-php/test/phpunit.xml | 16 - .../unit/AbstractCapabilityProfileTest.php | 69 - .../test/unit/AuresCustomerDisplayTest.php | 76 + .../test/unit/CapabilityProfileTest.php | 59 + .../escpos-php/test/unit/CodePageTest.php | 63 + .../test/unit/CupsPrintConnectorTest.php | 36 + .../escpos-php/test/unit/EscposImageTest.php | 245 +-- .../test/unit/EscposPrintBufferTest.php | 288 +-- .../escpos-php/test/unit/EscposTest.php | 1760 ++++++++++------- .../test/unit/FilePrintConnectorTest.php | 26 + .../test/unit/GdEscposImageTest.php | 101 + .../test/unit/ImagickEscposImageTest.php | 142 ++ .../test/unit/LegacyCapabilityProfileTest.php | 79 + .../test/unit/UriPrintConnectorTest.php | 59 + .../test/unit/WindowsPrintConnectorTest.php | 542 ++--- .../test/unit/resources/black_white_tall.png | Bin 0 -> 162 bytes .../escpos-php/test/unit/resources/demo.php | 21 +- 140 files changed, 11495 insertions(+), 5539 deletions(-) create mode 100644 htdocs/includes/mike42/escpos-php/.coveralls.yml create mode 100644 htdocs/includes/mike42/escpos-php/.travis.yml create mode 100644 htdocs/includes/mike42/escpos-php/CONTRIBUTING.md create mode 100644 htdocs/includes/mike42/escpos-php/CONTRIBUTORS.md delete mode 100644 htdocs/includes/mike42/escpos-php/Escpos.php create mode 100644 htdocs/includes/mike42/escpos-php/autoload.php create mode 100644 htdocs/includes/mike42/escpos-php/doc/FAQ.md rename htdocs/includes/mike42/escpos-php/doc/{escpos.conf => escpos.doxyfile} (99%) create mode 100644 htdocs/includes/mike42/escpos-php/example/customer-display.php create mode 100644 htdocs/includes/mike42/escpos-php/example/interface/cups.php create mode 100644 htdocs/includes/mike42/escpos-php/example/margins-and-spacing.php create mode 100644 htdocs/includes/mike42/escpos-php/example/pdf417-code.php create mode 100644 htdocs/includes/mike42/escpos-php/example/rawbt-receipt.html create mode 100644 htdocs/includes/mike42/escpos-php/example/rawbt-receipt.php create mode 100644 htdocs/includes/mike42/escpos-php/example/resources/document.html create mode 100644 htdocs/includes/mike42/escpos-php/example/resources/rawbtlogo.png create mode 100644 htdocs/includes/mike42/escpos-php/example/resources/tulips.png create mode 100644 htdocs/includes/mike42/escpos-php/example/specific/123-code128-barcode.php create mode 100644 htdocs/includes/mike42/escpos-php/example/specific/141-custom-command.php create mode 100644 htdocs/includes/mike42/escpos-php/example/specific/148-data-uri.php create mode 100644 htdocs/includes/mike42/escpos-php/example/specific/235-get-data.php create mode 100644 htdocs/includes/mike42/escpos-php/example/specific/37-chinese.php create mode 100644 htdocs/includes/mike42/escpos-php/example/specific/62-greek-symbol-swap.php create mode 100644 htdocs/includes/mike42/escpos-php/example/specific/68-redblack.php create mode 100644 htdocs/includes/mike42/escpos-php/example/specific/97-dithering.php create mode 100644 htdocs/includes/mike42/escpos-php/phpunit.xml delete mode 100644 htdocs/includes/mike42/escpos-php/src/AbstractCapabilityProfile.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/CodePage.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/DefaultCapabilityProfile.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/DummyPrintConnector.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/EposTepCapabilityProfile.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/EscposImage.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/EscposPrintBuffer.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/FilePrintConnector.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/ImagePrintBuffer.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfile.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/DefaultCapabilityProfile.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/EposTepCapabilityProfile.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/P822DCapabilityProfile.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/SimpleCapabilityProfile.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/StarCapabilityProfile.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CodePage.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Devices/AuresCustomerDisplay.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/EscposImage.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/NativeEscposImage.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/PrintBuffer.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-OCD-300.ser.z create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-P822D.ser.z create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-POS-5890.ser.z create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-SP2000.ser.z create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-TEP-200M.ser.z create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-default.ser.z create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-simple.ser.z create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/ApiPrintConnector.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/NetworkPrintConnector.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/PrintConnector.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/RawbtPrintConnector.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/UriPrintConnector.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/WindowsPrintConnector.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php create mode 100644 htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/resources/capabilities.json delete mode 100644 htdocs/includes/mike42/escpos-php/src/NetworkPrintConnector.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/P822DCapabilityProfile.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/PrintBuffer.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/PrintConnector.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/SimpleCapabilityProfile.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/StarCapabilityProfile.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/WindowsPrintConnector.php delete mode 100644 htdocs/includes/mike42/escpos-php/src/cache/Characters-DefaultCapabilityProfile.ser.gz delete mode 100644 htdocs/includes/mike42/escpos-php/src/cache/Characters-SimpleCapabilityProfile.ser.gz delete mode 100644 htdocs/includes/mike42/escpos-php/src/cache/Characters-StarCapabilityProfile.ser.gz delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/interface.bin create mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/margins-and-spacing.bin create mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/pdf417-code.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/print-from-pdf.bin.z delete mode 100644 htdocs/includes/mike42/escpos-php/test/phpunit.xml delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/AbstractCapabilityProfileTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/AuresCustomerDisplayTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/CapabilityProfileTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/CodePageTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/CupsPrintConnectorTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/FilePrintConnectorTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/GdEscposImageTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/ImagickEscposImageTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/LegacyCapabilityProfileTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/UriPrintConnectorTest.php create mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/black_white_tall.png diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index 6184bebd97f..42b0ecb9ea9 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -166,6 +166,24 @@ if ($action == 'testprinter' && $user->admin) { $action = ''; } +if ($action == 'testtemplate' && $user->admin) { + $error=0; + // if (empty($printerid)) { + // $error++; + // setEventMessages($langs->trans("PrinterIdEmpty"), null, 'errors'); + // } + + // if (! $error) { + // // test + // $ret = $printer->sendTestToPrinter($printerid); + // if ($ret == 0) { + setEventMessages($langs->trans("TestTemplateToPrinter", $printername), null); + // } else { + // setEventMessages($printer->error, $printer->errors, 'errors'); + // } + // } + $action = ''; +} if ($action == 'updatetemplate' && $user->admin) { $error=0; @@ -190,6 +208,29 @@ if ($action == 'updatetemplate' && $user->admin) { $action = ''; } +if ($action == 'addtemplate' && $user->admin) { + $error=0; + $db->begin(); + if (empty($templatename)) { + $error++; + setEventMessages($langs->trans("TemplateNameEmpty"), null, 'errors'); + } + + if (! $error) { + $result= $printer->addTemplate($templatename, $template); + if ($result > 0) $error++; + + if (! $error) { + $db->commit(); + setEventMessages($langs->trans("TemplateAdded", $templatename), null); + } else { + $db->rollback(); + dol_print_error($db); + } + } + $action = ''; +} + /* * View @@ -345,7 +386,7 @@ if ($mode == 'template' && $user->admin) { dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); print $langs->trans("ReceiptPrinterTemplateDesc")."

\n"; - print ''."\n"; + print '
'."\n"; print ''; print ''; print ''; @@ -359,8 +400,7 @@ if ($mode == 'template' && $user->admin) { setEventMessages($printer->error, $printer->errors, 'errors'); } else { $max = count($printer->listprinterstemplates); - for ($line=0; $line < $max; $line++) - { + for ($line=0; $line < $max; $line++) { print ''; if ($action=='edittemplate' && $printer->listprinterstemplates[$line]['rowid']==$templateid) { print ''; @@ -392,6 +432,14 @@ if ($mode == 'template' && $user->admin) { print '
'.$langs->trans("Name").''.$langs->trans("Template").'
'; if ($action!='edittemplate') { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print '
'; } else { print '
'; diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index ef529f39d9a..1f9ea78bf95 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2015-2019 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,13 +91,19 @@ * */ -require_once DOL_DOCUMENT_ROOT .'/includes/mike42/escpos-php/Escpos.php'; +require_once DOL_DOCUMENT_ROOT .'/includes/mike42/escpos-php/autoload.php'; +use Mike42\Escpos\PrintConnectors\FilePrintConnector; +use Mike42\Escpos\PrintConnectors\NetworkPrintConnector; +use Mike42\Escpos\PrintConnectors\WindowsPrintConnector; +use Mike42\Escpos\CapabilityProfile; +use Mike42\Escpos\Printer; +use Mike42\Escpos\EscposImage; /** * Class to manage Receipt Printers */ -class dolReceiptPrinter extends Escpos +class dolReceiptPrinter extends Printer { const CONNECTOR_DUMMY = 1; const CONNECTOR_FILE_PRINT = 2; @@ -423,6 +429,29 @@ class dolReceiptPrinter extends Escpos return $error; } + /** + * Function to add a printer template in db + * + * @param string $name Template name + * @param int $template Template + * @return int 0 if OK; >0 if KO + */ + public function addTemplate($name, $template) + { + global $conf; + $error = 0; + $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'printer_receipt_template'; + $sql.= ' (name, template, entity) VALUES ("'.$this->db->escape($name).'"'; + $sql.= ', "'.$this->db->escape($template).'", '.$conf->entity.')'; + $resql = $this->db->query($sql); + if (! $resql) { + $error++; + $this->errors[] = $this->db->lasterror; + } + return $error; + } + + /** * Function to Update a printer template in db * @@ -458,16 +487,17 @@ class dolReceiptPrinter extends Escpos { global $conf; $error = 0; - $img = new EscposImage(DOL_DOCUMENT_ROOT .'/theme/common/dolibarr_logo_bw.png'); + $img = EscposImage::load(DOL_DOCUMENT_ROOT .'/theme/common/dolibarr_logo_bw.png'); + //$this->profile = CapabilityProfile::load("TM-T88IV"); $ret = $this->initPrinter($printerid); if ($ret>0) { setEventMessages($this->error, $this->errors, 'errors'); } else { try { - $this->printer->graphics($img); + $this->printer->bitImage($img); $this->printer->text("Hello World!\n"); - $testStr = "Testing 123"; - $this->printer->qrCode($testStr); + $testStr = "1234567890"; + $this->printer->barcode($testStr); $this->printer->text("Most simple example\n"); $this->printer->feed(); $this->printer->cut(); @@ -687,7 +717,7 @@ class dolReceiptPrinter extends Escpos $this->connector = 'CONNECTOR_UNKNOWN'; break; } - $this->printer = new Escpos($this->connector); + $this->printer = new Printer($this->connector, $this->profile); } catch (Exception $e) { $this->errors[] = $e->getMessage(); $error++; diff --git a/htdocs/includes/mike42/escpos-php/.coveralls.yml b/htdocs/includes/mike42/escpos-php/.coveralls.yml new file mode 100644 index 00000000000..b33373af905 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/.coveralls.yml @@ -0,0 +1,4 @@ +service_name: travis-ci +coverage_clover: build/logs/clover.xml +json_path: build/logs/coveralls-upload.json + diff --git a/htdocs/includes/mike42/escpos-php/.gitignore b/htdocs/includes/mike42/escpos-php/.gitignore index 0e8fc4a31ee..8632f891ad4 100644 --- a/htdocs/includes/mike42/escpos-php/.gitignore +++ b/htdocs/includes/mike42/escpos-php/.gitignore @@ -10,3 +10,7 @@ doc/doxygen_sqlite3.db # composer files vendor/ + +# other build files +build/* +*.phar diff --git a/htdocs/includes/mike42/escpos-php/.travis.yml b/htdocs/includes/mike42/escpos-php/.travis.yml new file mode 100644 index 00000000000..04ffb6523b6 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/.travis.yml @@ -0,0 +1,46 @@ +--- +dist: trusty +sudo: required + +language: php + +php: + - 5.4 + - 5.5 + - 5.6 + - 7.0 + - 7.1 + - 7.2 + - nightly + - hhvm-3.21 + - hhvm-nightly + +matrix: + allow_failures: + - php: nightly + - php: hhvm-nightly + +before_install: + - sudo apt-get -qq update + - sudo apt-get install -y imagemagick ghostscript + +install: + - composer install + +before_script: + # Install 'imagick' plugin + - bash -c 'if [[ $TRAVIS_PHP_VERSION != hhvm* ]]; then printf "\n" | pecl install imagick; fi' + # Directory for coverage report + - mkdir -p build/logs/ + +script: + # Check code style + - php vendor/bin/phpcs --standard=psr2 src/ -n + # Run tests + - php vendor/bin/phpunit --coverage-clover build/logs/clover.xml + +after_success: + # Upload coverage statistics to coveralls service after test + - wget -c -nc https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar + - php coveralls.phar -v +... diff --git a/htdocs/includes/mike42/escpos-php/CONTRIBUTING.md b/htdocs/includes/mike42/escpos-php/CONTRIBUTING.md new file mode 100644 index 00000000000..326e1d093ac --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# How to contribute + +This project is open to many different types of contribution. You can help with improving the documentation and examples, sharing your insights on the issue tracker, adding fixes to the code, providing test cases, or just [writing about your hardware setup that you use](https://github.com/mike42/escpos-php/issues/new). + +## Issue tracker + +Open issues of all sorts are tracked on the [issue tracker](https://github.com/mike42/escpos-php/issues). Please check [the FAQ](https://github.com/mike42/escpos-php/blob/development/doc/FAQ.md) before you post, and practice good [bug tracker etiquette](https://bugzilla.mozilla.org/page.cgi?id=etiquette.html) to keep it running smoothly. + +Issues are [loosely categorised](https://github.com/mike42/escpos-php/labels), and will stay open while there is still something that can be resolved. + +Anybody may add to the discussion on the bug tracker. Just be sure to add new questions as separate issues, and to avoid commenting on closed issues. + +## Submitting changes + +Code changes may be submitted as a "[pull request](https://help.github.com/articles/about-pull-requests/)" at [mike42/escpos-php](https://github.com/mike42/escpos-php). The description should include some information about how the change improves the library. + +The project is MIT-licensed (see [LICENSE.md](https://github.com/mike42/escpos-php/blob/development/LICENSE.md) for details). You are not required to assign copyright in order to submit changes, but you do need to agree for your code to be distributed under this license in order for it to be accepted. + +### Documentation changes + +The official documentaton is also located in the main repository, under the [doc/](https://github.com/mike42/escpos-php/tree/development/doc) folder. + +You are welcome to post any suggested improvements as pull requests. + +### Release process + +Once a pull request is accepted, it usually appears in a release a few days later. + +Branches: + +- "development" is the most recent code, possibly containing unreleased fixes +- "master" contains the most recently released code (old versions are not maintained). + +The release process for your changes is: + +- Changes are submitted via pull request to the shared "development" branch. +- A new release is staged on the "master" branch via another pull request, and then tagged. + +## Code style + +This project uses the [PSR-2 standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) for all PHP source code. + +## Testing and CI + +The tests are executed on [Travis CI](https://travis-ci.org/mike42/escpos-php) over PHP 5.4, 5.5, 5.6, 7.0, 7.1 and 7.2, plus the latest LTS version of HHVM, 3.21. Older versions of PHP are not supported in current releases. + +For development, it's suggested that you load `imagick`, `gd` and `Xdebug` PHP exensions, and install `composer`. + +Fetch a copy of this code and load dependencies with composer: + + git clone https://github.com/mike42/escpos-php + cd escpos-php/ + composer install + +Execute unit tests via `phpunit`: + + php vendor/bin/phpunit --coverage-text + +Code style can be checked via [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer): + + php vendor/bin/phpcs --standard=psr2 src/ -n + +The developer docs are built with [doxygen](https://github.com/doxygen/doxygen). Re-build them to check for documentation warnings: + + make -C doc clean && make -C doc diff --git a/htdocs/includes/mike42/escpos-php/CONTRIBUTORS.md b/htdocs/includes/mike42/escpos-php/CONTRIBUTORS.md new file mode 100644 index 00000000000..12f3acf95a5 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/CONTRIBUTORS.md @@ -0,0 +1,25 @@ +# escpos-php contributors + +This file contains a list of people who have made contributions of +code which appear in the public repository of escpos-php. + +Main repository: [mike42/escpos-php](https://github.com/mike42/escpos-php) ([online contributor list](https://github.com/mike42/escpos-php/graphs/contributors)) + +- [Michael Billington](https://github.com/mike42) +- [Alif Maulana El Fattah Nataly](https://github.com/alif25r) +- [Mareks Sudniks](https://github.com/marech) +- [matiasgaston](https://github.com/matiasgaston) +- [Mike Stivala](https://github.com/brndwgn) +- [Nicholas Long](https://github.com/longsview) +- [Evandro Araújo](https://github.com/evsar3) + +Via fork: [wdoyle/EpsonESCPOS-PHP](https://github.com/wdoyle/EpsonESCPOS-PHP): + +- [Warren Doyle](https://github.com/wdoyle) + +Via fork: [ronisaha/php-esc-pos](https://github.com/ronisaha/php-esc-pos): + +- [Roni Saha](https://github.com/ronisaha) +- [Gergely Radics](https://github.com/Gerifield) +- [vharo](https://github.com/vharo) + diff --git a/htdocs/includes/mike42/escpos-php/Escpos.php b/htdocs/includes/mike42/escpos-php/Escpos.php deleted file mode 100644 index b8568260738..00000000000 --- a/htdocs/includes/mike42/escpos-php/Escpos.php +++ /dev/null @@ -1,853 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * This class generates ESC/POS printer control commands for compatible printers. - * See README.md for a summary of compatible printers and supported commands, and - * basic usage. - * - * See example/demo.php for a detailed print-out demonstrating the range of commands - * implemented in this project. - * - * Note that some functions have not been implemented: - * - Set paper sensors - * - Select print colour - * - * Please direct feature requests, bug reports and contributions to escpos-php - * on Github: - * - https://github.com/mike42/escpos-php - */ -require_once(dirname(__FILE__) . "/src/EscposImage.php"); -require_once(dirname(__FILE__) . "/src/PrintBuffer.php"); -require_once(dirname(__FILE__) . "/src/EscposPrintBuffer.php"); -require_once(dirname(__FILE__) . "/src/PrintConnector.php"); -require_once(dirname(__FILE__) . "/src/WindowsPrintConnector.php"); -require_once(dirname(__FILE__) . "/src/FilePrintConnector.php"); -require_once(dirname(__FILE__) . "/src/NetworkPrintConnector.php"); -require_once(dirname(__FILE__) . "/src/AbstractCapabilityProfile.php"); -require_once(dirname(__FILE__) . "/src/DefaultCapabilityProfile.php"); -require_once(dirname(__FILE__) . "/src/SimpleCapabilityProfile.php"); -require_once(dirname(__FILE__) . "/src/EposTepCapabilityProfile.php"); -require_once(dirname(__FILE__) . "/src/StarCapabilityProfile.php"); -require_once(dirname(__FILE__) . "/src/P822DCapabilityProfile.php"); -require_once(dirname(__FILE__) . "/src/CodePage.php"); -require_once(dirname(__FILE__) . "/src/ImagePrintBuffer.php"); - -class Escpos { - /* ASCII codes */ - const NUL = "\x00"; - const LF = "\x0a"; - const ESC = "\x1b"; - const FS = "\x1c"; - const FF = "\x0c"; - const GS = "\x1d"; - const DLE = "\x10"; - const EOT = "\x04"; - - /* Barcode types */ - const BARCODE_UPCA = 65; - const BARCODE_UPCE = 66; - const BARCODE_JAN13 = 67; - const BARCODE_JAN8 = 68; - const BARCODE_CODE39 = 69; - const BARCODE_ITF = 70; - const BARCODE_CODABAR = 71; - const BARCODE_CODE93 = 72; - const BARCODE_CODE128 = 73; - - /* Barcode HRI (human-readable interpretation) text position */ - const BARCODE_TEXT_NONE = 0; - const BARCODE_TEXT_ABOVE = 1; - const BARCODE_TEXT_BELOW = 2; - - /* Cut types */ - const CUT_FULL = 65; - const CUT_PARTIAL = 66; - - /* Fonts */ - const FONT_A = 0; - const FONT_B = 1; - const FONT_C = 2; - - /* Image sizing options */ - const IMG_DEFAULT = 0; - const IMG_DOUBLE_WIDTH = 1; - const IMG_DOUBLE_HEIGHT = 2; - - /* Justifications */ - const JUSTIFY_LEFT = 0; - const JUSTIFY_CENTER = 1; - const JUSTIFY_RIGHT = 2; - - /* Print mode constants */ - const MODE_FONT_A = 0; - const MODE_FONT_B = 1; - const MODE_EMPHASIZED = 8; - const MODE_DOUBLE_HEIGHT = 16; - const MODE_DOUBLE_WIDTH = 32; - const MODE_UNDERLINE = 128; - - /* QR code error correction levels */ - const QR_ECLEVEL_L = 0; - const QR_ECLEVEL_M = 1; - const QR_ECLEVEL_Q = 2; - const QR_ECLEVEL_H = 3; - - /* QR code models */ - const QR_MODEL_1 = 1; - const QR_MODEL_2 = 2; - const QR_MICRO = 3; - - /* Printer statuses */ - const STATUS_PRINTER = 1; - const STATUS_OFFLINE_CAUSE = 2; - const STATUS_ERROR_CAUSE = 3; - const STATUS_PAPER_ROLL = 4; - const STATUS_INK_A = 7; - const STATUS_INK_B = 6; - const STATUS_PEELER = 8; - - /* Underline */ - const UNDERLINE_NONE = 0; - const UNDERLINE_SINGLE = 1; - const UNDERLINE_DOUBLE = 2; - - /** - * @var PrintBuffer The printer's output buffer. - */ - private $buffer; - - /** - * @var PrintConnector - * @CHANGE - */ - protected $connector; - // private $connector; - - /** - * @var AbstractCapabilityProfile - */ - private $profile; - - /** - * @var int Current character code table - */ - private $characterTable; - - /** - * Construct a new print object - * - * @param PrintConnector $connector The PrintConnector to send data to. If not set, output is sent to standard output. - * @param AbstractCapabilityProfile $profile Supported features of this printer. If not set, the DefaultCapabilityProfile will be used, which is suitable for Epson printers. - * @throws InvalidArgumentException - */ - function __construct(PrintConnector $connector = null, AbstractCapabilityProfile $profile = null) { - if(is_null($connector)) { - if(php_sapi_name() == 'cli') { - $connector = new FilePrintConnector("php://stdout"); - } else { - throw new InvalidArgumentException("Argument passed to Escpos::__construct() must implement interface PrintConnector, null given."); - } - } - /* Set connector */ - $this -> connector = $connector; - - /* Set capability profile */ - if($profile === null) { - $profile = DefaultCapabilityProfile::getInstance(); - } - $this -> profile = $profile; - /* Set buffer */ - $buffer = new EscposPrintBuffer(); - $this -> buffer = null; - $this -> setPrintBuffer($buffer); - $this -> initialize(); - } - - /** - * Print a barcode. - * - * @param string $content The information to encode. - * @param int $type The barcode standard to output. If not specified, `Escpos::BARCODE_CODE39` will be used. Note that some barcode formats only support specific lengths or sets of characters. - * @throws InvalidArgumentException Where the length or characters used in $content is invalid for the requested barcode format. - */ - function barcode($content, $type = self::BARCODE_CODE39) { - /* Validate input */ - self::validateInteger($type, 65, 73, __FUNCTION__, "Barcode type"); - $len = strlen($content); - switch($type) { - case self::BARCODE_UPCA: - self::validateInteger($len, 11, 12, __FUNCTION__, "UPCA barcode content length"); - self::validateStringRegex($content, __FUNCTION__, "/^[0-9]{11,12}$/", "UPCA barcode content"); - break; - case self::BARCODE_UPCE: - self::validateIntegerMulti($len, array(array(6, 8), array(11, 12)), __FUNCTION__, "UPCE barcode content length"); - self::validateStringRegex($content, __FUNCTION__, "/^([0-9]{6,8}|[0-9]{11,12})$/", "UPCE barcode content"); - break; - case self::BARCODE_JAN13: - self::validateInteger($len, 12, 13, __FUNCTION__, "JAN13 barcode content length"); - self::validateStringRegex($content, __FUNCTION__, "/^[0-9]{12,13}$/", "JAN13 barcode content"); - break; - case self::BARCODE_JAN8: - self::validateInteger($len, 7, 8, __FUNCTION__, "JAN8 barcode content length"); - self::validateStringRegex($content, __FUNCTION__, "/^[0-9]{7,8}$/", "JAN8 barcode content"); - break; - case self::BARCODE_CODE39: - self::validateInteger($len, 1, 255, __FUNCTION__, "CODE39 barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. - self::validateStringRegex($content, __FUNCTION__, "/^([0-9A-Z \$\%\+\-\.\/]+|\*[0-9A-Z \$\%\+\-\.\/]+\*)$/", "CODE39 barcode content"); - break; - case self::BARCODE_ITF: - self::validateInteger($len, 2, 255, __FUNCTION__, "ITF barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. - self::validateStringRegex($content, __FUNCTION__, "/^([0-9]{2})+$/", "ITF barcode content"); - break; - case self::BARCODE_CODABAR: - self::validateInteger($len, 1, 255, __FUNCTION__, "Codabar barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. - self::validateStringRegex($content, __FUNCTION__, "/^[A-Da-d][0-9\$\+\-\.\/\:]+[A-Da-d]$/", "Codabar barcode content"); - break; - case self::BARCODE_CODE93: - self::validateInteger($len, 1, 255, __FUNCTION__, "Code93 barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. - self::validateStringRegex($content, __FUNCTION__, "/^[\\x00-\\x7F]+$/", "Code93 barcode content"); - break; - case self::BARCODE_CODE128: - self::validateInteger($len, 1, 255, __FUNCTION__, "Code128 barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. - // The CODE128 encoder is quite complex, so only a very basic header-check is applied here. - self::validateStringRegex($content, __FUNCTION__, "/^\{[A-C][\\x00-\\x7F]+$/", "Code128 barcode content"); - break; - } - if(!$this -> profile -> getSupportsBarcodeB()) { - // A simpler barcode command which supports fewer codes - self::validateInteger($type, 65, 71, __FUNCTION__); - $this -> connector -> write(self::GS . "k" . chr($type - 65) . $content . self::NUL); - return; - } - // More advanced function B, used in preference - $this -> connector -> write(self::GS . "k" . chr($type) . chr(strlen($content)) . $content); - } - - /** - * Print an image, using the older "bit image" command. This creates padding on the right of the image, - * if its width is not divisible by 8. - * - * Should only be used if your printer does not support the graphics() command. - * - * @param EscposImage $img The image to print - * @param EscposImage $size Size modifier for the image. - */ - function bitImage(EscposImage $img, $size = self::IMG_DEFAULT) { - self::validateInteger($size, 0, 3, __FUNCTION__); - $header = self::dataHeader(array($img -> getWidthBytes(), $img -> getHeight()), true); - $this -> connector -> write(self::GS . "v0" . chr($size) . $header); - $this -> connector -> write($img -> toRasterFormat()); - } - - /** - * Close the underlying buffer. With some connectors, the - * job will not actually be sent to the printer until this is called. - */ - function close() { - $this -> connector -> finalize(); - } - - /** - * Cut the paper. - * - * @param int $mode Cut mode, either Escpos::CUT_FULL or Escpos::CUT_PARTIAL. If not specified, `Escpos::CUT_FULL` will be used. - * @param int $lines Number of lines to feed - */ - function cut($mode = self::CUT_FULL, $lines = 3) { - // TODO validation on cut() inputs - $this -> connector -> write(self::GS . "V" . chr($mode) . chr($lines)); - } - - /** - * Print and feed line / Print and feed n lines. - * - * @param int $lines Number of lines to feed - */ - function feed($lines = 1) { - self::validateInteger($lines, 1, 255, __FUNCTION__); - if($lines <= 1) { - $this -> connector -> write(self::LF); - } else { - $this -> connector -> write(self::ESC . "d" . chr($lines)); - } - } - - /** - * Some printers require a form feed to release the paper. On most printers, this - * command is only useful in page mode, which is not implemented in this driver. - */ - function feedForm() { - $this -> connector -> write(self::FF); - } - - /** - * Print and reverse feed n lines. - * - * @param int $lines number of lines to feed. If not specified, 1 line will be fed. - */ - function feedReverse($lines = 1) { - self::validateInteger($lines, 1, 255, __FUNCTION__); - $this -> connector -> write(self::ESC . "e" . chr($lines)); - } - - /** - * @return number - */ - function getCharacterTable() { - return $this -> characterTable; - } - - /** - * @return PrintBuffer - */ - function getPrintBuffer() { - return $this -> buffer; - } - - /** - * @return PrintConnector - */ - function getPrintConnector() { - return $this -> connector; - } - - /** - * @return AbstractCapabilityProfile - */ - function getPrinterCapabilityProfile() { - return $this -> profile; - } - - /** - * @param int $type The type of status to request - * @return stdClass Class containing requested status, or null if either no status was received, or your print connector is unable to read from the printer. - */ - function getPrinterStatus($type = self::STATUS_PRINTER) { - self::validateIntegerMulti($type, array(array(1, 4), array(6, 8)), __FUNCTION__); - // Determine which flags we are looking for - $statusFlags = array( - self::STATUS_PRINTER => array( - 4 => "pulseHigh", // connector pin 3, see pulse(). - 8 => "offline", - 32 => "waitingForOnlineRecovery", - 64 => "feedButtonPressed" - ), - self::STATUS_OFFLINE_CAUSE => array( - 4 => "coverOpen", - 8 => "paperManualFeed", - 32 => "paperEnd", - 64 => "errorOccurred" - ), - self::STATUS_ERROR_CAUSE => array( - 4 => "recoverableError", - 8 => "autocutterError", - 32 => "unrecoverableError", - 64 => "autorecoverableError" - ), - self::STATUS_PAPER_ROLL => array( - 4 => "paperNearEnd", - 32 => "paperNotPresent" - ), - self::STATUS_INK_A => array( - 4 => "inkNearEnd", - 8 => "inkEnd", - 32 => "inkNotPresent", - 64 => "cleaning" - ), - self::STATUS_INK_B => array( - 4 => "inkNearEnd", - 8 => "inkEnd", - 32 => "inkNotPresent" - ), - self::STATUS_PEELER => array( - 4 => "labelWaitingForRemoval", - 32 => "labelPaperNotDetected" - ) - ); - $flags = $statusFlags[$type]; - // Clear any previous statuses which haven't been read yet - $f = $this -> connector -> read(1); - // Make request - $reqC = chr($type); - switch($type) { - // Special cases: These are two-character requests - case self::STATUS_INK_A: - $reqC = chr(7) . chr(1); - break; - case self::STATUS_INK_B: - $reqC = chr(7) . chr(2); - break; - case self::STATUS_PEELER: - $reqC = chr(8) . chr(3); - break; - } - $this -> connector -> write(self::DLE . self::EOT . $reqC); - // Wait for single-character response - $f = $this -> connector -> read(1); - $i = 0; - while($f === false && $i < 50000) { - usleep(100); - $f = $this -> connector -> read(1); - $i++; - } - if($f === false) { - // Timeout - return null; - } - $ret = new stdClass(); - foreach($flags as $num => $name) { - $ret -> $name = (ord($f) & $num) != 0; - } - return $ret; - } - - /** - * Print an image to the printer. - * - * Size modifiers are: - * - IMG_DEFAULT (leave image at original size) - * - IMG_DOUBLE_WIDTH - * - IMG_DOUBLE_HEIGHT - * - * See the example/ folder for detailed examples. - * - * The function bitImage() takes the same parameters, and can be used if - * your printer doesn't support the newer graphics commands. - * - * @param EscposImage $img The image to print. - * @param int $size Output size modifier for the image. - */ - function graphics(EscposImage $img, $size = self::IMG_DEFAULT) { - self::validateInteger($size, 0, 3, __FUNCTION__); - $imgHeader = self::dataHeader(array($img -> getWidth(), $img -> getHeight()), true); - $tone = '0'; - $colors = '1'; - $xm = (($size & self::IMG_DOUBLE_WIDTH) == self::IMG_DOUBLE_WIDTH) ? chr(2) : chr(1); - $ym = (($size & self::IMG_DOUBLE_HEIGHT) == self::IMG_DOUBLE_HEIGHT) ? chr(2) : chr(1); - $header = $tone . $xm . $ym . $colors . $imgHeader; - $this -> wrapperSendGraphicsData('0', 'p', $header . $img -> toRasterFormat()); - $this -> wrapperSendGraphicsData('0', '2'); - } - - /** - * Initialize printer. This resets formatting back to the defaults. - */ - function initialize() { - $this -> connector -> write(self::ESC . "@"); - $this -> characterTable = 0; - } - - /** - * Generate a pulse, for opening a cash drawer if one is connected. - * The default settings should open an Epson drawer. - * - * @param int $pin 0 or 1, for pin 2 or pin 5 kick-out connector respectively. - * @param int $on_ms pulse ON time, in milliseconds. - * @param int $off_ms pulse OFF time, in milliseconds. - */ - function pulse($pin = 0, $on_ms = 120, $off_ms = 240) { - self::validateInteger($pin, 0, 1, __FUNCTION__); - self::validateInteger($on_ms, 1, 511, __FUNCTION__); - self::validateInteger($off_ms, 1, 511, __FUNCTION__); - $this -> connector -> write(self::ESC . "p" . chr($pin + 48) . chr($on_ms / 2) . chr($off_ms / 2)); - } - - /** - * Print the given data as a QR code on the printer. - * - * @param string $content The content of the code. Numeric data will be more efficiently compacted. - * @param int $ec Error-correction level to use. One of Escpos::QR_ECLEVEL_L (default), Escpos::QR_ECLEVEL_M, Escpos::QR_ECLEVEL_Q or Escpos::QR_ECLEVEL_H. Higher error correction results in a less compact code. - * @param int $size Pixel size to use. Must be 1-16 (default 3) - * @param int $model QR code model to use. Must be one of Escpos::QR_MODEL_1, Escpos::QR_MODEL_2 (default) or Escpos::QR_MICRO (not supported by all printers). - */ - function qrCode($content, $ec = self::QR_ECLEVEL_L, $size = 3, $model = self::QR_MODEL_2) { - self::validateString($content, __FUNCTION__); - self::validateInteger($ec, 0, 3, __FUNCTION__); - self::validateInteger($size, 1, 16, __FUNCTION__); - self::validateInteger($model, 1, 3, __FUNCTION__); - if($content == "") { - return; - } - if(!$this -> profile -> getSupportsQrCode()) { - // TODO use software rendering via phpqrcode instead - throw new Exception("QR codes are not supported on your printer."); - } - $cn = '1'; // Code type for QR code - // Select model: 1, 2 or micro. - $this -> wrapperSend2dCodeData(chr(65), $cn, chr(48 + $model) . chr(0)); - // Set dot size. - $this -> wrapperSend2dCodeData(chr(67), $cn, chr($size)); - // Set error correction level: L, M, Q, or H - $this -> wrapperSend2dCodeData(chr(69), $cn, chr(48 + $ec)); - // Send content & print - $this -> wrapperSend2dCodeData(chr(80), $cn, $content, '0'); - $this -> wrapperSend2dCodeData(chr(81), $cn, '', '0'); - } - - /** - * Switch character table (code page) manually. Used in conjunction with textRaw() to - * print special characters which can't be encoded automatically. - * - * @param int $table The table to select. Available code tables are model-specific. - */ - function selectCharacterTable($table = 0) { - self::validateInteger($table, 0, 255, __FUNCTION__); - $supported = $this -> profile -> getSupportedCodePages(); - if(!isset($supported[$table])) { - throw new InvalidArgumentException("There is no code table $table allowed by this printer's capability profile."); - } - $this -> characterTable = $table; - if($this -> profile -> getSupportsStarCommands()) { - /* Not an ESC/POS command: STAR printers stash all the extra code pages under a different command. */ - $this -> connector -> write(self::ESC . self::GS . "t" . chr($table)); - return; - } - $this -> connector -> write(self::ESC . "t" . chr($table)); - } - - /** - * Select print mode(s). - * - * Several MODE_* constants can be OR'd together passed to this function's `$mode` argument. The valid modes are: - * - MODE_FONT_A - * - MODE_FONT_B - * - MODE_EMPHASIZED - * - MODE_DOUBLE_HEIGHT - * - MODE_DOUBLE_WIDTH - * - MODE_UNDERLINE - * - * @param int $mode The mode to use. Default is Escpos::MODE_FONT_A, with no special formatting. This has a similar effect to running initialize(). - */ - function selectPrintMode($mode = self::MODE_FONT_A) { - $allModes = self::MODE_FONT_B | self::MODE_EMPHASIZED | self::MODE_DOUBLE_HEIGHT | self::MODE_DOUBLE_WIDTH | self::MODE_UNDERLINE; - if(!is_integer($mode) || $mode < 0 || ($mode & $allModes) != $mode) { - throw new InvalidArgumentException("Invalid mode"); - } - - $this -> connector -> write(self::ESC . "!" . chr($mode)); - } - - /** - * Set barcode height. - * - * @param int $height Height in dots. If not specified, 8 will be used. - */ - function setBarcodeHeight($height = 8) { - self::validateInteger($height, 1, 255, __FUNCTION__); - $this -> connector -> write(self::GS . "h" . chr($height)); - } - - - /** - * Set the position for the Human Readable Interpretation (HRI) of barcode characters. - * - * @param position $position. Use Escpos::BARCODE_TEXT_NONE to hide the text (default), or any combination of Escpos::BARCODE_TEXT_TOP and Escpos::BARCODE_TEXT_BOTTOM flags to display the text. - */ - function setBarcodeTextPosition($position = self::BARCODE_TEXT_NONE) { - self::validateInteger($position, 0, 3, __FUNCTION__, "Barcode text position"); - $this -> connector -> write(self::GS . "H" . chr($position)); - } - - /** - * Turn double-strike mode on/off. - * - * @param boolean $on true for double strike, false for no double strike - */ - function setDoubleStrike($on = true) { - self::validateBoolean($on, __FUNCTION__); - $this -> connector -> write(self::ESC . "G". ($on ? chr(1) : chr(0))); - } - - /** - * Turn emphasized mode on/off. - * - * @param boolean $on true for emphasis, false for no emphasis - */ - function setEmphasis($on = true) { - self::validateBoolean($on, __FUNCTION__); - $this -> connector -> write(self::ESC . "E". ($on ? chr(1) : chr(0))); - } - - /** - * Select font. Most printers have two fonts (Fonts A and B), and some have a third (Font C). - * - * @param int $font The font to use. Must be either Escpos::FONT_A, Escpos::FONT_B, or Escpos::FONT_C. - */ - function setFont($font = self::FONT_A) { - self::validateInteger($font, 0, 2, __FUNCTION__); - $this -> connector -> write(self::ESC . "M" . chr($font)); - } - - /** - * Select justification. - * - * @param int $justification One of Escpos::JUSTIFY_LEFT, Escpos::JUSTIFY_CENTER, or Escpos::JUSTIFY_RIGHT. - */ - function setJustification($justification = self::JUSTIFY_LEFT) { - self::validateInteger($justification, 0, 2, __FUNCTION__); - $this -> connector -> write(self::ESC . "a" . chr($justification)); - } - - /** - * Attach a different print buffer to the printer. Buffers are responsible for handling text output to the printer. - * - * @param PrintBuffer $buffer The buffer to use. - * @throws InvalidArgumentException Where the buffer is already attached to a different printer. - */ - function setPrintBuffer(PrintBuffer $buffer) { - if($buffer === $this -> buffer) { - return; - } - if($buffer -> getPrinter() != null) { - throw new InvalidArgumentException("This buffer is already attached to a printer."); - } - if($this -> buffer !== null) { - $this -> buffer -> setPrinter(null); - } - $this -> buffer = $buffer; - $this -> buffer -> setPrinter($this); - } - - /** - * Set black/white reverse mode on or off. In this mode, text is printed white on a black background. - * - * @param boolean $on True to enable, false to disable. - */ - function setReverseColors($on = true) { - self::validateBoolean($on, __FUNCTION__); - $this -> connector -> write(self::GS . "B" . ($on ? chr(1) : chr(0))); - } - - /** - * Set the size of text, as a multiple of the normal size. - * - * @param int $widthMultiplier Multiple of the regular height to use (range 1 - 8) - * @param int $heightMultiplier Multiple of the regular height to use (range 1 - 8) - */ - function setTextSize($widthMultiplier, $heightMultiplier) { - self::validateInteger($widthMultiplier, 1, 8, __FUNCTION__); - self::validateInteger($heightMultiplier, 1, 8, __FUNCTION__); - $c = pow(2,4) * ($widthMultiplier - 1) + ($heightMultiplier - 1); - $this -> connector -> write(self::GS . "!" . chr($c)); - } - - /** - * Set underline for printed text. - * - * Argument can be true/false, or one of UNDERLINE_NONE, - * UNDERLINE_SINGLE or UNDERLINE_DOUBLE. - * - * @param int $underline Either true/false, or one of Escpos::UNDERLINE_NONE, Escpos::UNDERLINE_SINGLE or Escpos::UNDERLINE_DOUBLE. Defaults to Escpos::UNDERLINE_SINGLE. - */ - function setUnderline($underline = self::UNDERLINE_SINGLE) { - /* Map true/false to underline constants */ - if($underline === true) { - $underline = self::UNDERLINE_SINGLE; - } else if($underline === false) { - $underline = self::UNDERLINE_NONE; - } - /* Set the underline */ - self::validateInteger($underline, 0, 2, __FUNCTION__); - $this -> connector -> write(self::ESC . "-". chr($underline)); - } - - /** - * Add text to the buffer. - * - * Text should either be followed by a line-break, or feed() should be called - * after this to clear the print buffer. - * - * @param string $str Text to print - */ - function text($str = "") { - self::validateString($str, __FUNCTION__); - $this -> buffer -> writeText((string)$str); - } - - /** - * Add text to the buffer without attempting to interpret chararacter codes. - * - * Text should either be followed by a line-break, or feed() should be called - * after this to clear the print buffer. - * - * @param string $str Text to print - */ - function textRaw($str = "") { - self::validateString($str, __FUNCTION__); - $this -> buffer -> writeTextRaw((string)$str); - } - - /** - * Wrapper for GS ( k, to calculate and send correct data length. - * - * @param string $fn Function to use - * @param string $cn Output code type. Affects available data - * @param string $data Data to send. - * @param string $m Modifier/variant for function. Often '0' where used. - * @throws InvalidArgumentException Where the input lengths are bad. - */ - private function wrapperSend2dCodeData($fn, $cn, $data = '', $m = '') { - if(strlen($m) > 1 || strlen($cn) != 1 || strlen($fn) != 1) { - throw new InvalidArgumentException("wrapperSend2dCodeData: cn and fn must be one character each."); - } - $header = $this -> intLowHigh(strlen($data) + strlen($m) + 2, 2); - $this -> connector -> write(self::GS . "(k" . $header . $cn . $fn . $m . $data); - } - - /** - * Wrapper for GS ( L, to calculate and send correct data length. - * - * @param string $m Modifier/variant for function. Usually '0'. - * @param string $fn Function number to use, as character. - * @param string $data Data to send. - * @throws InvalidArgumentException Where the input lengths are bad. - */ - private function wrapperSendGraphicsData($m, $fn, $data = '') { - if(strlen($m) != 1 || strlen($fn) != 1) { - throw new InvalidArgumentException("wrapperSendGraphicsData: m and fn must be one character each."); - } - $header = $this -> intLowHigh(strlen($data) + 2, 2); - $this -> connector -> write(self::GS . "(L" . $header . $m . $fn . $data); - } - - /** - * Convert widths and heights to characters. Used before sending graphics to set the size. - * - * @param array $inputs - * @param boolean $long True to use 4 bytes, false to use 2 - * @return string - */ - private static function dataHeader(array $inputs, $long = true) { - $outp = array(); - foreach($inputs as $input) { - if($long) { - $outp[] = Escpos::intLowHigh($input, 2); - } else { - self::validateInteger($input, 0 , 255, __FUNCTION__); - $outp[] = chr($input); - } - } - return implode("", $outp); - } - - /** - * Generate two characters for a number: In lower and higher parts, or more parts as needed. - * @param int $int Input number - * @param int $length The number of bytes to output (1 - 4). - */ - private static function intLowHigh($input, $length) { - $maxInput = (256 << ($length * 8) - 1); - self::validateInteger($length, 1, 4, __FUNCTION__); - self::validateInteger($input, 0, $maxInput, __FUNCTION__); - $outp = ""; - for($i = 0; $i < $length; $i++) { - $outp .= chr($input % 256); - $input = (int)($input / 256); - } - return $outp; - } - - /** - * Throw an exception if the argument given is not a boolean - * - * @param boolean $test the input to test - * @param string $source the name of the function calling this - */ - protected static function validateBoolean($test, $source) { - if(!($test === true || $test === false)) { - throw new InvalidArgumentException("Argument to $source must be a boolean"); - } - } - - /** - * Throw an exception if the argument given is not an integer within the specified range - * - * @param int $test the input to test - * @param int $min the minimum allowable value (inclusive) - * @param int $max the maximum allowable value (inclusive) - * @param string $source the name of the function calling this - * @param string $argument the name of the invalid parameter - */ - protected static function validateInteger($test, $min, $max, $source, $argument = "Argument") { - self::validateIntegerMulti($test, array(array($min, $max)), $source, $argument); - } - - /** - * Throw an exception if the argument given is not an integer within one of the specified ranges - * - * @param int $test the input to test - * @param arrray $ranges array of two-item min/max ranges. - * @param string $source the name of the function calling this - * @param string $source the name of the function calling this - * @param string $argument the name of the invalid parameter - */ - protected static function validateIntegerMulti($test, array $ranges, $source, $argument = "Argument") { - if(!is_integer($test)) { - throw new InvalidArgumentException("$argument given to $source must be a number, but '$test' was given."); - } - $match = false; - foreach($ranges as $range) { - $match |= $test >= $range[0] && $test <= $range[1]; - } - if(!$match) { - // Put together a good error "range 1-2 or 4-6" - $rangeStr = "range "; - for($i = 0; $i < count($ranges); $i++) { - $rangeStr .= $ranges[$i][0] . "-" . $ranges[$i][1]; - if($i == count($ranges) - 1) { - continue; - } else if($i == count($ranges) - 2) { - $rangeStr .= " or "; - } else { - $rangeStr .= ", "; - } - } - throw new InvalidArgumentException("$argument given to $source must be in $rangeStr, but $test was given."); - } - } - - /** - * Throw an exception if the argument given can't be cast to a string - * - * @param string $test the input to test - * @param string $source the name of the function calling this - * @param string $argument the name of the invalid parameter - */ - protected static function validateString($test, $source, $argument = "Argument") { - if (is_object($test) && !method_exists($test, '__toString')) { - throw new InvalidArgumentException("$argument to $source must be a string"); - } - } - - protected static function validateStringRegex($test, $source, $regex, $argument = "Argument") { - if(preg_match($regex, $test) === 0) { - throw new InvalidArgumentException("$argument given to $source is invalid. It should match regex '$regex', but '$test' was given."); - } - } -} diff --git a/htdocs/includes/mike42/escpos-php/LICENSE.md b/htdocs/includes/mike42/escpos-php/LICENSE.md index a0bebf6920b..0e04f34f84f 100644 --- a/htdocs/includes/mike42/escpos-php/LICENSE.md +++ b/htdocs/includes/mike42/escpos-php/LICENSE.md @@ -1,11 +1,7 @@ -escpos-php, a Thermal receipt printer library, for use with -ESC/POS compatible printers. +MIT License -Copyright (c) 2014-15 Michael Billington , -incorporating modifications by: -- Roni Saha -- Gergely Radics -- Warren Doyle +Copyright (c) 2014-2016 Michael Billington, incorporating modifications by others. +See CONTRIBUTORS.md for a full list. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -13,10 +9,10 @@ in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - + The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -24,4 +20,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/htdocs/includes/mike42/escpos-php/README.md b/htdocs/includes/mike42/escpos-php/README.md index 43798bb0852..c5bb5c91337 100644 --- a/htdocs/includes/mike42/escpos-php/README.md +++ b/htdocs/includes/mike42/escpos-php/README.md @@ -1,73 +1,14 @@ -ESC/POS Print Driver for PHP -============================ +# ESC/POS Print Driver for PHP +[![Build Status](https://travis-ci.org/mike42/escpos-php.svg?branch=master)](https://travis-ci.org/mike42/escpos-php) [![Latest Stable Version](https://poser.pugx.org/mike42/escpos-php/v/stable)](https://packagist.org/packages/mike42/escpos-php) +[![Total Downloads](https://poser.pugx.org/mike42/escpos-php/downloads)](https://packagist.org/packages/mike42/escpos-php) +[![License](https://poser.pugx.org/mike42/escpos-php/license)](https://packagist.org/packages/mike42/escpos-php) +[![Coverage Status](https://coveralls.io/repos/github/mike42/escpos-php/badge.svg?branch=development)](https://coveralls.io/github/mike42/escpos-php?branch=development) + This project implements a subset of Epson's ESC/POS protocol for thermal receipt printers. It allows you to generate and print receipts with basic formatting, cutting, and barcodes on a compatible printer. The library was developed to add drop-in support for receipt printing to any PHP app, including web-based point-of-sale (POS) applications. -Basic usage ------------ -A "hello world" receipt can be generated easily (Call this `hello-world.php`): -```php - text("Hello World!\n"); -$printer -> cut(); -$printer -> close(); -``` -This would be printed as: -``` -# Networked printer -php hello-world.php | nc 10.x.x.x. 9100 -# Local printer -php hello-world.php > /dev/... -# Windows local printer -php hello-world.php > foo.txt -net use LPT1 \\server\printer -copy foo.txt LPT1 -del foo.txt -``` - -From your web app, you could pass the output directly to a socket if your printer is networked: -```php - text("Hello World!\n"); -$printer -> cut(); -$printer -> close(); -``` - -Or to a local printer: -```php - text("Hello World!\n"); -$printer -> cut(); -$printer -> close(); -``` - -### Basic workflow -The library should be initialised with a PrintConnector, which will pass on the data to your printer. -Use the table under "Compatibility", or the examples below to choose the appropriate connector for your -platform & interface. If no connector is specified, then standard output is used. - -When you have finished using the print object, call `close()` to finalize any data transfers. - -### Tips & examples -On Linux, your printer device file will be somewhere like `/dev/lp0` (parallel), `/dev/usb/lp1` (USB), `/dev/ttyUSB0` (USB-Serial), `/dev/ttyS0` (serial). - -On Windows, the device files will be along the lines of `LPT1` (parallel) or `COM1` (serial). Use the `WindowsPrintConnector` to tap into system printing on Windows (eg. [Windows USB](https://github.com/mike42/escpos-php/tree/master/example/interface/windows-usb.php), [SMB](https://github.com/mike42/escpos-php/tree/master/example/interface/smb.php) or [Windows LPT](https://github.com/mike42/escpos-php/tree/master/example/interface/windows-lpt.php)) - this submits print jobs via a queue rather than communicating directly with the printer. - -A complete real-world receipt can be found in the code of [Auth](https://github.com/mike42/Auth) in [ReceiptPrinter.php](https://github.com/mike42/Auth/blob/master/lib/misc/ReceiptPrinter.php). It includes justification, boldness, and a barcode. - -Other examples are located in the [example/](https://github.com/mike42/escpos-php/blob/master/example/) directory. - -Compatibility -------------- +## Compatibility ### Interfaces and operating systems This driver is known to work with the following OS/interface combinations: @@ -115,43 +56,276 @@ This driver is known to work with the following OS/interface combinations: No Yes + +CUPS hosted +Yes +Yes +No + ### Printers Many thermal receipt printers support ESC/POS to some degree. This driver has been known to work with: +- 3nStar RPT-008 +- Approx APPPOS80AM +- AURES ODP-333 +- AURES ODP-500 +- Bematech-4200-TH +- Bematech LR2000E +- Birch PRP-085III +- Bixolon SRP-350III +- Bixolon SRP-350Plus +- Black Copper BC-85AC +- CHD TH-305N +- Citizen CBM1000-II +- Citizen CT-S310II +- Dapper-Geyi Q583P +- Daruma DR800 +- DR-MP200 (manufacturer unknown) - EPOS TEP 220M +- Elgin i9 +- Epson EU-T332C +- Epson FX-890 (requires `feedForm()` to release paper). +- Epson TM-T20 +- Epson TM-T20II +- Epson TM-T70 +- Epson TM-T70II +- Epson TM-T81 +- Epson TM-T82II +- Epson TM-T88II - Epson TM-T88III - Epson TM-T88IV -- Epson TM-T70 -- Epson TM-T82II -- Epson TM-T20 -- Epson TM-T70II +- Epson TM-T88V - Epson TM-U220 -- Epson FX-890 (requires `feedForm()` to release paper). -- Okipos 80 Plus III +- Epson TM-U295 (requires `release()` to release slip). +- Epson TM-U590 and TM-U590P +- Equal (EQ-IT-001) POS-58 +- Everycom EC-58 +- Excelvan HOP-E200 +- Excelvan HOP-E58 +- Excelvan HOP-E801 +- Gainscha GP-2120TF +- Gainscha GP-5890x (Also marketed as EC Line 5890x) +- Gainscha GP-U80300I (Also marketed as gprinter GP-U80300I) +- gprinter GP-U80160I +- HOIN HOP-H58 +- Ithaca iTherm 28 +- Hasar HTP 250 +- Metapace T-1 +- Metapace T-25 +- Nexa PX700 +- Nyear NP100 +- OKI RT322 +- OKI 80 Plus III +- Orient BTP-R580 - P-822D +- P85A-401 (make unknown) +- Partner Tech RP320 +- POSLIGNE ODP200H-III-G +- QPOS Q58M +- Rongta RP326US +- Rongta RP58-U +- Rongta RP80USE +- SAM4S GIANT-100DB +- Senor TP-100 +- Sewoo SLK-TS400 +- SEYPOS PRP-96 - SEYPOS PRP-300 (Also marketed as TYSSO PRP-300) +- SNBC BTP-R880NPIII +- Solux SX-TP-88300 +- Sicar POS-80 +- Silicon SP-201 / RP80USE +- SPRT SP-POS88V +- Star BSC10 +- Star TSP100 ECO +- Star TSP100III FuturePRNT - Star TSP-650 - Star TUP-592 +- TVS RP45 Shoppe +- Venus V248T +- Xeumior SM-8330 +- Xprinter F-900 +- Xprinter XP-365B +- Xprinter XP-58 Series +- Xprinter XP-80C +- Xprinter XP-90 +- XPrinter XP-Q20011 - Xprinter XP-Q800 -- Zijang NT-58H -- Zijang ZJ-5870 -- Zijang ZJ-5890T (Marketed as POS 5890T) +- Zjiang NT-58H +- Zjiang ZJ-5870 +- Zjiang ZJ-5890 (Also sold as POS-5890 by many vendors; ZJ-5890K, ZJ-5890T also work). +- Zjiang ZJ-8220 (Also marketed as Excelvan ZJ-8220) +- Zjiang ZJ-8250 -If you use any other printer with this code, please let me know so I can add it to the list. +If you use any other printer with this code, please [let us know](https://github.com/mike42/escpos-php/issues/new) so that it can be added to the list. -Available methods ------------------ +## Basic usage -### __construct(PrintConnector $connector, AbstractCapabilityProfile $profile) +### Include the library + +#### Composer +If you are using composer, then add `mike42/escpos-php` as a dependency: + +```bash +composer require mike42/escpos-php +``` + +In this case, you would include composer's auto-loader at the top of your source files: + +```php + text("Hello World!\n"); +$printer -> cut(); +$printer -> close(); +``` + +Some examples are below for common interfaces. + +Communicate with a printer with an Ethernet interface using `netcat`: + +```bash +php hello-world.php | nc 10.x.x.x. 9100 +``` + +A USB local printer connected with `usblp` on Linux has a device file (Includes USB-parallel interfaces): + +```bash +php hello-world.php > /dev/usb/lp0 +``` + +A computer installed into the local `cups` server is accessed through `lp` or `lpr`: + +```bash +php hello-world.php > foo.txt +lpr -o raw -H localhost -P printer foo.txt +``` + +A local or networked printer on a Windows computer is mapped in to a file, and generally requires you to share the printer first: + +``` +php hello-world.php > foo.txt +net use LPT1 \\server\printer +copy foo.txt LPT1 +del foo.txt +``` + +If you have troubles at this point, then you should consult your OS and printer system documentation to try to find a working print command. + +### Using a PrintConnector + +To print receipts from PHP, use the most applicable [PrintConnector](https://github.com/mike42/escpos-php/tree/master/src/Mike42/Escpos/PrintConnectors) for your setup. The connector simply provides the plumbing to get data to the printer. + +For example, a `NetworkPrintConnector` accepts an IP address and port: + +```php +use Mike42\Escpos\PrintConnectors\NetworkPrintConnector; +use Mike42\Escpos\Printer; +$connector = new NetworkPrintConnector("10.x.x.x", 9100); +$printer = new Printer($connector); +try { + // ... Print stuff +} finally { + $printer -> close(); +} +``` + +While a serial printer might use: +```php +use Mike42\Escpos\PrintConnectors\FilePrintConnector; +use Mike42\Escpos\Printer; +$connector = new FilePrintConnector("/dev/ttyS0"); +$printer = new Printer($connector); +``` + +For each OS/interface combination that's supported, there are examples in the compatibility section of how a `PrintConnector` would be constructed. If you can't get a `PrintConnector` to work, then be sure to include the working print command in bug. + +### Using a CapabilityProfile + +Support for commands and code pages varies between printer vendors and models. By default, the driver will accept UTF-8, and output commands that are suitable for Epson TM-series printers. + +When trying out a new brand of printer, it's a good idea to use the "simple" `CapabilityProfile`, which instructs the driver to avoid the use of advanced features (generally simpler image handling, ASCII-only text). + +```php +use Mike42\Escpos\PrintConnectors\WindowsPrintConnector; +use Mike42\Escpos\CapabilityProfile; +$profile = CapabilityProfile::load("simple"); +$connector = new WindowsPrintConnector("smb://computer/printer"); +$printer = new Printer($connector, $profile); +``` + +As another example, Star-branded printers use different commands: + +```php +use Mike42\Escpos\PrintConnectors\WindowsPrintConnector; +use Mike42\Escpos\CapabilityProfile; +$profile = CapabilityProfile::load("SP2000") +$connector = new WindowsPrintConnector("smb://computer/printer"); +$printer = new Printer($connector, $profile); +``` + +For a list of available profiles, or to have support for your printer improved, please see the upstream [receipt-print-hq/escpos-printer-db](https://github.com/receipt-print-hq/escpos-printer-db) project. + +### Tips & examples +On Linux, your printer device file will be somewhere like `/dev/lp0` (parallel), `/dev/usb/lp1` (USB), `/dev/ttyUSB0` (USB-Serial), `/dev/ttyS0` (serial). + +On Windows, the device files will be along the lines of `LPT1` (parallel) or `COM1` (serial). Use the `WindowsPrintConnector` to tap into system printing on Windows (eg. [Windows USB](https://github.com/mike42/escpos-php/tree/master/example/interface/windows-usb.php), [SMB](https://github.com/mike42/escpos-php/tree/master/example/interface/smb.php) or [Windows LPT](https://github.com/mike42/escpos-php/tree/master/example/interface/windows-lpt.php)) - this submits print jobs via a queue rather than communicating directly with the printer. + +A complete real-world receipt can be found in the code of [Auth](https://github.com/mike42/Auth) in [ReceiptPrinter.php](https://github.com/mike42/Auth/blob/master/lib/misc/ReceiptPrinter.php). It includes justification, boldness, and a barcode. + +Other examples are located in the [example/](https://github.com/mike42/escpos-php/blob/master/example/) directory. + +## Available methods + +### __construct(PrintConnector $connector, CapabilityProfile $profile) Construct new print object. Parameters: -- `PrintConnector $connector`: The PrintConnector to send data to. If not set, output is sent to standard output. -- `AbstractCapabilityProfile $profile` Supported features of this printer. If not set, the DefaultCapabilityProfile will be used, which is suitable for Epson printers. +- `PrintConnector $connector`: The PrintConnector to send data to. +- `CapabilityProfile $profile` Supported features of this printer. If not set, the "default" CapabilityProfile will be used, which is suitable for Epson printers. -See [example/interface/]("https://github.com/mike42/escpos-php/tree/master/example/interface/) for ways to open connections for different platforms and interfaces. +See [example/interface/](https://github.com/mike42/escpos-php/tree/master/example/interface/) for ways to open connections for different platforms and interfaces. ### barcode($content, $type) Print a barcode. @@ -159,7 +333,7 @@ Print a barcode. Parameters: - `string $content`: The information to encode. -- `int $type`: The barcode standard to output. If not specified, `Escpos::BARCODE_CODE39` will be used. +- `int $type`: The barcode standard to output. If not specified, `Printer::BARCODE_CODE39` will be used. Currently supported barcode standards are (depending on your printer): @@ -181,7 +355,7 @@ Cut the paper. Parameters: -- `int $mode`: Cut mode, either `Escpos::CUT_FULL` or `Escpos::CUT_PARTIAL`. If not specified, `Escpos::CUT_FULL` will be used. +- `int $mode`: Cut mode, either `Printer::CUT_FULL` or `Printer::CUT_PARTIAL`. If not specified, `Printer::CUT_FULL` will be used. - `int $lines`: Number of lines to feed before cutting. If not specified, 3 will be used. ### feed($lines) @@ -219,17 +393,29 @@ A minimal example: ```php graphics($img); ``` See the [example/](https://github.com/mike42/escpos-php/blob/master/example/) folder for detailed examples. -The function [bitImage()](#bitimageescposimage-image-size) takes the same parameters, and can be used if your printer doesn't support the newer graphics commands. +The function [bitImage()](#bitimageescposimage-image-size) takes the same parameters, and can be used if your printer doesn't support the newer graphics commands. As an additional fallback, the `bitImageColumnFormat()` function is also provided. ### initialize() Initialize printer. This resets formatting back to the defaults. +### pdf417Code($content, $width, $heightMultiplier, $dataColumnCount, $ec, $options) +Print a two-dimensional data code using the PDF417 standard. + +Parameters: + +- `string $content`: Text or numbers to store in the code +- `number $width`: Width of a module (pixel) in the printed code. Default is 3 dots. +- `number $heightMultiplier`: Multiplier for height of a module. Default is 3 times the width. +- `number $dataColumnCount`: Number of data columns to use. 0 (default) is to auto-calculate. Smaller numbers will result in a narrower code, making larger pixel sizes possible. Larger numbers require smaller pixel sizes. +- `real $ec`: Error correction ratio, from 0.01 to 4.00. Default is 0.10 (10%). +- `number $options`: Standard code `Printer::PDF417_STANDARD` with start/end bars, or truncated code `Printer::PDF417_TRUNCATED` with start bars only. + ### pulse($pin, $on_ms, $off_ms) Generate a pulse, for opening a cash drawer if one is connected. The default settings (0, 120, 240) should open an Epson drawer. @@ -243,16 +429,16 @@ Parameters: Print the given data as a QR code on the printer. - `string $content`: The content of the code. Numeric data will be more efficiently compacted. -- `int $ec` Error-correction level to use. One of `Escpos::QR_ECLEVEL_L` (default), `Escpos::QR_ECLEVEL_M`, `Escpos::QR_ECLEVEL_Q` or `Escpos::QR_ECLEVEL_H`. Higher error correction results in a less compact code. +- `int $ec` Error-correction level to use. One of `Printer::QR_ECLEVEL_L` (default), `Printer::QR_ECLEVEL_M`, `Printer::QR_ECLEVEL_Q` or `Printer::QR_ECLEVEL_H`. Higher error correction results in a less compact code. - `int $size`: Pixel size to use. Must be 1-16 (default 3) -- `int $model`: QR code model to use. Must be one of `Escpos::QR_MODEL_1`, `Escpos::QR_MODEL_2` (default) or `Escpos::QR_MICRO` (not supported by all printers). +- `int $model`: QR code model to use. Must be one of `Printer::QR_MODEL_1`, `Printer::QR_MODEL_2` (default) or `Printer::QR_MICRO` (not supported by all printers). ### selectPrintMode($mode) Select print mode(s). Parameters: -- `int $mode`: The mode to use. Default is `Escpos::MODE_FONT_A`, with no special formatting. This has a similar effect to running `initialize()`. +- `int $mode`: The mode to use. Default is `Printer::MODE_FONT_A`, with no special formatting. This has a similar effect to running `initialize()`. Several MODE_* constants can be OR'd together passed to this function's `$mode` argument. The valid modes are: @@ -270,6 +456,20 @@ Parameters: - `int $height`: Height in dots. If not specified, 8 will be used. +### setBarcodeWidth($width) +Set barcode bar width. + +Parameters: + +- `int $width`: Bar width in dots. If not specified, 3 will be used. Values above 6 appear to have no effect. + +### setColor($color) +Select print color - on printers that support multiple colors. + +Parameters: + +- `int $color`: Color to use. Must be either `Printer::COLOR_1` (default), or `Printer::COLOR_2` + ### setDoubleStrike($on) Turn double-strike mode on/off. @@ -289,14 +489,40 @@ Select font. Most printers have two fonts (Fonts A and B), and some have a third Parameters: -- `int $font`: The font to use. Must be either `Escpos::FONT_A`, `Escpos::FONT_B`, or `Escpos::FONT_C`. +- `int $font`: The font to use. Must be either `Printer::FONT_A`, `Printer::FONT_B`, or `Printer::FONT_C`. ### setJustification($justification) Select justification. Parameters: -- `int $justification`: One of `Escpos::JUSTIFY_LEFT`, `Escpos::JUSTIFY_CENTER`, or `Escpos::JUSTIFY_RIGHT`. +- `int $justification`: One of `Printer::JUSTIFY_LEFT`, `Printer::JUSTIFY_CENTER`, or `Printer::JUSTIFY_RIGHT`. + +### setLineSpacing($height) + +Set the height of the line. + +Some printers will allow you to overlap lines with a smaller line feed. + +Parameters: + +- `int $height`: The height of each line, in dots. If not set, the printer will reset to its default line spacing. + +### setPrintLeftMargin($margin) + +Set print area left margin. Reset to default with `Printer::initialize()`. + +Parameters: + +- `int $margin`: The left margin to set on to the print area, in dots. + +### setPrintWidth($width) + +Set print area width. This can be used to add a right margin to the print area. Reset to default with `Printer::initialize()`. + +Parameters: + +- `int $width`: The width of the page print area, in dots. ### setReverseColors($on) Set black/white reverse mode on or off. In this mode, text is printed white on a black background. @@ -318,7 +544,7 @@ Set underline for printed text. Parameters: -- `int $underline`: Either `true`/`false`, or one of `Escpos::UNDERLINE_NONE`, `Escpos::UNDERLINE_SINGLE` or `Escpos::UNDERLINE_DOUBLE`. Defaults to `Escpos::UNDERLINE_SINGLE`. +- `int $underline`: Either `true`/`false`, or one of `Printer::UNDERLINE_NONE`, `Printer::UNDERLINE_SINGLE` or `Printer::UNDERLINE_DOUBLE`. Defaults to `Printer::UNDERLINE_SINGLE`. ### text($str) Add text to the buffer. Text should either be followed by a line-break, or `feed()` should be called after this. @@ -327,26 +553,37 @@ Parameters: - `string $str`: The string to print. -Further notes -------------- +# Further notes Posts I've written up for people who are learning how to use receipt printers: -* [What is ESC/POS, and how do I use it?](http://mike.bitrevision.com/blog/what-is-escpos-and-how-do-i-use-it), which documents the output of test.php. -* [Setting up an Epson receipt printer](http://mike.bitrevision.com/blog/2014-20-26-setting-up-an-epson-receipt-printer) -* [Getting a USB receipt printer working on Linux](http://mike.bitrevision.com/blog/2015-03-getting-a-usb-receipt-printer-working-on-linux) +* [What is ESC/POS, and how do I use it?](https://mike42.me/blog/what-is-escpos-and-how-do-i-use-it), which documents the output of `example/demo.php`. +* [Setting up an Epson receipt printer](https://mike42.me/blog/2014-20-26-setting-up-an-epson-receipt-printer) +* [Getting a USB receipt printer working on Linux](https://mike42.me/blog/2015-03-getting-a-usb-receipt-printer-working-on-linux) -Other versions --------------- -Some forks of this project have been developed by others for specific use cases. Improvements from the following projects have been incorporated into escpos-php: +# Development -- [wdoyle/EpsonESCPOS-PHP](https://github.com/wdoyle/EpsonESCPOS-PHP) -- [ronisaha/php-esc-pos](https://github.com/ronisaha/php-esc-pos) +This code is MIT licensed, and you are encouraged to contribute any modifications back to the project. -Vendor documentation --------------------- -Epson notes that not all of its printers support all ESC/POS features, and includes a table in their documentation: +For development, it's suggested that you load `imagick`, `gd` and `Xdebug` PHP exensions, and install `composer`. -* [FAQ about ESC/POS from Epson](http://content.epson.de/fileadmin/content/files/RSD/downloads/escpos.pdf) +The tests are executed on [Travis CI](https://travis-ci.org/mike42/escpos-php) over PHP 5.4, 5.5, 5.6, 7.0, 7.1 and 7.2, plus the latest LTS version of HHVM, 3.21. Older versions of PHP are not supported in current releases. -Note that many printers produced by other vendors use the same standard, and are compatible by varying degrees. +Fetch a copy of this code and load dependencies with composer: + git clone https://github.com/mike42/escpos-php + cd escpos-php/ + composer install + +Execute unit tests via `phpunit`: + + php vendor/bin/phpunit --coverage-text + +This project uses the PSR-2 standard, which can be checked via [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer): + + php vendor/bin/phpcs --standard=psr2 src/ -n + +The developer docs are build with [doxygen](https://github.com/doxygen/doxygen). Re-build them to check for documentation warnings: + + make -C doc clean && make -C doc + +Pull requests and bug reports welcome. diff --git a/htdocs/includes/mike42/escpos-php/autoload.php b/htdocs/includes/mike42/escpos-php/autoload.php new file mode 100644 index 00000000000..7779486b824 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/autoload.php @@ -0,0 +1,26 @@ +=5.3.0" - }, - "require-dev": { - "phpunit/phpunit": "4.5.*" - } + "name": "mike42/escpos-php", + "type": "library", + "description": "PHP receipt printer library for use with ESC/POS-compatible thermal and impact printers", + "homepage": "https://github.com/mike42/escpos-php", + "keywords": ["receipt", "print", "escpos", "ESC-POS", "driver"], + "license": "MIT", + "authors": [ + { + "name": "Michael Billington", + "email": "michael.billington@gmail.com" + } + ], + "config": { + "platform": { + "php": "5.4.0" + } + }, + "require": { + "php": ">=5.4.0", + "ext-mbstring": "*" + }, + "suggest": { + "guzzlehttp/guzzle": "Allows the use of the ApiConnector to send print jobs over HTTP.", + "ext-imagick": "Will be used for image printing if present. Required for PDF printing or use of custom fonts.", + "ext-gd": "Used for image printing if present." + }, + "require-dev": { + "phpunit/phpunit": "^4.8", + "squizlabs/php_codesniffer": "^3.2", + "guzzlehttp/guzzle": "^5.3" + }, + "autoload": { + "psr-4": { + "Mike42\\": "src/Mike42" + } + } } diff --git a/htdocs/includes/mike42/escpos-php/composer.lock b/htdocs/includes/mike42/escpos-php/composer.lock index ab6911c281d..d46bbc79312 100644 --- a/htdocs/includes/mike42/escpos-php/composer.lock +++ b/htdocs/includes/mike42/escpos-php/composer.lock @@ -1,24 +1,24 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "fd25f2b816df83dabf03fe7259ad4018", + "content-hash": "0094775b67f67bc65c1ff4aebb0fd065", "packages": [], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.0.4", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", "shasum": "" }, "require": { @@ -29,7 +29,7 @@ "ext-pdo": "*", "ext-phar": "*", "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "2.0.*@ALPHA" + "squizlabs/php_codesniffer": "~2.0" }, "type": "library", "extra": { @@ -38,8 +38,8 @@ } }, "autoload": { - "psr-0": { - "Doctrine\\Instantiator\\": "src" + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", @@ -59,7 +59,161 @@ "constructor", "instantiate" ], - "time": "2014-10-13 12:58:55" + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "5.3.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "f9acb4761844317e626a32259205bec1f1bc60d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/f9acb4761844317e626a32259205bec1f1bc60d2", + "reference": "f9acb4761844317e626a32259205bec1f1bc60d2", + "shasum": "" + }, + "require": { + "guzzlehttp/ringphp": "^1.1", + "php": ">=5.4.0", + "react/promise": "^2.2" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2018-01-15T07:18:01+00:00" + }, + { + "name": "guzzlehttp/ringphp", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/RingPHP.git", + "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/RingPHP/zipball/dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", + "reference": "dbbb91d7f6c191e5e405e900e3102ac7f261bc0b", + "shasum": "" + }, + "require": { + "guzzlehttp/streams": "~3.0", + "php": ">=5.4.0", + "react/promise": "~2.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "~4.0" + }, + "suggest": { + "ext-curl": "Guzzle will use specific adapters if cURL is present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Ring\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple API and specification that abstracts away the details of HTTP into a single PHP function.", + "time": "2015-05-20T03:37:09+00:00" + }, + { + "name": "guzzlehttp/streams", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/guzzle/streams.git", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/streams/zipball/47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "reference": "47aaa48e27dae43d39fc1cea0ccf0d84ac1a2ba5", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Stream\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Provides a simple abstraction over streams of data", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "Guzzle", + "stream" + ], + "time": "2014-10-12T19:18:40+00:00" }, { "name": "phpdocumentor/reflection-docblock", @@ -108,34 +262,37 @@ "email": "mike.vanriel@naenius.com" } ], - "time": "2015-02-03 12:10:50" + "time": "2015-02-03T12:10:50+00:00" }, { "name": "phpspec/prophecy", - "version": "1.4.0", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5" + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", - "reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", - "phpdocumentor/reflection-docblock": "~2.0", - "sebastian/comparator": "~1.1" + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { - "phpspec/phpspec": "~2.0" + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8 || ^5.6.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "1.6.x-dev" } }, "autoload": { @@ -168,20 +325,20 @@ "spy", "stub" ], - "time": "2015-03-27 19:31:25" + "time": "2017-03-02T20:05:34+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "2.0.15", + "version": "2.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "34cc484af1ca149188d0d9e91412191e398e0b67" + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67", - "reference": "34cc484af1ca149188d0d9e91412191e398e0b67", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979", + "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979", "shasum": "" }, "require": { @@ -189,7 +346,7 @@ "phpunit/php-file-iterator": "~1.3", "phpunit/php-text-template": "~1.2", "phpunit/php-token-stream": "~1.3", - "sebastian/environment": "~1.0", + "sebastian/environment": "^1.3.2", "sebastian/version": "~1.0" }, "require-dev": { @@ -204,7 +361,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "2.2.x-dev" } }, "autoload": { @@ -230,35 +387,37 @@ "testing", "xunit" ], - "time": "2015-01-24 10:06:35" + "time": "2015-10-06T15:47:00+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.3.4", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb" + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb", - "reference": "acd690379117b042d1c8af1fafd61bde001bf6bb", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5", + "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5", "shasum": "" }, "require": { "php": ">=5.3.3" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, "autoload": { "classmap": [ - "File/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -275,20 +434,20 @@ "filesystem", "iterator" ], - "time": "2013-10-10 15:34:57" + "time": "2016-10-03T07:40:28+00:00" }, { "name": "phpunit/php-text-template", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a" + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", - "reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "shasum": "" }, "require": { @@ -297,20 +456,17 @@ "type": "library", "autoload": { "classmap": [ - "Text/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -319,35 +475,40 @@ "keywords": [ "template" ], - "time": "2014-01-30 17:20:04" + "time": "2015-06-21T13:50:34+00:00" }, { "name": "phpunit/php-timer", - "version": "1.0.5", + "version": "1.0.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c" + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c", - "reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, "autoload": { "classmap": [ - "PHP/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", - "include-path": [ - "" - ], "license": [ "BSD-3-Clause" ], @@ -363,20 +524,20 @@ "keywords": [ "timer" ], - "time": "2013-08-02 07:42:54" + "time": "2017-02-26T11:10:40+00:00" }, { "name": "phpunit/php-token-stream", - "version": "1.4.0", + "version": "1.4.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74" + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74", - "reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", "shasum": "" }, "require": { @@ -412,20 +573,20 @@ "keywords": [ "tokenizer" ], - "time": "2015-01-17 09:51:32" + "time": "2017-02-27T10:12:30+00:00" }, { "name": "phpunit/phpunit", - "version": "4.5.1", + "version": "4.8.36", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4" + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d6429b0995b24a2d9dfe5587ee3a7071c1161af4", - "reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", "shasum": "" }, "require": { @@ -435,19 +596,19 @@ "ext-reflection": "*", "ext-spl": "*", "php": ">=5.3.3", - "phpspec/prophecy": "~1.3,>=1.3.1", - "phpunit/php-code-coverage": "~2.0,>=2.0.11", - "phpunit/php-file-iterator": "~1.3.2", + "phpspec/prophecy": "^1.3.1", + "phpunit/php-code-coverage": "~2.1", + "phpunit/php-file-iterator": "~1.4", "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "~1.0.2", + "phpunit/php-timer": "^1.0.6", "phpunit/phpunit-mock-objects": "~2.3", - "sebastian/comparator": "~1.1", - "sebastian/diff": "~1.1", - "sebastian/environment": "~1.2", + "sebastian/comparator": "~1.2.2", + "sebastian/diff": "~1.2", + "sebastian/environment": "~1.3", "sebastian/exporter": "~1.2", "sebastian/global-state": "~1.0", "sebastian/version": "~1.0", - "symfony/yaml": "~2.0" + "symfony/yaml": "~2.1|~3.0" }, "suggest": { "phpunit/php-invoker": "~1.1" @@ -458,7 +619,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.5.x-dev" + "dev-master": "4.8.x-dev" } }, "autoload": { @@ -484,26 +645,27 @@ "testing", "xunit" ], - "time": "2015-03-29 09:24:05" + "time": "2017-06-21T08:07:12+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "2.3.1", + "version": "2.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "74ffb87f527f24616f72460e54b595f508dccb5c" + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/74ffb87f527f24616f72460e54b595f508dccb5c", - "reference": "74ffb87f527f24616f72460e54b595f508dccb5c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983", + "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983", "shasum": "" }, "require": { - "doctrine/instantiator": "~1.0,>=1.0.2", + "doctrine/instantiator": "^1.0.2", "php": ">=5.3.3", - "phpunit/php-text-template": "~1.2" + "phpunit/php-text-template": "~1.2", + "sebastian/exporter": "~1.2" }, "require-dev": { "phpunit/phpunit": "~4.4" @@ -539,26 +701,72 @@ "mock", "xunit" ], - "time": "2015-04-02 05:36:41" + "time": "2015-10-02T06:51:40+00:00" }, { - "name": "sebastian/comparator", - "version": "1.1.1", + "name": "react/promise", + "version": "v2.5.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1dd8869519a225f7f2b9eb663e225298fade819e" + "url": "https://github.com/reactphp/promise.git", + "reference": "62785ae604c8d69725d693eb370e1d67e94c4053" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e", - "reference": "1dd8869519a225f7f2b9eb663e225298fade819e", + "url": "https://api.github.com/repos/reactphp/promise/zipball/62785ae604c8d69725d693eb370e1d67e94c4053", + "reference": "62785ae604c8d69725d693eb370e1d67e94c4053", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com" + } + ], + "description": "A lightweight implementation of CommonJS Promises/A for PHP", + "keywords": [ + "promise", + "promises" + ], + "time": "2017-03-25T12:08:31+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", "shasum": "" }, "require": { "php": ">=5.3.3", "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2" + "sebastian/exporter": "~1.2 || ~2.0" }, "require-dev": { "phpunit/phpunit": "~4.4" @@ -566,7 +774,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -603,32 +811,32 @@ "compare", "equality" ], - "time": "2015-01-29 16:28:08" + "time": "2017-01-29T09:50:25+00:00" }, { "name": "sebastian/diff", - "version": "1.3.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "~4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -651,31 +859,31 @@ } ], "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", + "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff" ], - "time": "2015-02-22 15:13:53" + "time": "2015-12-08T07:14:41+00:00" }, { "name": "sebastian/environment", - "version": "1.2.2", + "version": "1.3.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e" + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e", - "reference": "5a8c7d31914337b69923db26c4221b81ff5a196e", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea", + "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^4.8 || ^5.0" }, "type": "library", "extra": { @@ -705,20 +913,20 @@ "environment", "hhvm" ], - "time": "2015-01-01 10:01:08" + "time": "2016-08-18T05:49:44+00:00" }, { "name": "sebastian/exporter", - "version": "1.2.0", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "84839970d05254c73cde183a721c7af13aede943" + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943", - "reference": "84839970d05254c73cde183a721c7af13aede943", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", + "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", "shasum": "" }, "require": { @@ -726,12 +934,13 @@ "sebastian/recursion-context": "~1.0" }, "require-dev": { + "ext-mbstring": "*", "phpunit/phpunit": "~4.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "1.3.x-dev" } }, "autoload": { @@ -771,20 +980,20 @@ "export", "exporter" ], - "time": "2015-01-27 07:23:06" + "time": "2016-06-17T09:04:28+00:00" }, { "name": "sebastian/global-state", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01" + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01", - "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", "shasum": "" }, "require": { @@ -822,20 +1031,20 @@ "keywords": [ "global state" ], - "time": "2014-10-06 09:23:50" + "time": "2015-10-12T03:26:01+00:00" }, { "name": "sebastian/recursion-context", - "version": "1.0.0", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "3989662bbb30a29d20d9faa04a846af79b276252" + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252", - "reference": "3989662bbb30a29d20d9faa04a846af79b276252", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", "shasum": "" }, "require": { @@ -875,20 +1084,20 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-01-24 09:48:32" + "time": "2016-10-03T07:41:43+00:00" }, { "name": "sebastian/version", - "version": "1.0.5", + "version": "1.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4" + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", - "reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", + "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6", "shasum": "" }, "type": "library", @@ -910,39 +1119,100 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", - "time": "2015-02-24 06:35:25" + "time": "2015-06-21T13:59:46+00:00" }, { - "name": "symfony/yaml", - "version": "v2.6.6", - "target-dir": "Symfony/Component/Yaml", + "name": "squizlabs/php_codesniffer", + "version": "3.2.3", "source": { "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "174f009ed36379a801109955fc5a71a49fe62dd4" + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "4842476c434e375f9d3182ff7b89059583aa8b27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/174f009ed36379a801109955fc5a71a49fe62dd4", - "reference": "174f009ed36379a801109955fc5a71a49fe62dd4", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/4842476c434e375f9d3182ff7b89059583aa8b27", + "reference": "4842476c434e375f9d3182ff7b89059583aa8b27", "shasum": "" }, "require": { - "php": ">=5.3.3" + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" }, "require-dev": { - "symfony/phpunit-bridge": "~2.7" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2018-02-20T21:35:23+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v2.8.18", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "bb4ec47e8e109c1c1172145732d0aa468d967cd0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bb4ec47e8e109c1c1172145732d0aa468d967cd0", + "reference": "bb4ec47e8e109c1c1172145732d0aa468d967cd0", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^2.0.5|~3.0.0", + "symfony/dependency-injection": "~2.6|~3.0.0", + "symfony/expression-language": "~2.6|~3.0.0", + "symfony/stopwatch": "~2.3|~3.0.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.8-dev" } }, "autoload": { - "psr-0": { - "Symfony\\Component\\Yaml\\": "" - } + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -950,17 +1220,66 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony EventDispatcher Component", + "homepage": "https://symfony.com", + "time": "2017-02-21T08:33:48+00:00" + }, + { + "name": "symfony/yaml", + "version": "v2.8.18", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "2a7bab3c16f6f452c47818fdd08f3b1e49ffcf7d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/2a7bab3c16f6f452c47818fdd08f3b1e49ffcf7d", + "reference": "2a7bab3c16f6f452c47818fdd08f3b1e49ffcf7d", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Yaml Component", - "homepage": "http://symfony.com", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com", + "time": "2017-03-01T18:13:50+00:00" } ], "aliases": [], @@ -969,7 +1288,11 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.3.0" + "php": ">=5.4.0", + "ext-mbstring": "*" }, - "platform-dev": [] + "platform-dev": [], + "platform-overrides": { + "php": "5.4.0" + } } diff --git a/htdocs/includes/mike42/escpos-php/doc/FAQ.md b/htdocs/includes/mike42/escpos-php/doc/FAQ.md new file mode 100644 index 00000000000..6b7a6247bca --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/doc/FAQ.md @@ -0,0 +1,142 @@ +# Frequently Asked Questions (FAQ) + +## Can I print to File Format X with this? + +If you are trying to generate XPS, PDF or DOCX or HTML files from PHP, then you are most likely in the wrong place. + +The purpose of this driver it to generate binary ESC/POS code, which is understood by many embedded thermal receipt and impact printers. + +## I have Printer X. Can I use this driver? + +If the printer understands ESC/POS, and you know how to get raw binary data to it, then yes. Otherwise, no. + +The [list of printers that are known to work](https://github.com/mike42/escpos-php/blob/development/README.md#printers) is crowd-sourced. We appreciate it when developers try out the driver, then [file information on the bug tracker](https://github.com/mike42/escpos-php/issues/new) with some information about which features worked on their model of printer. + +To see how well your printer works, first check that it supports ESC/POS, then begin by attempting to send the text "Hello World" to your printer on the command-line, from the computer that will run PHP. + +Once you solve this, [try to do the same from PHP](https://github.com/mike42/escpos-php/blob/development/README.md#basic-usage) using the default profile. Further details are in the [README](https://github.com/mike42/escpos-php/blob/development/README.md) file. + +## Can you add support for Printer X? + +Features vary between printers, so we collaborate on an ESC/POS printer compatibility database to collect known differences: [receipt-print-hq/escpos-printer-db](https://github.com/receipt-print-hq/escpos-printer-db). + +If you encounter garbage output when you try to print images or special characters, then please submit a test page and a link to vendor documentation to the `escpos-printer-db` project, so that support can be improved for future versions. + +## I have a printer that does not understand ESC/POS. Can I use this driver? + +No. The purpose of this driver it to generate binary ESC/POS code. If your printer doesn't understand that, then this code wont be much use to you. + +Some printers do have an emulation mode for ESC/POS. The vendor docs will tell if this is the case, and how to enable it. + +## Why do I get this error when I try to print? + +Start by testing that you can send text to your printer outside of escpos-php. The examples linked to in the README are commented with some commands to get you started. + +Generally, initial setup problems seem to have one of these causes: + +1. You are writing to the wrong place. Writing to `LPT1` does not output to parallel port on Linux, and `/dev/ttyS0` is not a serial printer on Windows. +2. The printer has not been set up to accept printing the way you expect. This means permissions on Linux, network printers being configured, and shared printers having user accounts and firewalls set up correctly on the print server. +3. Your printer actually doesn't work (rare but possible). + +To be clear, these are not escpos-php issues: No amount of PHP code can set up your printer for you. Instead, the driver relies on developers determining how their setup is going to work before using a connector to transport data to their printer. + +Once you have a working command to send text to your printer (from the PHP server), you are ready to use escpos-php. You can try to use a PrintConnector now, based on your operating system and printer interface. A table is located in the README to help you select the right one. + +The connectors are- + +- `FilePrintConnector` and `NetworkPrintConnector` directly use files or network sockets. +- `WindowsPrintConnector` and `CupsPrintConnector` tie in with Windows and Unix system printing. +- `DummyPrintConnector` does not connect to a real printer, and can be used to save ESC/POS receipts to a database, for example. + +At this point, you might find that the way you would like to print is not supported by escpos-php. You can post your printing command as a feature request on the issue tracker. + +Lastly, you may run in to the final common trap: + +4. Your PHP is not running with the same sort of permissions as your login account. Again, no amount of PHP code can fix this. For example, on LAMP, your `www-data` user needs to be in the `lp` group, while on WAMP, `Local Service` account may run in to problems. SELinux and firewalls are also worth a look. + +When printing fails, you can expect a PHP Exception that explains what went wrong. They are all clues: + +- `Warning: copy(\\pc\printer): failed to open stream: Permission denied` +- `/dev/usb/lp0: Permission denied` +- `User name or password is incorrect` + +Ensure that while you are developing, you configure PHP to show error messages, so that you can see these problems. + +Please file a bug if you think that there is a specific situation which escpos-php could provide better error messages for. + +## Can I print over the network? + +Certainly, as long as your printer is available over the network. + +- `NetworkPrintConnector` will speak directly to an Ethernet-connected printer on port 9100. + +For USB or Serial printers, you need to install the printer on a computer and then share it, so that it becomes network-accessible. + +- `WindowsPrintConnector` will connect to Windows shared printers from Windows or Linux (Linux users will need Samba). +- `CupsPrintConnector` will connect to CUPS-shared printers from Linux or Mac. + +Always start by testing your shared printer setup outside of escpos-php. The examples linked to in the README are commented with some example commands to get you started. Typically, networks, firewalls and permissions need to be set up. + +Once you have a working command to send text to your printer (from the PHP server), you are ready to use escpos-php. + +If you have any issues at this stage, please ask on the issue tracker, and include the commands that you used to verify your setup. + +## Can I print from my server on the Internet? + +Since PHP is a server-side language, escpos-php is a server-side print library. The driver is able to transport data between a server and a printer in a few different ways, all of them server-side. For example, you may print to a USB printer *connected to the server running PHP*, or an Ethernet printer *on a network accessible to the server*. + +Many developers dream of having an application that is hosted on the public Internet, with POS terminals accessing it, and printing via a web browser. Because the webserver cannot see the printer in this sort of setup, a server-side print driver is not much use. + +Because of this, there are no cut-and-paste recipes available, but here are two top-level approaches you could take: + +1. Architect your application so that the server can see your printer +2. Use an application which runs client-side to deliver print data instead + +### Option 1: Allow the server to print + +Server-side printing is viable if the server can get to the printer. Here are some ways it could work: + +- Run your server on the LAN instead, and read the section above about printing over the network +- Set up a VPN so that your cloud-hosted server can also access the LAN +- Expose the printer via some other secure tunnel to the server, via SSH or TLS + +Please do your own research to determine how these may apply to your setup- the escpos-php issue tracker is not a place where you should be requesting network support. + +### Option 2: Use client software to print + +If you aren't able to set up some network infrastructure to implement the above, then you cannot use a server-side print driver. + +Here are some browser-based printing tools which you may like to consider instead. + +- Use system printing with a vendor driver, and some good `@media print` CSS +- [Chrome Raw Print](https://github.com/receipt-print-hq/chrome-raw-print) app +- [qz](https://qz.io/) +- [ePOS-Device SDK for JavaScript](https://reference.epson-biz.com/modules/ref_epos_device_js_en/index.php?content_id=139). Requires network interface card that supports ePOS (UB-E04/R04) + +Please direct queries about client-side printing products to the appropriate project. + +## Why is image printing slow? + +Three things tend to slow down the image processing: + +1. Slow PHP code +2. Data link +3. The printer itself + +First, ensure you have the Imagick plugin loaded. The driver will avoid a slower image processing implementation once you've got it. + +Next, connect over a faster interface. Serial printers have a low bit-rate, and the printer spends a lot of time waiting for data. If you have USB or Ethernet, then use it (note: storing graphics to the printer memory is not currently implemented). + +Lastly, the printer will go faster if you use less pixels. Since images are two-dimensional, scaling down by 50% removes 75% of the pixels. The driver can then print at a half the density, so that your lower resolution image appears the same size when printed. + +## How can I get the status of the printer? + +This feature is not implemented, but a solution for some Epson printers is planned. + +Only `FilePrintConnector` or `NetworkPrintConnector` will support reading from the printer, ensure that you migrate to those if you would like these features. + +## How do I produce this complex layout? + +ESC/POS "page mode" is not currently supported, which would allow some printers to render some more complex layouts natively + +Since the output is raster anyway, it is suggested that you render your output to an image and print that instead. The driver supports PDF printing via Imagick, and an example that uses `wkhtmltoimage` is available in the repository. diff --git a/htdocs/includes/mike42/escpos-php/doc/Makefile b/htdocs/includes/mike42/escpos-php/doc/Makefile index fed323f0cff..4e01c2ac0a1 100644 --- a/htdocs/includes/mike42/escpos-php/doc/Makefile +++ b/htdocs/includes/mike42/escpos-php/doc/Makefile @@ -1,9 +1,20 @@ -html: ../Escpos.php escpos.conf - doxygen escpos.conf +html: escpos.doxyfile + # Compile + doxygen escpos.doxyfile + # Filter out warnings on README.md- doxygen cannot handle image links that + # are used there: [![Caption](https://example.com/target)](https://example.com/image) + sed -i '/README.md\:/d' warnings.log + # Show warnings log + cat warnings.log + # Return failure if there were any doc warnings + [ ! -s warnings.log ] latex: html # Do nothing -clean: - rm --preserve-root -Rf html latex doxygen_sqlite3.db +xml: html + xsltproc xml/combine.xslt xml/index.xml > all.xml + +clean: + rm --preserve-root -Rf html latex xml doxygen_sqlite3.db all.xml warnings.log diff --git a/htdocs/includes/mike42/escpos-php/doc/escpos.conf b/htdocs/includes/mike42/escpos-php/doc/escpos.doxyfile similarity index 99% rename from htdocs/includes/mike42/escpos-php/doc/escpos.conf rename to htdocs/includes/mike42/escpos-php/doc/escpos.doxyfile index 54ea2874aa5..0c48656e15b 100644 --- a/htdocs/includes/mike42/escpos-php/doc/escpos.conf +++ b/htdocs/includes/mike42/escpos-php/doc/escpos.doxyfile @@ -20,7 +20,7 @@ # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See https://www.gnu.org/software/libiconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. @@ -51,7 +51,7 @@ PROJECT_BRIEF = # and the maximum width should not exceed 200 pixels. Doxygen will copy the logo # to the output directory. -PROJECT_LOGO = ../example/images/escpos-php-small.png +PROJECT_LOGO = ../example/resources/escpos-php-small.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is @@ -741,7 +741,7 @@ WARN_FORMAT = "$file:$line: $text" # messages should be written. If left blank the output is written to standard # error (stderr). -WARN_LOGFILE = +WARN_LOGFILE = warnings.log #--------------------------------------------------------------------------- # Configuration options related to the input files @@ -753,12 +753,12 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = ../Escpos.php ../src/ ../README.md +INPUT = ../src ../README.md ./ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: https://www.gnu.org/software/libiconv) for the list of +# documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. @@ -773,13 +773,13 @@ INPUT_ENCODING = UTF-8 # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. -FILE_PATTERNS = +FILE_PATTERNS = *.php *.md # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. -RECURSIVE = NO +RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a @@ -950,7 +950,7 @@ SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system -# (see https://www.gnu.org/software/global/global.html). You will need version +# (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: @@ -1820,7 +1820,7 @@ MAN_LINKS = NO # captures the structure of the code including all documentation. # The default value is: NO. -GENERATE_XML = NO +GENERATE_XML = YES # The XML_OUTPUT tag is used to specify where the XML pages will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of diff --git a/htdocs/includes/mike42/escpos-php/example/README.md b/htdocs/includes/mike42/escpos-php/example/README.md index 68b0dc77e7c..e59e6c095e4 100644 --- a/htdocs/includes/mike42/escpos-php/example/README.md +++ b/htdocs/includes/mike42/escpos-php/example/README.md @@ -23,4 +23,4 @@ Each example prints to standard output, so either edit the print connector, or r - `print-from-html.php` - Runs `wkhtmltoimage` to convert HTML to an image, and then prints the image. (This is very slow) - `character-tables.php` - Prints a compact character code table for each available character set. Used to debug incorrect output from `character-encodings.php`. - `print-from-pdf.php` - Loads a PDF and prints each page in a few different ways (very slow as well) - +- `rawbt-receipt` (.php & .html) - Demonstration of Back and Front for integration between the site and the Android application “RawBT - Printer Driver for Android” diff --git a/htdocs/includes/mike42/escpos-php/example/barcode.php b/htdocs/includes/mike42/escpos-php/example/barcode.php index 5475b76c19d..d3ef9f2f44a 100644 --- a/htdocs/includes/mike42/escpos-php/example/barcode.php +++ b/htdocs/includes/mike42/escpos-php/example/barcode.php @@ -1,181 +1,207 @@ setBarcodeHeight ( 40 ); +require __DIR__ . '/../autoload.php'; +use Mike42\Escpos\Printer; +use Mike42\Escpos\PrintConnectors\FilePrintConnector; + +$connector = new FilePrintConnector("php://stdout"); +$printer = new Printer($connector); + +/* Height and width */ +$printer->selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); +$printer->text("Height and bar width\n"); +$printer->selectPrintMode(); +$heights = array(1, 2, 4, 8, 16, 32); +$widths = array(1, 2, 3, 4, 5, 6, 7, 8); +$printer -> text("Default look\n"); +$printer->barcode("ABC", Printer::BARCODE_CODE39); + +foreach($heights as $height) { + $printer -> text("\nHeight $height\n"); + $printer->setBarcodeHeight($height); + $printer->barcode("ABC", Printer::BARCODE_CODE39); +} +foreach($widths as $width) { + $printer -> text("\nWidth $width\n"); + $printer->setBarcodeWidth($width); + $printer->barcode("ABC", Printer::BARCODE_CODE39); +} +$printer->feed(); +// Set to something sensible for the rest of the examples +$printer->setBarcodeHeight(40); +$printer->setBarcodeWidth(2); /* Text position */ -$printer->selectPrintMode ( Escpos::MODE_DOUBLE_HEIGHT | Escpos::MODE_DOUBLE_WIDTH ); -$printer->text ( "Text position\n" ); -$printer->selectPrintMode (); +$printer->selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); +$printer->text("Text position\n"); +$printer->selectPrintMode(); $hri = array ( - Escpos::BARCODE_TEXT_NONE => "No text", - Escpos::BARCODE_TEXT_ABOVE => "Above", - Escpos::BARCODE_TEXT_BELOW => "Below", - Escpos::BARCODE_TEXT_ABOVE | Escpos::BARCODE_TEXT_BELOW => "Both" + Printer::BARCODE_TEXT_NONE => "No text", + Printer::BARCODE_TEXT_ABOVE => "Above", + Printer::BARCODE_TEXT_BELOW => "Below", + Printer::BARCODE_TEXT_ABOVE | Printer::BARCODE_TEXT_BELOW => "Both" ); -foreach ( $hri as $position => $caption ) { - $printer->text ( $caption . "\n" ); - $printer->setBarcodeTextPosition ( $position ); - $printer->barcode ( "012345678901", Escpos::BARCODE_JAN13 ); - $printer->feed (); +foreach ($hri as $position => $caption) { + $printer->text($caption . "\n"); + $printer->setBarcodeTextPosition($position); + $printer->barcode("012345678901", Printer::BARCODE_JAN13); + $printer->feed(); } /* Barcode types */ $standards = array ( - Escpos::BARCODE_UPCA => array ( - "title" => "UPC-A", - "caption" => "Fixed-length numeric product barcodes.", - "example" => array ( - array ( - "caption" => "12 char numeric including (wrong) check digit.", - "content" => "012345678901" - ), - array ( - "caption" => "Send 11 chars to add check digit automatically.", - "content" => "01234567890" - ) - ) - ), - Escpos::BARCODE_UPCE => array ( - "title" => "UPC-E", - "caption" => "Fixed-length numeric compact product barcodes.", - "example" => array ( - array ( - "caption" => "6 char numeric - auto check digit & NSC", - "content" => "123456" - ), - array ( - "caption" => "7 char numeric - auto check digit", - "content" => "0123456" - ), - array ( - "caption" => "8 char numeric", - "content" => "01234567" - ), - array ( - "caption" => "11 char numeric - auto check digit", - "content" => "01234567890" - ), - array ( - "caption" => "12 char numeric including (wrong) check digit", - "content" => "012345678901" - ) - ) - ), - Escpos::BARCODE_JAN13 => array ( - "title" => "JAN13/EAN13", - "caption" => "Fixed-length numeric barcodes.", - "example" => array ( - array ( - "caption" => "12 char numeric - auto check digit", - "content" => "012345678901" - ), - array ( - "caption" => "13 char numeric including (wrong) check digit", - "content" => "0123456789012" - ) - ) - ), - Escpos::BARCODE_JAN8 => array ( - "title" => "JAN8/EAN8", - "caption" => "Fixed-length numeric barcodes.", - "example" => array ( - array ( - "caption" => "7 char numeric - auto check digit", - "content" => "0123456" - ), - array ( - "caption" => "8 char numeric including (wrong) check digit", - "content" => "01234567" - ) - ) - ), - Escpos::BARCODE_CODE39 => array ( - "title" => "Code39", - "caption" => "Variable length alphanumeric w/ some special chars.", - "example" => array ( - array ( - "caption" => "Text, numbers, spaces", - "content" => "ABC 012" - ), - array ( - "caption" => "Special characters", - "content" => "$%+-./" - ), - array ( - "caption" => "Extra char (*) Used as start/stop", - "content" => "*TEXT*" - ) - ) - ), - Escpos::BARCODE_ITF => array ( - "title" => "ITF", - "caption" => "Variable length numeric w/even number of digits,\nas they are encoded in pairs.", - "example" => array ( - array ( - "caption" => "Numeric- even number of digits", - "content" => "0123456789" - ) - ) - ), - Escpos::BARCODE_CODABAR => array ( - "title" => "Codabar", - "caption" => "Varaible length numeric with some allowable\nextra characters. ABCD/abcd must be used as\nstart/stop characters (one at the start, one\nat the end) to distinguish between barcode\napplications.", - "example" => array ( - array ( - "caption" => "Numeric w/ A A start/stop. ", - "content" => "A012345A" - ), - array ( - "caption" => "Extra allowable characters", - "content" => "A012$+-./:A" - ) - ) - ), - Escpos::BARCODE_CODE93 => array ( - "title" => "Code93", - "caption" => "Variable length- any ASCII is available", - "example" => array ( - array ( - "caption" => "Text", - "content" => "012abcd" - ) - ) - ), - Escpos::BARCODE_CODE128 => array ( - "title" => "Code128", - "caption" => "Variable length- any ASCII is available", - "example" => array ( - array ( - "caption" => "Code set A uppercase & symbols", - "content" => "{A" . "012ABCD" - ), - array ( - "caption" => "Code set B general text", - "content" => "{B" . "012ABCDabcd" - ), - array ( - "caption" => "Code set C compact numbers\n Sending chr(21) chr(32) chr(43)", - "content" => "{C" . chr ( 21 ) . chr ( 32 ) . chr ( 43 ) - ) - ) - ) + Printer::BARCODE_UPCA => array ( + "title" => "UPC-A", + "caption" => "Fixed-length numeric product barcodes.", + "example" => array ( + array ( + "caption" => "12 char numeric including (wrong) check digit.", + "content" => "012345678901" + ), + array ( + "caption" => "Send 11 chars to add check digit automatically.", + "content" => "01234567890" + ) + ) + ), + Printer::BARCODE_UPCE => array ( + "title" => "UPC-E", + "caption" => "Fixed-length numeric compact product barcodes.", + "example" => array ( + array ( + "caption" => "6 char numeric - auto check digit & NSC", + "content" => "123456" + ), + array ( + "caption" => "7 char numeric - auto check digit", + "content" => "0123456" + ), + array ( + "caption" => "8 char numeric", + "content" => "01234567" + ), + array ( + "caption" => "11 char numeric - auto check digit", + "content" => "01234567890" + ), + array ( + "caption" => "12 char numeric including (wrong) check digit", + "content" => "012345678901" + ) + ) + ), + Printer::BARCODE_JAN13 => array ( + "title" => "JAN13/EAN13", + "caption" => "Fixed-length numeric barcodes.", + "example" => array ( + array ( + "caption" => "12 char numeric - auto check digit", + "content" => "012345678901" + ), + array ( + "caption" => "13 char numeric including (wrong) check digit", + "content" => "0123456789012" + ) + ) + ), + Printer::BARCODE_JAN8 => array ( + "title" => "JAN8/EAN8", + "caption" => "Fixed-length numeric barcodes.", + "example" => array ( + array ( + "caption" => "7 char numeric - auto check digit", + "content" => "0123456" + ), + array ( + "caption" => "8 char numeric including (wrong) check digit", + "content" => "01234567" + ) + ) + ), + Printer::BARCODE_CODE39 => array ( + "title" => "Code39", + "caption" => "Variable length alphanumeric w/ some special chars.", + "example" => array ( + array ( + "caption" => "Text, numbers, spaces", + "content" => "ABC 012" + ), + array ( + "caption" => "Special characters", + "content" => "$%+-./" + ), + array ( + "caption" => "Extra char (*) Used as start/stop", + "content" => "*TEXT*" + ) + ) + ), + Printer::BARCODE_ITF => array ( + "title" => "ITF", + "caption" => "Variable length numeric w/even number of digits,\nas they are encoded in pairs.", + "example" => array ( + array ( + "caption" => "Numeric- even number of digits", + "content" => "0123456789" + ) + ) + ), + Printer::BARCODE_CODABAR => array ( + "title" => "Codabar", + "caption" => "Varaible length numeric with some allowable\nextra characters. ABCD/abcd must be used as\nstart/stop characters (one at the start, one\nat the end) to distinguish between barcode\napplications.", + "example" => array ( + array ( + "caption" => "Numeric w/ A A start/stop. ", + "content" => "A012345A" + ), + array ( + "caption" => "Extra allowable characters", + "content" => "A012$+-./:A" + ) + ) + ), + Printer::BARCODE_CODE93 => array ( + "title" => "Code93", + "caption" => "Variable length- any ASCII is available", + "example" => array ( + array ( + "caption" => "Text", + "content" => "012abcd" + ) + ) + ), + Printer::BARCODE_CODE128 => array ( + "title" => "Code128", + "caption" => "Variable length- any ASCII is available", + "example" => array ( + array ( + "caption" => "Code set A uppercase & symbols", + "content" => "{A" . "012ABCD" + ), + array ( + "caption" => "Code set B general text", + "content" => "{B" . "012ABCDabcd" + ), + array ( + "caption" => "Code set C compact numbers\n Sending chr(21) chr(32) chr(43)", + "content" => "{C" . chr(21) . chr(32) . chr(43) + ) + ) + ) ); -$printer->setBarcodeTextPosition ( Escpos::BARCODE_TEXT_BELOW ); -foreach ( $standards as $type => $standard ) { - $printer->selectPrintMode ( Escpos::MODE_DOUBLE_HEIGHT | Escpos::MODE_DOUBLE_WIDTH ); - $printer->text ( $standard ["title"] . "\n" ); - $printer->selectPrintMode (); - $printer->text ( $standard ["caption"] . "\n\n" ); - foreach ( $standard ["example"] as $id => $barcode ) { - $printer->setEmphasis ( true ); - $printer->text ( $barcode ["caption"] . "\n" ); - $printer->setEmphasis ( false ); - $printer->text ( "Content: " . $barcode ["content"] . "\n" ); - $printer->barcode ( $barcode ["content"], $type ); - $printer->feed (); - } +$printer->setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW); +foreach ($standards as $type => $standard) { + $printer->selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); + $printer->text($standard ["title"] . "\n"); + $printer->selectPrintMode(); + $printer->text($standard ["caption"] . "\n\n"); + foreach ($standard ["example"] as $id => $barcode) { + $printer->setEmphasis(true); + $printer->text($barcode ["caption"] . "\n"); + $printer->setEmphasis(false); + $printer->text("Content: " . $barcode ["content"] . "\n"); + $printer->barcode($barcode ["content"], $type); + $printer->feed(); + } } -$printer->cut (); -$printer->close (); - +$printer->cut(); +$printer->close(); diff --git a/htdocs/includes/mike42/escpos-php/example/bit-image.php b/htdocs/includes/mike42/escpos-php/example/bit-image.php index f3a4054d98f..befebf80b9f 100644 --- a/htdocs/includes/mike42/escpos-php/example/bit-image.php +++ b/htdocs/includes/mike42/escpos-php/example/bit-image.php @@ -1,32 +1,36 @@ text("These example images are printed with the older\nbit image print command. You should only use\n\$p -> bitImage() if \$p -> graphics() does not\nwork on your printer.\n\n"); - - $printer -> bitImage($tux); - $printer -> text("Regular Tux (bit image).\n"); - $printer -> feed(); - - $printer -> bitImage($tux, Escpos::IMG_DOUBLE_WIDTH); - $printer -> text("Wide Tux (bit image).\n"); - $printer -> feed(); - - $printer -> bitImage($tux, Escpos::IMG_DOUBLE_HEIGHT); - $printer -> text("Tall Tux (bit image).\n"); - $printer -> feed(); - - $printer -> bitImage($tux, Escpos::IMG_DOUBLE_WIDTH | Escpos::IMG_DOUBLE_HEIGHT); - $printer -> text("Large Tux in correct proportion (bit image).\n"); -} catch(Exception $e) { - /* Images not supported on your PHP, or image file not found */ - $printer -> text($e -> getMessage() . "\n"); + $printer -> text("These example images are printed with the older\nbit image print command. You should only use\n\$p -> bitImage() if \$p -> graphics() does not\nwork on your printer.\n\n"); + + $printer -> bitImage($tux); + $printer -> text("Regular Tux (bit image).\n"); + $printer -> feed(); + + $printer -> bitImage($tux, Printer::IMG_DOUBLE_WIDTH); + $printer -> text("Wide Tux (bit image).\n"); + $printer -> feed(); + + $printer -> bitImage($tux, Printer::IMG_DOUBLE_HEIGHT); + $printer -> text("Tall Tux (bit image).\n"); + $printer -> feed(); + + $printer -> bitImage($tux, Printer::IMG_DOUBLE_WIDTH | Printer::IMG_DOUBLE_HEIGHT); + $printer -> text("Large Tux in correct proportion (bit image).\n"); +} catch (Exception $e) { + /* Images not supported on your PHP, or image file not found */ + $printer -> text($e -> getMessage() . "\n"); } $printer -> cut(); $printer -> close(); -?> diff --git a/htdocs/includes/mike42/escpos-php/example/character-encodings-with-images.php b/htdocs/includes/mike42/escpos-php/example/character-encodings-with-images.php index a98bdbc96ae..bc99c2f1872 100644 --- a/htdocs/includes/mike42/escpos-php/example/character-encodings-with-images.php +++ b/htdocs/includes/mike42/escpos-php/example/character-encodings-with-images.php @@ -1,12 +1,17 @@ selectPrintMode(Escpos::MODE_DOUBLE_HEIGHT | Escpos::MODE_EMPHASIZED | Escpos::MODE_DOUBLE_WIDTH); - $printer -> text("Implemented languages\n"); - $printer -> selectPrintMode(); - foreach($inputsOk as $label => $str) { - $printer -> setEmphasis(true); - $printer -> text($label . ":\n"); - $printer -> setEmphasis(false); - foreach($buffers as $buffer) { - $printer -> setPrintBuffer($buffer); - $printer -> text($str); - } - $printer -> setPrintBuffer($buffers[0]); - } - $printer -> feed(); - - $printer -> selectPrintMode(Escpos::MODE_DOUBLE_HEIGHT | Escpos::MODE_EMPHASIZED | Escpos::MODE_DOUBLE_WIDTH); - $printer -> text("Works in progress\n"); - $printer -> selectPrintMode(); - foreach($inputsNotOk as $label => $str) { - $printer -> setEmphasis(true); - $printer -> text($label . ":\n"); - $printer -> setEmphasis(false); - foreach($buffers as $buffer) { - $printer -> setPrintBuffer($buffer); - $printer -> text($str); - } - $printer -> setPrintBuffer($buffers[0]); - } - $printer -> cut(); + /* Print a series of receipts containing i18n example strings */ + $printer = new Printer($connector, $profile); + $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_EMPHASIZED | Printer::MODE_DOUBLE_WIDTH); + $printer -> text("Implemented languages\n"); + $printer -> selectPrintMode(); + foreach ($inputsOk as $label => $str) { + $printer -> setEmphasis(true); + $printer -> text($label . ":\n"); + $printer -> setEmphasis(false); + foreach ($buffers as $buffer) { + $printer -> setPrintBuffer($buffer); + $printer -> text($str); + } + $printer -> setPrintBuffer($buffers[0]); + } + $printer -> feed(); + + $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_EMPHASIZED | Printer::MODE_DOUBLE_WIDTH); + $printer -> text("Works in progress\n"); + $printer -> selectPrintMode(); + foreach ($inputsNotOk as $label => $str) { + $printer -> setEmphasis(true); + $printer -> text($label . ":\n"); + $printer -> setEmphasis(false); + foreach ($buffers as $buffer) { + $printer -> setPrintBuffer($buffer); + $printer -> text($str); + } + $printer -> setPrintBuffer($buffers[0]); + } + $printer -> cut(); - /* Close printer */ - $printer -> close(); -} catch(Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; + /* Close printer */ + $printer -> close(); +} catch (Exception $e) { + echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; } - diff --git a/htdocs/includes/mike42/escpos-php/example/character-encodings.php b/htdocs/includes/mike42/escpos-php/example/character-encodings.php index 8a42ecd0847..a38e99fb9ea 100644 --- a/htdocs/includes/mike42/escpos-php/example/character-encodings.php +++ b/htdocs/includes/mike42/escpos-php/example/character-encodings.php @@ -1,58 +1,60 @@ selectPrintMode(Escpos::MODE_DOUBLE_HEIGHT | Escpos::MODE_EMPHASIZED | Escpos::MODE_DOUBLE_WIDTH); - $printer -> text("Implemented languages\n"); - $printer -> selectPrintMode(); - foreach($inputsOk as $label => $str) { - $printer -> setEmphasis(true); - $printer -> text($label . ":\n"); - $printer -> setEmphasis(false); - $printer -> text($str); - } - $printer -> feed(); - - $printer -> selectPrintMode(Escpos::MODE_DOUBLE_HEIGHT | Escpos::MODE_EMPHASIZED | Escpos::MODE_DOUBLE_WIDTH); - $printer -> text("Works in progress\n"); - $printer -> selectPrintMode(); - foreach($inputsNotOk as $label => $str) { - $printer -> setEmphasis(true); - $printer -> text($label . ":\n"); - $printer -> setEmphasis(false); - $printer -> text($str); - } - $printer -> cut(); + // Enter connector and capability profile (to match your printer) + $connector = new FilePrintConnector("php://stdout"); + $profile = CapabilityProfile::load("default"); + + /* Print a series of receipts containing i18n example strings */ + $printer = new Printer($connector, $profile); + $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_EMPHASIZED | Printer::MODE_DOUBLE_WIDTH); + $printer -> text("Implemented languages\n"); + $printer -> selectPrintMode(); + foreach ($inputsOk as $label => $str) { + $printer -> setEmphasis(true); + $printer -> text($label . ":\n"); + $printer -> setEmphasis(false); + $printer -> text($str); + } + $printer -> feed(); + + $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_EMPHASIZED | Printer::MODE_DOUBLE_WIDTH); + $printer -> text("Works in progress\n"); + $printer -> selectPrintMode(); + foreach ($inputsNotOk as $label => $str) { + $printer -> setEmphasis(true); + $printer -> text($label . ":\n"); + $printer -> setEmphasis(false); + $printer -> text($str); + } + $printer -> cut(); - /* Close printer */ - $printer -> close(); -} catch(Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; + /* Close printer */ + $printer -> close(); +} catch (Exception $e) { + echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; } - diff --git a/htdocs/includes/mike42/escpos-php/example/character-tables.php b/htdocs/includes/mike42/escpos-php/example/character-tables.php index 1ce2c5c9f1e..d2ab8bbcfa1 100644 --- a/htdocs/includes/mike42/escpos-php/example/character-tables.php +++ b/htdocs/includes/mike42/escpos-php/example/character-tables.php @@ -4,68 +4,72 @@ * for debugging character-encoding issues: If your printer does not work with * a built-in capability profile, you need to check its documentation for * supported code pages. - * + * * These are then loaded into a capability profile, which maps code page * numbers to iconv encoding names on your particular printer. This script * will print all configured code pages, so that you can check that the chosen * iconv encoding name matches the actual code page contents. - * + * * If this is correctly set up for your printer, then the driver will try its * best to map UTF-8 text into these code pages for you, allowing you to accept * arbitrary input from a database, without worrying about encoding it for the printer. */ -require_once(dirname(__FILE__) . "/../Escpos.php"); +require __DIR__ . '/../autoload.php'; +use Mike42\Escpos\Printer; +use Mike42\Escpos\PrintConnectors\FilePrintConnector; +use Mike42\Escpos\CapabilityProfile; // Enter connector and capability profile (to match your printer) $connector = new FilePrintConnector("php://stdout"); -$profile = DefaultCapabilityProfile::getInstance(); +$profile = CapabilityProfile::load("default"); $verbose = false; // Skip tables which iconv wont convert to (ie, only print characters available with UTF-8 input) /* Print a series of receipts containing i18n example strings - Code below shouldn't need changing */ -$printer = new Escpos($connector, $profile); -$codePages = $profile -> getSupportedCodePages(); +$printer = new Mike42\Escpos\Printer($connector, $profile); +$codePages = $profile -> getCodePages(); $first = true; // Print larger table for first code-page. -foreach($codePages as $table => $name) { - /* Change printer code page */ - $printer -> selectCharacterTable(255); - $printer -> selectCharacterTable($table); - /* Select & print a label for it */ - $label = $name; - if($name === false) { - $label= " (not matched to iconv table)"; - } - $printer -> setEmphasis(true); - $printer -> textRaw("Table $table: $label\n"); - $printer -> setEmphasis(false); - if($name === false && !$verbose) { - continue; // Skip non-recognised - } - /* Print a table of available characters (first table is larger than subsequent ones */ - if($first) { - $first = false; - compactCharTable($printer, 1, true); - } else { - compactCharTable($printer); - } +foreach ($codePages as $table => $page) { + /* Change printer code page */ + $printer -> selectCharacterTable(255); + $printer -> selectCharacterTable($table); + /* Select & print a label for it */ + $label = $page -> getId(); + if (!$page -> isEncodable()) { + $label= " (not supported)"; + } + $printer -> setEmphasis(true); + $printer -> textRaw("Table $table: $label\n"); + $printer -> setEmphasis(false); + if (!$page -> isEncodable() && !$verbose) { + continue; // Skip non-recognised + } + /* Print a table of available characters (first table is larger than subsequent ones */ + if ($first) { + $first = false; + compactCharTable($printer, 1, true); + } else { + compactCharTable($printer); + } } $printer -> cut(); $printer -> close(); -function compactCharTable($printer, $start = 4, $header = false) { - /* Output a compact character table for the current encoding */ - $chars = str_repeat(' ', 256); - for($i = 0; $i < 255; $i++) { - $chars[$i] = ($i > 32 && $i != 127) ? chr($i) : ' '; - } - if($header) { - $printer -> setEmphasis(true); - $printer -> textRaw(" 0123456789ABCDEF0123456789ABCDEF\n"); - $printer -> setEmphasis(false); - } - for($y = $start; $y < 8; $y++) { - $printer -> setEmphasis(true); - $printer -> textRaw(strtoupper(dechex($y * 2)) . " "); - $printer -> setEmphasis(false); - $printer -> textRaw(substr($chars, $y * 32, 32) . "\n"); - } +function compactCharTable($printer, $start = 4, $header = false) +{ + /* Output a compact character table for the current encoding */ + $chars = str_repeat(' ', 256); + for ($i = 0; $i < 255; $i++) { + $chars[$i] = ($i > 32 && $i != 127) ? chr($i) : ' '; + } + if ($header) { + $printer -> setEmphasis(true); + $printer -> textRaw(" 0123456789ABCDEF0123456789ABCDEF\n"); + $printer -> setEmphasis(false); + } + for ($y = $start; $y < 8; $y++) { + $printer -> setEmphasis(true); + $printer -> textRaw(strtoupper(dechex($y * 2)) . " "); + $printer -> setEmphasis(false); + $printer -> textRaw(substr($chars, $y * 32, 32) . "\n"); + } } diff --git a/htdocs/includes/mike42/escpos-php/example/customer-display.php b/htdocs/includes/mike42/escpos-php/example/customer-display.php new file mode 100644 index 00000000000..47947789540 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/customer-display.php @@ -0,0 +1,51 @@ + feed(); + $display -> text($line); + usleep(500000); +} + +// Finish by showing "Hello World" +$display -> clear(); +$display -> text("Hello World\n"); + +// Dont forget to close the device +$display -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/demo.php b/htdocs/includes/mike42/escpos-php/example/demo.php index 1c99e5cc880..f0e357ed431 100644 --- a/htdocs/includes/mike42/escpos-php/example/demo.php +++ b/htdocs/includes/mike42/escpos-php/example/demo.php @@ -8,8 +8,13 @@ * * @author Michael Billington */ -require_once(dirname(__FILE__) . "/../Escpos.php"); -$printer = new Escpos(); +require __DIR__ . '/../autoload.php'; +use Mike42\Escpos\Printer; +use Mike42\Escpos\PrintConnectors\FilePrintConnector; +use Mike42\Escpos\EscposImage; + +$connector = new FilePrintConnector("php://stdout"); +$printer = new Printer($connector); /* Initialize */ $printer -> initialize(); @@ -29,132 +34,132 @@ $printer -> cut(); /* Font modes */ $modes = array( - Escpos::MODE_FONT_B, - Escpos::MODE_EMPHASIZED, - Escpos::MODE_DOUBLE_HEIGHT, - Escpos::MODE_DOUBLE_WIDTH, - Escpos::MODE_UNDERLINE); -for($i = 0; $i < pow(2, count($modes)); $i++) { - $bits = str_pad(decbin($i), count($modes), "0", STR_PAD_LEFT); - $mode = 0; - for($j = 0; $j < strlen($bits); $j++) { - if(substr($bits, $j, 1) == "1") { - $mode |= $modes[$j]; - } - } - $printer -> selectPrintMode($mode); - $printer -> text("ABCDEFGHIJabcdefghijk\n"); + Printer::MODE_FONT_B, + Printer::MODE_EMPHASIZED, + Printer::MODE_DOUBLE_HEIGHT, + Printer::MODE_DOUBLE_WIDTH, + Printer::MODE_UNDERLINE); +for ($i = 0; $i < pow(2, count($modes)); $i++) { + $bits = str_pad(decbin($i), count($modes), "0", STR_PAD_LEFT); + $mode = 0; + for ($j = 0; $j < strlen($bits); $j++) { + if (substr($bits, $j, 1) == "1") { + $mode |= $modes[$j]; + } + } + $printer -> selectPrintMode($mode); + $printer -> text("ABCDEFGHIJabcdefghijk\n"); } $printer -> selectPrintMode(); // Reset $printer -> cut(); /* Underline */ -for($i = 0; $i < 3; $i++) { - $printer -> setUnderline($i); - $printer -> text("The quick brown fox jumps over the lazy dog\n"); +for ($i = 0; $i < 3; $i++) { + $printer -> setUnderline($i); + $printer -> text("The quick brown fox jumps over the lazy dog\n"); } $printer -> setUnderline(0); // Reset $printer -> cut(); /* Cuts */ $printer -> text("Partial cut\n(not available on all printers)\n"); -$printer -> cut(Escpos::CUT_PARTIAL); +$printer -> cut(Printer::CUT_PARTIAL); $printer -> text("Full cut\n"); -$printer -> cut(Escpos::CUT_FULL); +$printer -> cut(Printer::CUT_FULL); /* Emphasis */ -for($i = 0; $i < 2; $i++) { - $printer -> setEmphasis($i == 1); - $printer -> text("The quick brown fox jumps over the lazy dog\n"); +for ($i = 0; $i < 2; $i++) { + $printer -> setEmphasis($i == 1); + $printer -> text("The quick brown fox jumps over the lazy dog\n"); } $printer -> setEmphasis(false); // Reset $printer -> cut(); /* Double-strike (looks basically the same as emphasis) */ -for($i = 0; $i < 2; $i++) { - $printer -> setDoubleStrike($i == 1); - $printer -> text("The quick brown fox jumps over the lazy dog\n"); +for ($i = 0; $i < 2; $i++) { + $printer -> setDoubleStrike($i == 1); + $printer -> text("The quick brown fox jumps over the lazy dog\n"); } $printer -> setDoubleStrike(false); $printer -> cut(); /* Fonts (many printers do not have a 'Font C') */ $fonts = array( - Escpos::FONT_A, - Escpos::FONT_B, - Escpos::FONT_C); -for($i = 0; $i < count($fonts); $i++) { - $printer -> setFont($fonts[$i]); - $printer -> text("The quick brown fox jumps over the lazy dog\n"); + Printer::FONT_A, + Printer::FONT_B, + Printer::FONT_C); +for ($i = 0; $i < count($fonts); $i++) { + $printer -> setFont($fonts[$i]); + $printer -> text("The quick brown fox jumps over the lazy dog\n"); } $printer -> setFont(); // Reset $printer -> cut(); /* Justification */ $justification = array( - Escpos::JUSTIFY_LEFT, - Escpos::JUSTIFY_CENTER, - Escpos::JUSTIFY_RIGHT); -for($i = 0; $i < count($justification); $i++) { - $printer -> setJustification($justification[$i]); - $printer -> text("A man a plan a canal panama\n"); + Printer::JUSTIFY_LEFT, + Printer::JUSTIFY_CENTER, + Printer::JUSTIFY_RIGHT); +for ($i = 0; $i < count($justification); $i++) { + $printer -> setJustification($justification[$i]); + $printer -> text("A man a plan a canal panama\n"); } $printer -> setJustification(); // Reset $printer -> cut(); /* Barcodes - see barcode.php for more detail */ $printer -> setBarcodeHeight(80); -$printer->setBarcodeTextPosition ( Escpos::BARCODE_TEXT_BELOW ); +$printer->setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW); $printer -> barcode("9876"); $printer -> feed(); $printer -> cut(); /* Graphics - this demo will not work on some non-Epson printers */ try { - $logo = new EscposImage("resources/escpos-php.png"); - $imgModes = array( - Escpos::IMG_DEFAULT, - Escpos::IMG_DOUBLE_WIDTH, - Escpos::IMG_DOUBLE_HEIGHT, - Escpos::IMG_DOUBLE_WIDTH | Escpos::IMG_DOUBLE_HEIGHT - ); - foreach($imgModes as $mode) { - $printer -> graphics($logo, $mode); - } -} catch(Exception $e) { - /* Images not supported on your PHP, or image file not found */ - $printer -> text($e -> getMessage() . "\n"); + $logo = EscposImage::load("resources/escpos-php.png", false); + $imgModes = array( + Printer::IMG_DEFAULT, + Printer::IMG_DOUBLE_WIDTH, + Printer::IMG_DOUBLE_HEIGHT, + Printer::IMG_DOUBLE_WIDTH | Printer::IMG_DOUBLE_HEIGHT + ); + foreach ($imgModes as $mode) { + $printer -> graphics($logo, $mode); + } +} catch (Exception $e) { + /* Images not supported on your PHP, or image file not found */ + $printer -> text($e -> getMessage() . "\n"); } $printer -> cut(); /* Bit image */ try { - $logo = new EscposImage("resources/escpos-php.png"); - $imgModes = array( - Escpos::IMG_DEFAULT, - Escpos::IMG_DOUBLE_WIDTH, - Escpos::IMG_DOUBLE_HEIGHT, - Escpos::IMG_DOUBLE_WIDTH | Escpos::IMG_DOUBLE_HEIGHT - ); - foreach($imgModes as $mode) { - $printer -> bitImage($logo, $mode); - } -} catch(Exception $e) { - /* Images not supported on your PHP, or image file not found */ - $printer -> text($e -> getMessage() . "\n"); + $logo = EscposImage::load("resources/escpos-php.png", false); + $imgModes = array( + Printer::IMG_DEFAULT, + Printer::IMG_DOUBLE_WIDTH, + Printer::IMG_DOUBLE_HEIGHT, + Printer::IMG_DOUBLE_WIDTH | Printer::IMG_DOUBLE_HEIGHT + ); + foreach ($imgModes as $mode) { + $printer -> bitImage($logo, $mode); + } +} catch (Exception $e) { + /* Images not supported on your PHP, or image file not found */ + $printer -> text($e -> getMessage() . "\n"); } $printer -> cut(); /* QR Code - see also the more in-depth demo at qr-code.php */ $testStr = "Testing 123"; $models = array( - Escpos::QR_MODEL_1 => "QR Model 1", - Escpos::QR_MODEL_2 => "QR Model 2 (default)", - Escpos::QR_MICRO => "Micro QR code\n(not supported on all printers)"); -foreach($models as $model => $name) { - $printer -> qrCode($testStr, Escpos::QR_ECLEVEL_L, 3, $model); - $printer -> text("$name\n"); - $printer -> feed(); + Printer::QR_MODEL_1 => "QR Model 1", + Printer::QR_MODEL_2 => "QR Model 2 (default)", + Printer::QR_MICRO => "Micro QR code\n(not supported on all printers)"); +foreach ($models as $model => $name) { + $printer -> qrCode($testStr, Printer::QR_ECLEVEL_L, 3, $model); + $printer -> text("$name\n"); + $printer -> feed(); } $printer -> cut(); @@ -164,4 +169,3 @@ $printer -> pulse(); /* Always close the printer! On some PrintConnectors, no actual * data is sent until the printer is closed. */ $printer -> close(); -?> diff --git a/htdocs/includes/mike42/escpos-php/example/graphics.php b/htdocs/includes/mike42/escpos-php/example/graphics.php index 7650b6b9a08..49b02b9b0d9 100644 --- a/htdocs/includes/mike42/escpos-php/example/graphics.php +++ b/htdocs/includes/mike42/escpos-php/example/graphics.php @@ -1,32 +1,36 @@ graphics($tux); - $printer -> text("Regular Tux.\n"); - $printer -> feed(); - - $printer -> graphics($tux, Escpos::IMG_DOUBLE_WIDTH); - $printer -> text("Wide Tux.\n"); - $printer -> feed(); - - $printer -> graphics($tux, Escpos::IMG_DOUBLE_HEIGHT); - $printer -> text("Tall Tux.\n"); - $printer -> feed(); - - $printer -> graphics($tux, Escpos::IMG_DOUBLE_WIDTH | Escpos::IMG_DOUBLE_HEIGHT); - $printer -> text("Large Tux in correct proportion.\n"); - - $printer -> cut(); -} catch(Exception $e) { - /* Images not supported on your PHP, or image file not found */ - $printer -> text($e -> getMessage() . "\n"); + $tux = EscposImage::load("resources/tux.png", false); + + $printer -> graphics($tux); + $printer -> text("Regular Tux.\n"); + $printer -> feed(); + + $printer -> graphics($tux, Printer::IMG_DOUBLE_WIDTH); + $printer -> text("Wide Tux.\n"); + $printer -> feed(); + + $printer -> graphics($tux, Printer::IMG_DOUBLE_HEIGHT); + $printer -> text("Tall Tux.\n"); + $printer -> feed(); + + $printer -> graphics($tux, Printer::IMG_DOUBLE_WIDTH | Printer::IMG_DOUBLE_HEIGHT); + $printer -> text("Large Tux in correct proportion.\n"); + + $printer -> cut(); +} catch (Exception $e) { + /* Images not supported on your PHP, or image file not found */ + $printer -> text($e -> getMessage() . "\n"); } $printer -> close(); -?> diff --git a/htdocs/includes/mike42/escpos-php/example/interface/cups.php b/htdocs/includes/mike42/escpos-php/example/interface/cups.php new file mode 100644 index 00000000000..8b65ab3d4d9 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/interface/cups.php @@ -0,0 +1,19 @@ + text("Hello World!\n"); + $printer -> cut(); + + /* Close printer */ + $printer -> close(); +} catch (Exception $e) { + echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; +} diff --git a/htdocs/includes/mike42/escpos-php/example/interface/ethernet.php b/htdocs/includes/mike42/escpos-php/example/interface/ethernet.php index bfea443903c..129af5ce3aa 100644 --- a/htdocs/includes/mike42/escpos-php/example/interface/ethernet.php +++ b/htdocs/includes/mike42/escpos-php/example/interface/ethernet.php @@ -1,22 +1,22 @@ text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch(Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; + $connector = new NetworkPrintConnector("10.x.x.x", 9100); + + /* Print a "Hello world" receipt" */ + $printer = new Printer($connector); + $printer -> text("Hello World!\n"); + $printer -> cut(); + + /* Close printer */ + $printer -> close(); +} catch (Exception $e) { + echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; } - diff --git a/htdocs/includes/mike42/escpos-php/example/interface/linux-usb.php b/htdocs/includes/mike42/escpos-php/example/interface/linux-usb.php index 9e1d96b91c0..2b390f658b2 100644 --- a/htdocs/includes/mike42/escpos-php/example/interface/linux-usb.php +++ b/htdocs/includes/mike42/escpos-php/example/interface/linux-usb.php @@ -1,6 +1,8 @@ text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch(Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; + /* Print a "Hello world" receipt" */ + $printer = new Printer($connector); + $printer -> text("Hello World!\n"); + $printer -> cut(); + + /* Close printer */ + $printer -> close(); +} catch (Exception $e) { + echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; } - diff --git a/htdocs/includes/mike42/escpos-php/example/interface/smb.php b/htdocs/includes/mike42/escpos-php/example/interface/smb.php index 40988f553ee..fac54b342d1 100644 --- a/htdocs/includes/mike42/escpos-php/example/interface/smb.php +++ b/htdocs/includes/mike42/escpos-php/example/interface/smb.php @@ -1,51 +1,52 @@ testfile + * echo "Hello World" > testfile * ## If you need authentication, use "net use" to hook up the printer: - * # net use "\\computername\Receipt Printer" /user:Guest - * # net use "\\computername\Receipt Printer" /user:Bob secret - * # net use "\\computername\Receipt Printer" /user:workgroup\Bob secret - * copy testfile "\\computername\Receipt Printer" - * del testfile - * + * # net use "\\computername\Receipt Printer" /user:Guest + * # net use "\\computername\Receipt Printer" /user:Bob secret + * # net use "\\computername\Receipt Printer" /user:workgroup\Bob secret + * copy testfile "\\computername\Receipt Printer" + * del testfile + * * GNU/Linux: - * # No authentication - * echo "Hello World" | smbclient "//computername/Receipt Printer" -c "print -" -N - * # Guest login - * echo "Hello World" | smbclient "//computername/Receipt Printer" -U Guest -c "print -" -N + * # No authentication + * echo "Hello World" | smbclient "//computername/Receipt Printer" -c "print -" -N + * # Guest login + * echo "Hello World" | smbclient "//computername/Receipt Printer" -U Guest -c "print -" -N * # Basic username/password - * echo "Hello World" | smbclient "//computername/Receipt Printer" secret -U "Bob" -c "print -" - * # Including domain name - * echo "Hello World" | smbclient "//computername/Receipt Printer" secret -U "workgroup\\Bob" -c "print -" + * echo "Hello World" | smbclient "//computername/Receipt Printer" secret -U "Bob" -c "print -" + * # Including domain name + * echo "Hello World" | smbclient "//computername/Receipt Printer" secret -U "workgroup\\Bob" -c "print -" */ try { - // Enter the share name for your printer here, as a smb:// url format - $connector = null; - //$connector = new WindowsPrintConnector("smb://computername/Receipt Printer"); - //$connector = new WindowsPrintConnector("smb://Guest@computername/Receipt Printer"); - //$connector = new WindowsPrintConnector("smb://FooUser:secret@computername/workgroup/Receipt Printer"); - //$connector = new WindowsPrintConnector("smb://User:secret@computername/Receipt Printer"); - - /* Print a "Hello world" receipt" */ - $printer = new Escpos($connector); - $printer -> text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch(Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; + // Enter the share name for your printer here, as a smb:// url format + $connector = new WindowsPrintConnector("smb://computername/Receipt Printer"); + //$connector = new WindowsPrintConnector("smb://Guest@computername/Receipt Printer"); + //$connector = new WindowsPrintConnector("smb://FooUser:secret@computername/workgroup/Receipt Printer"); + //$connector = new WindowsPrintConnector("smb://User:secret@computername/Receipt Printer"); + + /* Print a "Hello world" receipt" */ + $printer = new Printer($connector); + $printer -> text("Hello World!\n"); + $printer -> cut(); + + /* Close printer */ + $printer -> close(); +} catch (Exception $e) { + echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; } diff --git a/htdocs/includes/mike42/escpos-php/example/interface/windows-lpt.php b/htdocs/includes/mike42/escpos-php/example/interface/windows-lpt.php index 76294425cdc..e8fef286bd8 100644 --- a/htdocs/includes/mike42/escpos-php/example/interface/windows-lpt.php +++ b/htdocs/includes/mike42/escpos-php/example/interface/windows-lpt.php @@ -1,30 +1,31 @@ LPT1 + * echo "Hello World" > LPT1 */ try { - $connector = null; - //$connector = new WindowsPrintConnector("LPT1"); - - // A FilePrintConnector will also work, but on non-Windows systems, writes - // to an actual file called 'LPT1' rather than giving a useful error. - // $connector = new FilePrintConnector("LPT1"); + $connector = new WindowsPrintConnector("LPT1"); + + // A FilePrintConnector will also work, but on non-Windows systems, writes + // to an actual file called 'LPT1' rather than giving a useful error. + // $connector = new FilePrintConnector("LPT1"); - /* Print a "Hello world" receipt" */ - $printer = new Escpos($connector); - $printer -> text("Hello World!\n"); - $printer -> cut(); + /* Print a "Hello world" receipt" */ + $printer = new Printer($connector); + $printer -> text("Hello World!\n"); + $printer -> cut(); - /* Close printer */ - $printer -> close(); -} catch(Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; + /* Close printer */ + $printer -> close(); +} catch (Exception $e) { + echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; } diff --git a/htdocs/includes/mike42/escpos-php/example/interface/windows-usb.php b/htdocs/includes/mike42/escpos-php/example/interface/windows-usb.php index d4b550e2f93..79776994231 100644 --- a/htdocs/includes/mike42/escpos-php/example/interface/windows-usb.php +++ b/htdocs/includes/mike42/escpos-php/example/interface/windows-usb.php @@ -1,32 +1,34 @@ testfile - * copy testfile "\\%COMPUTERNAME%\Receipt Printer" - * del testfile + * + * echo "Hello World" > testfile + * copy testfile "\\%COMPUTERNAME%\Receipt Printer" + * del testfile */ try { - // Enter the share name for your USB printer here - $connector = null; - //$connector = new WindowsPrintConnector("Receipt Printer"); + // Enter the share name for your USB printer here + $connector = null; + //$connector = new WindowsPrintConnector("Receipt Printer"); - /* Print a "Hello world" receipt" */ - $printer = new Escpos($connector); - $printer -> text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch(Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; + /* Print a "Hello world" receipt" */ + $printer = new Printer($connector); + $printer -> text("Hello World!\n"); + $printer -> cut(); + + /* Close printer */ + $printer -> close(); +} catch (Exception $e) { + echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; } diff --git a/htdocs/includes/mike42/escpos-php/example/margins-and-spacing.php b/htdocs/includes/mike42/escpos-php/example/margins-and-spacing.php new file mode 100644 index 00000000000..296a7b0bc73 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/margins-and-spacing.php @@ -0,0 +1,48 @@ + setEmphasis(true); +$printer -> text("Line spacing\n"); +$printer -> setEmphasis(false); +foreach(array(16, 32, 64, 128, 255) as $spacing) { + $printer -> setLineSpacing($spacing); + $printer -> text("Spacing $spacing: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.\n"); +} +$printer -> setLineSpacing(); // Back to default +*/ + +/* Stuff around with left margin */ +$printer -> setEmphasis(true); +$printer -> text("Left margin\n"); +$printer -> setEmphasis(false); +$printer -> text("Default left\n"); +foreach(array(1, 2, 4, 8, 16, 32, 64, 128, 256, 512) as $margin) { + $printer -> setPrintLeftMargin($margin); + $printer -> text("left margin $margin\n"); +} +/* Reset left */ +$printer -> setPrintLeftMargin(0); + +/* Stuff around with page width */ +$printer -> setEmphasis(true); +$printer -> text("Page width\n"); +$printer -> setEmphasis(false); +$printer -> setJustification(Printer::JUSTIFY_RIGHT); +$printer -> text("Default width\n"); +foreach(array(512, 256, 128, 64) as $width) { + $printer -> setPrintWidth($width); + $printer -> text("page width $width\n"); +} + +/* Printer shutdown */ +$printer -> cut(); +$printer -> close(); + diff --git a/htdocs/includes/mike42/escpos-php/example/pdf417-code.php b/htdocs/includes/mike42/escpos-php/example/pdf417-code.php new file mode 100644 index 00000000000..6735ae6ee4d --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/pdf417-code.php @@ -0,0 +1,95 @@ + pdf417Code($testStr); +$printer -> text("Most simple example\n"); +$printer -> feed(); + +// Demo that alignment is the same as text +$printer -> setJustification(Printer::JUSTIFY_CENTER); +$printer -> pdf417Code($testStr, 3, 3, 2); +$printer -> text("Same content, narrow and centred\n"); +$printer -> setJustification(); +$printer -> feed(); + +// Demo of error correction +title($printer, "Error correction\n"); +$ec = array(0.1, 0.5, 1.0, 2.0, 4.0); +foreach ($ec as $level) { + $printer -> pdf417Code($testStr, 3, 3, 0, $level); + $printer -> text("Error correction ratio $level\n"); + $printer -> feed(); +} + +// Change size +title($printer, "Pixel size\n"); +$sizes = array( + 2 => "(minimum)", + 3 => "(default)", + 4 => "", + 8 => "(maximum)"); +foreach ($sizes as $size => $label) { + $printer -> pdf417Code($testStr, $size); + $printer -> text("Module width $size dots $label\n"); + $printer -> feed(); +} + +// Change height +title($printer, "Height multiplier\n"); +$sizes = array( + 2 => "(minimum)", + 3 => "(default)", + 4 => "", + 8 => "(maximum)"); +foreach ($sizes as $size => $label) { + $printer -> pdf417Code($testStr, 3, $size); + $printer -> text("Height multiplier $size $label\n"); + $printer -> feed(); +} + +// Chage data column count +title($printer, "Data column count\n"); +$columnCounts = array( + 0 => "(auto, default)", + 1 => "", + 2 => "", + 3 => "", + 4 => "", + 5 => "", + 30 => "(maximum, doesnt fit!)"); +foreach ($columnCounts as $columnCount => $label) { + $printer -> pdf417Code($testStr, 3, 3, $columnCount); + $printer -> text("Column count $columnCount $label\n"); + $printer -> feed(); +} + +// Change options +title($printer, "Options\n"); +$models = array( + Printer::PDF417_STANDARD => "Standard", + Printer::PDF417_TRUNCATED => "Truncated"); +foreach ($models as $model => $name) { + $printer -> pdf417Code($testStr, 3, 3, 0, 0.10, $model); + $printer -> text("$name\n"); + $printer -> feed(); +} + +// Cut & close +$printer -> cut(); +$printer -> close(); + +function title(Printer $printer, $str) +{ + $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); + $printer -> text($str); + $printer -> selectPrintMode(); +} diff --git a/htdocs/includes/mike42/escpos-php/example/print-from-html.php b/htdocs/includes/mike42/escpos-php/example/print-from-html.php index f0751d7a4ae..640132e11b0 100644 --- a/htdocs/includes/mike42/escpos-php/example/print-from-html.php +++ b/htdocs/includes/mike42/escpos-php/example/print-from-html.php @@ -1,11 +1,20 @@ 225 below) and printing w/ Escpos::IMG_DOUBLE_WIDTH | Escpos::IMG_DOUBLE_HEIGHT */ try { - /* Set up command */ - $source = "http://en.m.wikipedia.org/wiki/ESC/P"; - $width = 550; - $dest = tempnam(sys_get_temp_dir(), 'escpos') . ".png"; - $cmd = sprintf("wkhtmltoimage -n -q --width %s %s %s", - escapeshellarg($width), - escapeshellarg($source), - escapeshellarg($dest)); - - /* Run wkhtmltoimage */ - ob_start(); - system($cmd); // Can also use popen() for better control of process - $outp = ob_get_contents(); - ob_end_clean(); - if(!file_exists($dest)) { - throw new Exception("Command $cmd failed: $outp"); - } + /* Set up command */ + $source = __DIR__ . "/resources/document.html"; + $width = 550; + $dest = tempnam(sys_get_temp_dir(), 'escpos') . ".png"; + $command = sprintf( + "xvfb-run wkhtmltoimage -n -q --width %s %s %s", + escapeshellarg($width), + escapeshellarg($source), + escapeshellarg($dest) + ); - /* Load up the image */ - try { - $img = new EscposImage($dest); - } catch(Exception $e) { - unlink($dest); - throw $e; - } - unlink($dest); + /* Test for dependencies */ + foreach (array("xvfb-run", "wkhtmltoimage") as $cmd) { + $testCmd = sprintf("which %s", escapeshellarg($cmd)); + exec($testCmd, $testOut, $testStatus); + if ($testStatus != 0) { + throw new Exception("You require $cmd but it could not be found"); + } + } - /* Print it */ - $printer = new Escpos(); // Add connector for your printer here. - $printer -> bitImage($img); // bitImage() seems to allow larger images than graphics() on the TM-T20. - $printer -> cut(); - $printer -> close(); -} catch(Exception $e) { - echo $e -> getMessage(); + + /* Run wkhtmltoimage */ + $descriptors = array( + 1 => array("pipe", "w"), + 2 => array("pipe", "w"), + ); + $process = proc_open($command, $descriptors, $fd); + if (is_resource($process)) { + /* Read stdout */ + $outputStr = stream_get_contents($fd[1]); + fclose($fd[1]); + /* Read stderr */ + $errorStr = stream_get_contents($fd[2]); + fclose($fd[2]); + /* Finish up */ + $retval = proc_close($process); + if ($retval != 0) { + throw new Exception("Command $cmd failed: $outputStr $errorStr"); + } + } else { + throw new Exception("Command '$cmd' failed to start."); + } + + /* Load up the image */ + try { + $img = EscposImage::load($dest); + } catch (Exception $e) { + unlink($dest); + throw $e; + } + unlink($dest); + + /* Print it */ + $printer -> bitImage($img); // bitImage() seems to allow larger images than graphics() on the TM-T20. bitImageColumnFormat() is another option. + $printer -> cut(); +} catch (Exception $e) { + echo $e -> getMessage(); +} finally { + $printer -> close(); } - diff --git a/htdocs/includes/mike42/escpos-php/example/print-from-pdf.php b/htdocs/includes/mike42/escpos-php/example/print-from-pdf.php index ba6a4c67a96..23469e8a00f 100644 --- a/htdocs/includes/mike42/escpos-php/example/print-from-pdf.php +++ b/htdocs/includes/mike42/escpos-php/example/print-from-pdf.php @@ -1,5 +1,9 @@ graphics($page); - } - $printer -> cut(); - $printer -> close(); -} catch(Exception $e) { - /* + $pages = ImagickEscposImage::loadPdf($pdf); + foreach ($pages as $page) { + $printer -> graphics($page); + } + $printer -> cut(); +} catch (Exception $e) { + /* * loadPdf() throws exceptions if files or not found, or you don't have the * imagick extension to read PDF's */ - echo $e -> getMessage() . "\n"; - exit(0); + echo $e -> getMessage() . "\n"; +} finally { + $printer -> close(); } @@ -33,11 +38,12 @@ try { * * Reduce the page width further if necessary: if it extends past the printing area, your prints will be very slow. */ -$printer = new Escpos(); +$connector = new FilePrintConnector("php://stdout"); +$printer = new Printer($connector); $pdf = 'resources/document.pdf'; -$pages = EscposImage::loadPdf($pdf, 260); -foreach($pages as $page) { - $printer -> graphics($page, Escpos::IMG_DOUBLE_HEIGHT | Escpos::IMG_DOUBLE_WIDTH); +$pages = ImagickEscposImage::loadPdf($pdf, 260); +foreach ($pages as $page) { + $printer -> graphics($page, Printer::IMG_DOUBLE_HEIGHT | Printer::IMG_DOUBLE_WIDTH); } $printer -> cut(); $printer -> close(); @@ -51,21 +57,22 @@ $printer -> close(); * * [1]After printing, the pixels are loaded and formatted for the print command you used, so even a raspberry pi can print complex PDF's quickly. */ -$printer = new Escpos(); +$connector = new FilePrintConnector("php://stdout"); +$printer = new Printer($connector); $pdf = 'resources/document.pdf'; $ser = 'resources/document.z'; -if(!file_exists($ser)) { - $pages = EscposImage::loadPdf($pdf); +if (!file_exists($ser)) { + $pages = ImagickEscposImage::loadPdf($pdf); } else { - $pages = unserialize(gzuncompress(file_get_contents($ser))); + $pages = unserialize(gzuncompress(file_get_contents($ser))); } -foreach($pages as $page) { - $printer -> graphics($page); +foreach ($pages as $page) { + $printer -> graphics($page); } $printer -> cut(); $printer -> close(); -if(!file_exists($ser)) { - file_put_contents($ser, gzcompress(serialize($pages))); +if (!file_exists($ser)) { + file_put_contents($ser, gzcompress(serialize($pages))); } diff --git a/htdocs/includes/mike42/escpos-php/example/qr-code.php b/htdocs/includes/mike42/escpos-php/example/qr-code.php index dbf21aaedf4..f57c2b8270d 100644 --- a/htdocs/includes/mike42/escpos-php/example/qr-code.php +++ b/htdocs/includes/mike42/escpos-php/example/qr-code.php @@ -1,7 +1,11 @@ text("Most simple example\n"); $printer -> feed(); // Demo that alignment is the same as text -$printer -> setJustification(Escpos::JUSTIFY_CENTER); +$printer -> setJustification(Printer::JUSTIFY_CENTER); $printer -> qrCode($testStr); $printer -> text("Same example, centred\n"); $printer -> setJustification(); $printer -> feed(); - + // Demo of numeric data being packed more densly title($printer, "Data encoding\n"); $test = array( - "Numeric" => "0123456789012345678901234567890123456789", - "Alphanumeric" => "abcdefghijklmnopqrstuvwxyzabcdefghijklmn", - "Binary" => str_repeat("\0", 40)); -foreach($test as $type => $data) { - $printer -> qrCode($data); - $printer -> text("$type\n"); - $printer -> feed(); + "Numeric" => "0123456789012345678901234567890123456789", + "Alphanumeric" => "abcdefghijklmnopqrstuvwxyzabcdefghijklmn", + "Binary" => str_repeat("\0", 40)); +foreach ($test as $type => $data) { + $printer -> qrCode($data); + $printer -> text("$type\n"); + $printer -> feed(); } // Demo of error correction title($printer, "Error correction\n"); $ec = array( - Escpos::QR_ECLEVEL_L => "L", - Escpos::QR_ECLEVEL_M => "M", - Escpos::QR_ECLEVEL_Q => "Q", - Escpos::QR_ECLEVEL_H => "H"); -foreach($ec as $level => $name) { - $printer -> qrCode($testStr, $level); - $printer -> text("Error correction $name\n"); - $printer -> feed(); + Printer::QR_ECLEVEL_L => "L", + Printer::QR_ECLEVEL_M => "M", + Printer::QR_ECLEVEL_Q => "Q", + Printer::QR_ECLEVEL_H => "H"); +foreach ($ec as $level => $name) { + $printer -> qrCode($testStr, $level); + $printer -> text("Error correction $name\n"); + $printer -> feed(); } // Change size title($printer, "Pixel size\n"); $sizes = array( - 1 => "(minimum)", - 2 => "", - 3 => "(default)", - 4 => "", - 5 => "", - 10 => "", - 16 => "(maximum)"); -foreach($sizes as $size => $label) { - $printer -> qrCode($testStr, Escpos::QR_ECLEVEL_L, $size); - $printer -> text("Pixel size $size $label\n"); - $printer -> feed(); + 1 => "(minimum)", + 2 => "", + 3 => "(default)", + 4 => "", + 5 => "", + 10 => "", + 16 => "(maximum)"); +foreach ($sizes as $size => $label) { + $printer -> qrCode($testStr, Printer::QR_ECLEVEL_L, $size); + $printer -> text("Pixel size $size $label\n"); + $printer -> feed(); } // Change model title($printer, "QR model\n"); $models = array( - Escpos::QR_MODEL_1 => "QR Model 1", - Escpos::QR_MODEL_2 => "QR Model 2 (default)", - Escpos::QR_MICRO => "Micro QR code\n(not supported on all printers)"); -foreach($models as $model => $name) { - $printer -> qrCode($testStr, Escpos::QR_ECLEVEL_L, 3, $model); - $printer -> text("$name\n"); - $printer -> feed(); + Printer::QR_MODEL_1 => "QR Model 1", + Printer::QR_MODEL_2 => "QR Model 2 (default)", + Printer::QR_MICRO => "Micro QR code\n(not supported on all printers)"); +foreach ($models as $model => $name) { + $printer -> qrCode($testStr, Printer::QR_ECLEVEL_L, 3, $model); + $printer -> text("$name\n"); + $printer -> feed(); } // Cut & close $printer -> cut(); $printer -> close(); -function title(Escpos $printer, $str) { - $printer -> selectPrintMode(Escpos::MODE_DOUBLE_HEIGHT | Escpos::MODE_DOUBLE_WIDTH); - $printer -> text($str); - $printer -> selectPrintMode(); +function title(Printer $printer, $str) +{ + $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); + $printer -> text($str); + $printer -> selectPrintMode(); } diff --git a/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.html b/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.html new file mode 100644 index 00000000000..c3d307a94d1 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.html @@ -0,0 +1,76 @@ + + + + + RawBT Integration Demo + + + + + + + +black & white picture +

RawBT Integration Demo

+
+
+    window.location.href = ajax_backend_data;
+
+
+
+ + +

Visit RawBT site

+ + diff --git a/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.php b/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.php new file mode 100644 index 00000000000..45a4e8fcde2 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.php @@ -0,0 +1,145 @@ +getSupportsGraphics()) { + $printer->graphics($logo); + } + if ($profile->getSupportsBitImageRaster() && !$profile->getSupportsGraphics()) { + $printer->bitImage($logo); + } + + /* Name of shop */ + $printer->setJustification(Printer::JUSTIFY_CENTER); + $printer->selectPrintMode(Printer::MODE_DOUBLE_WIDTH); + $printer->text("ExampleMart Ltd.\n"); + $printer->selectPrintMode(); + $printer->text("Shop No. 42.\n"); + $printer->feed(); + + + /* Title of receipt */ + $printer->setEmphasis(true); + $printer->text("SALES INVOICE\n"); + $printer->setEmphasis(false); + + /* Items */ + $printer->setJustification(Printer::JUSTIFY_LEFT); + $printer->setEmphasis(true); + $printer->text(new item('', '$')); + $printer->setEmphasis(false); + foreach ($items as $item) { + $printer->text($item->getAsString(32)); // for 58mm Font A + } + $printer->setEmphasis(true); + $printer->text($subtotal->getAsString(32)); + $printer->setEmphasis(false); + $printer->feed(); + + /* Tax and total */ + $printer->text($tax->getAsString(32)); + $printer->selectPrintMode(Printer::MODE_DOUBLE_WIDTH); + $printer->text($total->getAsString(32)); + $printer->selectPrintMode(); + + /* Footer */ + $printer->feed(2); + $printer->setJustification(Printer::JUSTIFY_CENTER); + $printer->text("Thank you for shopping\n"); + $printer->text("at ExampleMart\n"); + $printer->text("For trading hours,\n"); + $printer->text("please visit example.com\n"); + $printer->feed(2); + $printer->text($date . "\n"); + + /* Barcode Default look */ + + $printer->barcode("ABC", Printer::BARCODE_CODE39); + $printer->feed(); + $printer->feed(); + + +// Demo that alignment QRcode is the same as text + $printer2 = new Printer($connector); // dirty printer profile hack !! + $printer2->setJustification(Printer::JUSTIFY_CENTER); + $printer2->qrCode("https://rawbt.ru/mike42", Printer::QR_ECLEVEL_M, 8); + $printer2->text("rawbt.ru/mike42\n"); + $printer2->setJustification(); + $printer2->feed(); + + + /* Cut the receipt and open the cash drawer */ + $printer->cut(); + $printer->pulse(); + +} catch (Exception $e) { + echo $e->getMessage(); +} finally { + $printer->close(); +} + +/* A wrapper to do organise item names & prices into columns */ + +class item +{ + private $name; + private $price; + private $dollarSign; + + public function __construct($name = '', $price = '', $dollarSign = false) + { + $this->name = $name; + $this->price = $price; + $this->dollarSign = $dollarSign; + } + + public function getAsString($width = 48) + { + $rightCols = 10; + $leftCols = $width - $rightCols; + if ($this->dollarSign) { + $leftCols = $leftCols / 2 - $rightCols / 2; + } + $left = str_pad($this->name, $leftCols); + + $sign = ($this->dollarSign ? '$ ' : ''); + $right = str_pad($sign . $this->price, $rightCols, ' ', STR_PAD_LEFT); + return "$left$right\n"; + } + + public function __toString() + { + return $this->getAsString(); + } + +} diff --git a/htdocs/includes/mike42/escpos-php/example/receipt-with-logo.php b/htdocs/includes/mike42/escpos-php/example/receipt-with-logo.php index 8322c09c750..b094e9f2b2a 100644 --- a/htdocs/includes/mike42/escpos-php/example/receipt-with-logo.php +++ b/htdocs/includes/mike42/escpos-php/example/receipt-with-logo.php @@ -1,12 +1,18 @@ setJustification(Escpos::JUSTIFY_CENTER); +$printer -> setJustification(Printer::JUSTIFY_CENTER); $printer -> graphics($logo); /* Name of shop */ -$printer -> selectPrintMode(Escpos::MODE_DOUBLE_WIDTH); +$printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH); $printer -> text("ExampleMart Ltd.\n"); $printer -> selectPrintMode(); $printer -> text("Shop No. 42.\n"); @@ -36,12 +42,12 @@ $printer -> text("SALES INVOICE\n"); $printer -> setEmphasis(false); /* Items */ -$printer -> setJustification(Escpos::JUSTIFY_LEFT); +$printer -> setJustification(Printer::JUSTIFY_LEFT); $printer -> setEmphasis(true); $printer -> text(new item('', '$')); $printer -> setEmphasis(false); -foreach($items as $item) { - $printer -> text($item); +foreach ($items as $item) { + $printer -> text($item); } $printer -> setEmphasis(true); $printer -> text($subtotal); @@ -50,13 +56,13 @@ $printer -> feed(); /* Tax and total */ $printer -> text($tax); -$printer -> selectPrintMode(Escpos::MODE_DOUBLE_WIDTH); +$printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH); $printer -> text($total); $printer -> selectPrintMode(); /* Footer */ $printer -> feed(2); -$printer -> setJustification(Escpos::JUSTIFY_CENTER); +$printer -> setJustification(Printer::JUSTIFY_CENTER); $printer -> text("Thank you for shopping at ExampleMart\n"); $printer -> text("For trading hours, please visit example.com\n"); $printer -> feed(2); @@ -69,28 +75,30 @@ $printer -> pulse(); $printer -> close(); /* A wrapper to do organise item names & prices into columns */ -class item { - private $name; - private $price; - private $dollarSign; +class item +{ + private $name; + private $price; + private $dollarSign; - public function __construct($name = '', $price = '', $dollarSign = false) { - $this -> name = $name; - $this -> price = $price; - $this -> dollarSign = $dollarSign; - } - - public function __toString() { - $rightCols = 10; - $leftCols = 38; - if($this -> dollarSign) { - $leftCols = $leftCols / 2 - $rightCols / 2; - } - $left = str_pad($this -> name, $leftCols) ; - - $sign = ($this -> dollarSign ? '$ ' : ''); - $right = str_pad($sign . $this -> price, $rightCols, ' ', STR_PAD_LEFT); - return "$left$right\n"; - } + public function __construct($name = '', $price = '', $dollarSign = false) + { + $this -> name = $name; + $this -> price = $price; + $this -> dollarSign = $dollarSign; + } + + public function __toString() + { + $rightCols = 10; + $leftCols = 38; + if ($this -> dollarSign) { + $leftCols = $leftCols / 2 - $rightCols / 2; + } + $left = str_pad($this -> name, $leftCols) ; + + $sign = ($this -> dollarSign ? '$ ' : ''); + $right = str_pad($sign . $this -> price, $rightCols, ' ', STR_PAD_LEFT); + return "$left$right\n"; + } } -?> diff --git a/htdocs/includes/mike42/escpos-php/example/resources/character-encoding-test-strings.inc b/htdocs/includes/mike42/escpos-php/example/resources/character-encoding-test-strings.inc index caca76c4479..000b3bd59a2 100644 --- a/htdocs/includes/mike42/escpos-php/example/resources/character-encoding-test-strings.inc +++ b/htdocs/includes/mike42/escpos-php/example/resources/character-encoding-test-strings.inc @@ -3,21 +3,22 @@ * on the default profile, so you can use them to test modified profiles (using the wrong * profile for a printer produces mojibake) */ $inputsOk = array( - "Danish" => "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther spillede på xylofon.\n", - "German" => "Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.\n", - "Greek" => "Ξεσκεπάζω την ψυχοφθόρα βδελυγμία\n", - "English" => "The quick brown fox jumps over the lazy dog.\n", - "Spanish" => "El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.\n", - "French" => "Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en canoë au delà des îles, près du mälström où brûlent les novæ.\n", - "Irish Gaelic" => "D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh.\n", - "Hungarian" => "Árvíztűrő tükörfúrógép.\n", - "Icelandic" => "Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa.\n", - "Latvian" => "Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus.\n", - "Polish" => "Pchnąć w tę łódź jeża lub ośm skrzyń fig.\n", - "Russian" => "В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!\n", - "Turkish" => "Pijamalı hasta, yağız şoföre çabucak güvendi.\n", - "Japanese (Katakana half-width)" => implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウイノオクヤマ ケフコエテ アサキユメミシ エヒモセスン")) . "\n" - ); + "Danish" => "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther spillede på xylofon.\n", + "German" => "Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.\n", + "Greek" => "Ξεσκεπάζω την ψυχοφθόρα βδελυγμία\n", + "English" => "The quick brown fox jumps over the lazy dog.\n", + "Spanish" => "El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.\n", + "French" => "Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en canoë au delà des îles, près du mälström où brûlent les novæ.\n", + "Irish Gaelic" => "D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh.\n", + "Hungarian" => "Árvíztűrő tükörfúrógép.\n", + "Icelandic" => "Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa.\n", + "Latvian" => "Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus.\n", + "Polish" => "Pchnąć w tę łódź jeża lub ośm skrzyń fig.\n", + "Russian" => "В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!\n", + "Turkish" => "Pijamalı hasta, yağız şoföre çabucak güvendi.\n", + "Japanese (Katakana half-width)" => implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウイノオクヤマ ケフコエテ アサキユメミシ エヒモセスン")) . "\n", + "Vietnamese" => "Tiếng Việt, còn gọi tiếng Việt Nam hay Việt ngữ, là ngôn ngữ của người Việt (người Kinh) và là ngôn ngữ chính thức tại Việt Nam.\n" + ); /* * These strings are not expected to print correctly, if at all, even on an Epson printer. This is due to a mix of @@ -26,10 +27,9 @@ $inputsOk = array( * They are included here as a collection of things not yet implemented. */ $inputsNotOk = array( - "Thai (No character encoder available)" => "นายสังฆภัณฑ์ เฮงพิทักษ์ฝั่ง ผู้เฒ่าซึ่งมีอาชีพเป็นฅนขายฃวด ถูกตำรวจปฏิบัติการจับฟ้องศาล ฐานลักนาฬิกาคุณหญิงฉัตรชฎา ฌานสมาธิ\n", - "Japanese (Hiragana)" => implode("\n", array("いろはにほへとちりぬるを", " わかよたれそつねならむ", "うゐのおくやまけふこえて", "あさきゆめみしゑひもせす")) . "\n", - "Japanese (Katakana full-width)" => implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン")) . "\n", - "Arabic (RTL not supported, encoding issues)" => "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ" . "\n", - "Hebrew (RTL not supported, line break issues)" => "דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה" . "\n" - ); - + "Thai (No character encoder available)" => "นายสังฆภัณฑ์ เฮงพิทักษ์ฝั่ง ผู้เฒ่าซึ่งมีอาชีพเป็นฅนขายฃวด ถูกตำรวจปฏิบัติการจับฟ้องศาล ฐานลักนาฬิกาคุณหญิงฉัตรชฎา ฌานสมาธิ\n", + "Japanese (Hiragana)" => implode("\n", array("いろはにほへとちりぬるを", " わかよたれそつねならむ", "うゐのおくやまけふこえて", "あさきゆめみしゑひもせす")) . "\n", + "Japanese (Katakana full-width)" => implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン")) . "\n", + "Arabic (RTL not supported, encoding issues)" => "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ" . "\n", + "Hebrew (RTL not supported, line break issues)" => "דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה" . "\n" + ); diff --git a/htdocs/includes/mike42/escpos-php/example/resources/document.html b/htdocs/includes/mike42/escpos-php/example/resources/document.html new file mode 100644 index 00000000000..bb413aa1d3d --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/resources/document.html @@ -0,0 +1,40 @@ + + + + + + + + + + + + + +

+ + This is a simple document. For receipts involving complex formatting, + non-monospace fonts, advanced character encodings, or vector graphics, + you can always create and render HTML instead. +

+

+ The printing will be a lot slower, but you have full access to things like unicode and SVG. +

+

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua.

+

Ut enim ad minim veniam, quis nostrud exercitation ullamco + laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor + in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla + pariatur.

+

Excepteur sint occaecat cupidatat non proident, sunt in culpa + qui officia deserunt mollit anim id est laborum.

+ + diff --git a/htdocs/includes/mike42/escpos-php/example/resources/document.z b/htdocs/includes/mike42/escpos-php/example/resources/document.z index cb0473875589c9505bfaa40eec9fb6bb930e59a6..c19e213227aa0fd1d601285fc03b6caa3427b1ee 100644 GIT binary patch literal 18900 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 literal 20320 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 RuDa7m%-5OL40^FJe*+_L<7)r_ diff --git a/htdocs/includes/mike42/escpos-php/example/resources/rawbtlogo.png b/htdocs/includes/mike42/escpos-php/example/resources/rawbtlogo.png new file mode 100644 index 0000000000000000000000000000000000000000..999abab33e236912c93d59fd032431cdcdcb26e0 GIT binary patch literal 1358 zcmV-U1+n^xP)p(EnuI);X7XGWDosAHLOP)UR;MsOQM66j7#jM6lO z4oZ&?q0J?#ero_rOl{EpaRJzd6h7N;Hei9}BOgIo+A7%yR<}{p0J^GT8V1l-O*P$N z0qu{r8%Q`5*A1jcTipOD`cTy&QM?aj{oBR{ur5tcec06BKo`0uA_Hif7`tA?18l!o zdeF4h??oJT-3CNHg-Z0`#*a{6t$}d7#l~e^+S=NlpoVfS4LsDohS0(`aHfX5hKH`O zHLQL+K?m2j1a}BS3#X^Bgb3_$qyn(&AAA6F6jU7{u*XSKg-cdtgBd_qm3@Y4Zn|m8 zkPo0OF$X<@p*>3vZldkb_z^ZSg1+Ib2esIRUCjD<|Fq+1??cCo*cP=;mWQ&bHK2~O zPIJpNSF?P@&PeI+5>6fpc)=K_jT5Nj%3!$3a0)T+Le@YVn+@^|vFKS+(R=K~GqlVy z!#CfU2}f2;fFRcsbleENsC{z0q|^c-!~LUM?f!NDvVX)8v^3D9-aiicnAkE*VK~8< zDl^PGQg@m}1k=DwTbeVZJd|M`Paaxf=519weM6b84D~cSJTzPjwfI0%rKV=5(?GTf zHNz`Z$*h7PlYOLc_WxY#ieXF-crifzaUP9-mq2535 ze|BJ}XDDxcSE%M*&m5uX_4PG;Ps?f;J%43r!{6t6*&-OWNglEcwU3Au7jO-Ga4HlN zkDkMlku!6FbC@%fn{YD{Zjzy{pa`?j9w57bJe1glxU$IiIg`cU?FWZwkM4HRjj znRxuUhAKcagysnKJ+u|n9k|tS{?2eixcyhCYbc&Ug-~^%8NhhFqn^PdoSDk%EDPLl z!r``VC8)2V!a0f?#Tmj0PtjDBKOG=#N_B#Hm=W|-awGVLHc|)$xC;Kt2&xrfJnT0R zTPNQ!I`PUSLw*I}-E@L1*Kse86A;=KPVsdC-1}iCJNW$oC+ts0aU{4R{1D)q0vU}t z>O$Oi#zp4?w2;%ptRN>CW~%+MKtWSI!i~rChdsfWa!i3N!tk|yTcAfZ6uN;w7q}l_ zJaze(7EUJ!HGIjC9br81`Okh-+1C+VpTT&#^lkDRHS0!jDe&(BjHgS#rib)+4}Axz z8%Rg-2at}2@y!U*sMu(v-$Qi|X;gd@~Np2sh7LLL^W1j7R+o8gOx zb6NJnJWenyDh0+z6loz1(AIE@`(9Z?mY+x<48td{AZcZ7;6yN>3{?$z%yCz6i${M< zNFr`)8NpCL>`_@mmY%zWJ6}KzKTukdSQJ9EU^TSFHO&OUII)y@k^_>`yM=_-C*>i2lFeKas@WKj@Hw Q9{>OV07*qoM6N<$g5qCe^8f$< literal 0 HcmV?d00001 diff --git a/htdocs/includes/mike42/escpos-php/example/resources/tulips.png b/htdocs/includes/mike42/escpos-php/example/resources/tulips.png new file mode 100644 index 0000000000000000000000000000000000000000..a0e681cf0ffa7498bfff6e26d71b15f82a8bc7f6 GIT binary patch literal 379443 zcmV)RK(oJzP)004R=004l4008;_004mL004C`008P>0026e000+nl3&F}00006 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

;pHdyGure7GxRzfSq-{YSt0 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 L(g0N{n1A^n;lIUB literal 0 HcmV?d00001 diff --git a/htdocs/includes/mike42/escpos-php/example/specific/123-code128-barcode.php b/htdocs/includes/mike42/escpos-php/example/specific/123-code128-barcode.php new file mode 100644 index 00000000000..b87e44981e0 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/specific/123-code128-barcode.php @@ -0,0 +1,21 @@ + setJustification(Printer::JUSTIFY_CENTER); +$printer -> setBarcodeHeight(48); +$printer->setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW); +foreach(array($a, $b, $c) as $item) { + $printer -> barcode($item, Printer::BARCODE_CODE128); + $printer -> feed(1); +} +$printer -> cut(); +$printer -> close(); + diff --git a/htdocs/includes/mike42/escpos-php/example/specific/141-custom-command.php b/htdocs/includes/mike42/escpos-php/example/specific/141-custom-command.php new file mode 100644 index 00000000000..6e3bed70d0b --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/specific/141-custom-command.php @@ -0,0 +1,55 @@ +getPrintConnector()->write($barcodeCommand); +$printer->cut(); +$printer->close(); + +/** + * Generate two characters for a number: In lower and higher parts, or more parts as needed. + * + * @param int $input + * Input number + * @param int $length + * The number of bytes to output (1 - 4). + */ +function intLowHigh($input, $length) +{ + $outp = ""; + for ($i = 0; $i < $length; $i ++) { + $outp .= chr($input % 256); + $input = (int) ($input / 256); + } + return $outp; +} +?> \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/example/specific/148-data-uri.php b/htdocs/includes/mike42/escpos-php/example/specific/148-data-uri.php new file mode 100644 index 00000000000..74759146712 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/specific/148-data-uri.php @@ -0,0 +1,35 @@ + setResourceLimit(6, 1); // Prevent libgomp1 segfaults, grumble grumble. +$imagick -> readImageBlob($imageBlob, "input.png"); + +// Load Imagick straight into an EscposImage object +$im = new ImagickEscposImage(); +$im -> readImageFromImagick($imagick); + +// Do a test print to make sure that this EscposImage object has the right data +// (should see a tiny bullet point) +$connector = new FilePrintConnector("php://output"); +$printer = new Printer($connector); +$printer -> bitImage($im); +$printer -> cut(); +$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/235-get-data.php b/htdocs/includes/mike42/escpos-php/example/specific/235-get-data.php new file mode 100644 index 00000000000..c3607c868b3 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/specific/235-get-data.php @@ -0,0 +1,28 @@ + text("Hello world!\n"); +$printer -> cut(); + +// Get the data out as a string +$data = $connector -> getData(); + +// Return it, check the manual for specifics. +header('Content-type: application/octet-stream'); +header('Content-Length: '.strlen($data)); +echo $data; + +// Close the printer when done. +$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/29-latvian-star-tup592.php b/htdocs/includes/mike42/escpos-php/example/specific/29-latvian-star-tup592.php index 72dc7c8f2ed..73613100abb 100644 --- a/htdocs/includes/mike42/escpos-php/example/specific/29-latvian-star-tup592.php +++ b/htdocs/includes/mike42/escpos-php/example/specific/29-latvian-star-tup592.php @@ -1,11 +1,16 @@ - text("Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus\n"); $printer -> cut(); $printer -> close(); @@ -13,9 +18,8 @@ $printer -> close(); /* Option 2: Image-based output (formatting not available using this output) */ $buffer = new ImagePrintBuffer(); $connector = new FilePrintConnector("php://stdout"); -$printer = new Escpos($connector, $profile); +$printer = new Printer($connector, $profile); $printer -> setPrintBuffer($buffer); $printer -> text("Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus\n"); $printer -> cut(); $printer -> close(); -?> \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/example/specific/32-german-tm-t20-ii-custom-command.php b/htdocs/includes/mike42/escpos-php/example/specific/32-german-tm-t20-ii-custom-command.php index 49eca235091..29b6b3fc638 100644 --- a/htdocs/includes/mike42/escpos-php/example/specific/32-german-tm-t20-ii-custom-command.php +++ b/htdocs/includes/mike42/escpos-php/example/specific/32-german-tm-t20-ii-custom-command.php @@ -1,5 +1,9 @@ getPrintConnector() -> write($cmd); $printer -> text("Beispieltext in Deutsch\n"); $printer -> cut(); $printer -> close(); - /* * Hex-dump of output confirms that ESC V 1 being sent: * * 0000000 033 @ 033 V 001 B e i s p i e l t e x * 0000010 t i n D e u t s c h \n 035 V A * 0000020 003 - */ \ No newline at end of file + */ diff --git a/htdocs/includes/mike42/escpos-php/example/specific/33-spanish-seypos-prp-300.php b/htdocs/includes/mike42/escpos-php/example/specific/33-spanish-seypos-prp-300.php index 7314ad21bf0..90bdc63fb5c 100644 --- a/htdocs/includes/mike42/escpos-php/example/specific/33-spanish-seypos-prp-300.php +++ b/htdocs/includes/mike42/escpos-php/example/specific/33-spanish-seypos-prp-300.php @@ -6,11 +6,14 @@ * * Use the hardware switch to activate "Two-byte Character Code" */ -require_once(dirname(__FILE__) . "/../../Escpos.php"); +require __DIR__ . '/../../autoload.php'; +use Mike42\Escpos\CapabilityProfile; +use Mike42\Escpos\Printer; +use Mike42\Escpos\PrintConnectors\FilePrintConnector; + $connector = new FilePrintConnector("php://output"); -$profile = SimpleCapabilityProfile::getInstance(); -$printer = new Escpos($connector); +$profile = CapabilityProfile::load("simple"); // Works for Epson printers +$printer = new Printer($connector); $printer -> text("El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.\n"); $printer -> cut(); $printer -> close(); - diff --git a/htdocs/includes/mike42/escpos-php/example/specific/37-chinese.php b/htdocs/includes/mike42/escpos-php/example/specific/37-chinese.php new file mode 100644 index 00000000000..d14790f47d5 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/specific/37-chinese.php @@ -0,0 +1,24 @@ + textChinese("艾德蒙 AOC E2450SWH 23.6吋 LED液晶寬螢幕特價$ 19900\n\n"); + +// Note that on the printer tested (ZJ5890), the font only contained simplified characters. +$printer -> textChinese("示例文本打印机!\n\n"); +$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/39-currency-symbols.php b/htdocs/includes/mike42/escpos-php/example/specific/39-currency-symbols.php index b3d4b29edd1..b960ee681c3 100644 --- a/htdocs/includes/mike42/escpos-php/example/specific/39-currency-symbols.php +++ b/htdocs/includes/mike42/escpos-php/example/specific/39-currency-symbols.php @@ -1,11 +1,16 @@ - text("€ 9,95\n"); $printer -> text("£ 9.95\n"); $printer -> text("$ 9.95\n"); @@ -16,7 +21,7 @@ $printer -> close(); /* Option 2: Image-based output (formatting not available using this output). */ $buffer = new ImagePrintBuffer(); $connector = new FilePrintConnector("php://stdout"); -$printer = new Escpos($connector, $profile); +$printer = new Printer($connector, $profile); $printer -> setPrintBuffer($buffer); $printer -> text("€ 9,95\n"); $printer -> text("£ 9.95\n"); @@ -34,32 +39,35 @@ $printer -> close(); are not available in CP437. CP858 has good printer support, but is not included in all iconv builds. */ -class CustomCapabilityProfile extends SimpleCapabilityProfile { - function getCustomCodePages() { - /* +class CustomCapabilityProfile extends CapabilityProfile +{ + function getCustomCodePages() + { + /* * Example to print in a specific, user-defined character set * on a printer which has been configured to use i */ - return array( - 'CP858' => "ÇüéâäàåçêëèïîìÄÅ" . - "ÉæÆôöòûùÿÖÜø£Ø×ƒ" . - "áíóúñѪº¿®¬½¼¡«»" . - "░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐" . - "└┴┬├─┼ãÃ╚╔╩╦╠═╬¤" . - "ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀" . - "ÓßÔÒõÕµþÞÚÛÙýݯ´" . - " ±‗¾¶§÷¸°¨·¹³²■ "); - } - - function getSupportedCodePages() { - return array( - 0 => 'custom:CP858'); - } + return array( + 'CP858' => "ÇüéâäàåçêëèïîìÄÅ" . + "ÉæÆôöòûùÿÖÜø£Ø×ƒ" . + "áíóúñѪº¿®¬½¼¡«»" . + "░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐" . + "└┴┬├─┼ãÃ╚╔╩╦╠═╬¤" . + "ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀" . + "ÓßÔÒõÕµþÞÚÛÙýݯ´" . + " ±‗¾¶§÷¸°¨·¹³²■ "); + } + + function getSupportedCodePages() + { + return array( + 0 => 'custom:CP858'); + } } $connector = new FilePrintConnector("php://stdout"); $profile = CustomCapabilityProfile::getInstance(); -$printer = new Escpos($connector, $profile); +$printer = new Printer($connector, $profile); $printer -> text("€ 9,95\n"); $printer -> text("£ 9.95\n"); $printer -> text("$ 9.95\n"); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/44-pound-symbol-star-tsp650.php b/htdocs/includes/mike42/escpos-php/example/specific/44-pound-symbol-star-tsp650.php index 4ef1a9575c2..3e7e6a2e48b 100644 --- a/htdocs/includes/mike42/escpos-php/example/specific/44-pound-symbol-star-tsp650.php +++ b/htdocs/includes/mike42/escpos-php/example/specific/44-pound-symbol-star-tsp650.php @@ -7,12 +7,16 @@ */ // Adjust these to your environment -require_once(dirname(__FILE__) . "/../../Escpos.php"); +require __DIR__ . '/../../autoload.php'; +use Mike42\Escpos\CapabilityProfile; +use Mike42\Escpos\Printer; +use Mike42\Escpos\PrintConnectors\FilePrintConnector; + $connector = new FilePrintConnector("php://stdout"); // Start printer -$profile = SimpleCapabilityProfile::getInstance(); -$printer = new Escpos($connector, $profile); +$profile = CapabilityProfile::load("simple"); +$printer = new Printer($connector, $profile); // A) Raw pound symbol // This is the most likely thing to work, and bypasses all the fancy stuff. diff --git a/htdocs/includes/mike42/escpos-php/example/specific/50-P-822D-greek.php b/htdocs/includes/mike42/escpos-php/example/specific/50-P-822D-greek.php index 2d88cf1a2a8..1651f44a7fa 100644 --- a/htdocs/includes/mike42/escpos-php/example/specific/50-P-822D-greek.php +++ b/htdocs/includes/mike42/escpos-php/example/specific/50-P-822D-greek.php @@ -1,11 +1,14 @@ setJustification(Escpos::JUSTIFY_CENTER); - $printer -> graphics($img); - $printer -> cut(); - } finally { - // Always close the connection - $printer -> close(); - } + // Run the actual print + $printer = new Printer($connector, $profile); + try { + $printer -> setJustification(Printer::JUSTIFY_CENTER); + $printer -> graphics($img); + $printer -> cut(); + } finally { + // Always close the connection + $printer -> close(); + } } catch (Exception $e) { - // Print out any errors: Eg. printer connection, image loading & external image manipulation. - echo $e -> getMessage() . "\n"; - echo $e -> getTraceAsString(); + // Print out any errors: Eg. printer connection, image loading & external image manipulation. + echo $e -> getMessage() . "\n"; + echo $e -> getTraceAsString(); } finally { - unlink ( $imgCombined_path ); - unlink ( $tmpf_path ); + unlink($imgCombined_path); + unlink($tmpf_path); } diff --git a/htdocs/includes/mike42/escpos-php/example/specific/6-arabic-epos-tep-220m.php b/htdocs/includes/mike42/escpos-php/example/specific/6-arabic-epos-tep-220m.php index c2b0fb5aa57..5994b7a81c7 100644 --- a/htdocs/includes/mike42/escpos-php/example/specific/6-arabic-epos-tep-220m.php +++ b/htdocs/includes/mike42/escpos-php/example/specific/6-arabic-epos-tep-220m.php @@ -10,14 +10,30 @@ * Requirements are: * - imagick extension (For the ImagePrintBuffer, which does not * support gd at the time of writing) - * - Ar-PHP library, available from sourceforge, for the first - * part of this example. Drop it in the folder listed below: + * - ArPHP 4.0 (release date: Jan 8, 2016), available from SourceForge, for + * handling the layout for this example. */ -require_once(dirname(__FILE__) . "/../../Escpos.php"); -require_once(dirname(__FILE__) . "/../../vendor/I18N/Arabic.php"); +require __DIR__ . '/../../autoload.php'; +use Mike42\Escpos\CapabilityProfile; +use Mike42\Escpos\Printer; +use Mike42\Escpos\PrintConnectors\FilePrintConnector; +use Mike42\Escpos\PrintBuffers\ImagePrintBuffer; /* - * First, convert the text into LTR byte order with joined letters, + * Drop Ar-php into the folder listed below: + */ +require_once(dirname(__FILE__) . "/../../I18N/Arabic.php"); +$fontPath = dirname(__FILE__) . "/../../I18N/Arabic/Examples/GD/ae_AlHor.ttf"; + +/* + * Inputs are some text, line wrapping options, and a font size. + */ +$textUtf8 = "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ"; +$maxChars = 50; +$fontSize = 28; + +/* + * First, convert the text into LTR byte order with line wrapping, * Using the Ar-PHP library. * * The Ar-PHP library uses the default internal encoding, and can print @@ -29,19 +45,30 @@ require_once(dirname(__FILE__) . "/../../vendor/I18N/Arabic.php"); */ mb_internal_encoding("UTF-8"); $Arabic = new I18N_Arabic('Glyphs'); -$text = "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ"; -$text = $Arabic -> utf8Glyphs($text); +$textLtr = $Arabic -> utf8Glyphs($textUtf8, $maxChars); +$textLine = explode("\n", $textLtr); /* - * Set up and use the printer + * Set up and use an image print buffer with a suitable font */ $buffer = new ImagePrintBuffer(); -$profile = EposTepCapabilityProfile::getInstance(); -$connector = new FilePrintConnector("php://output"); - // = WindowsPrintConnector("LPT2"); - // Windows LPT2 was used in the bug tracker +$buffer -> setFont($fontPath); +$buffer -> setFontSize($fontSize); -$printer = new Escpos($connector, $profile); +$profile = CapabilityProfile::load("TEP-200M"); +$connector = new FilePrintConnector("php://output"); + // = new WindowsPrintConnector("LPT2"); + // Windows LPT2 was used in the bug tracker + +$printer = new Printer($connector, $profile); $printer -> setPrintBuffer($buffer); -$printer -> text($text . "\n"); + +$printer -> setJustification(Printer::JUSTIFY_RIGHT); +foreach($textLine as $text) { + // Print each line separately. We need to do this since Imagick thinks + // text is left-to-right + $printer -> text($text . "\n"); +} + +$printer -> cut(); $printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/62-greek-symbol-swap.php b/htdocs/includes/mike42/escpos-php/example/specific/62-greek-symbol-swap.php new file mode 100644 index 00000000000..5ea995e5aed --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/specific/62-greek-symbol-swap.php @@ -0,0 +1,15 @@ + text("Μιχάλης Νίκος\n"); +$printer -> cut(); +$printer -> close(); + +?> diff --git a/htdocs/includes/mike42/escpos-php/example/specific/68-redblack.php b/htdocs/includes/mike42/escpos-php/example/specific/68-redblack.php new file mode 100644 index 00000000000..142a83ab3e7 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/specific/68-redblack.php @@ -0,0 +1,21 @@ + text("Hello World!\n"); + $printer -> setColor(Printer::COLOR_2); + $printer -> text("Red?!\n"); + $printer -> setColor(Printer::COLOR_1); + $printer -> text("Default color again?!\n"); + $printer -> cut(); +} finally { + /* Always close the printer! */ + $printer -> close(); +} diff --git a/htdocs/includes/mike42/escpos-php/example/specific/97-dithering.php b/htdocs/includes/mike42/escpos-php/example/specific/97-dithering.php new file mode 100644 index 00000000000..312df749eb1 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/example/specific/97-dithering.php @@ -0,0 +1,28 @@ + bitImage($img1); + + /* Load with optimisations disabled, forcing the use of PHP to convert the + pixels, which uses a threshold and is much slower. + */ + $img2 = EscposImage::load(__DIR__ . '/../resources/tulips.png', false); + $printer -> bitImage($img2); + $printer -> cut(); +} finally { + /* Always close the printer! */ + $printer -> close(); +} diff --git a/htdocs/includes/mike42/escpos-php/example/text-size.php b/htdocs/includes/mike42/escpos-php/example/text-size.php index 2f9272e434b..01bf33dd699 100644 --- a/htdocs/includes/mike42/escpos-php/example/text-size.php +++ b/htdocs/includes/mike42/escpos-php/example/text-size.php @@ -5,33 +5,37 @@ * * @author Michael Billington */ -require_once(dirname(__FILE__) . "/../Escpos.php"); -$printer = new Escpos(); +require __DIR__ . '/../autoload.php'; +use Mike42\Escpos\Printer; +use Mike42\Escpos\PrintConnectors\FilePrintConnector; + +$connector = new FilePrintConnector("php://stdout"); +$printer = new Printer($connector); /* Initialize */ $printer -> initialize(); /* Text of various (in-proportion) sizes */ title($printer, "Change height & width\n"); -for($i = 1; $i <= 8; $i++) { - $printer -> setTextSize($i, $i); - $printer -> text($i); +for ($i = 1; $i <= 8; $i++) { + $printer -> setTextSize($i, $i); + $printer -> text($i); } $printer -> text("\n"); /* Width changing only */ title($printer, "Change width only (height=4):\n"); -for($i = 1; $i <= 8; $i++) { - $printer -> setTextSize($i, 4); - $printer -> text($i); +for ($i = 1; $i <= 8; $i++) { + $printer -> setTextSize($i, 4); + $printer -> text($i); } $printer -> text("\n"); /* Height changing only */ title($printer, "Change height only (width=4):\n"); -for($i = 1; $i <= 8; $i++) { - $printer -> setTextSize(4, $i); - $printer -> text($i); +for ($i = 1; $i <= 8; $i++) { + $printer -> setTextSize(4, $i); + $printer -> text($i); } $printer -> text("\n"); @@ -47,16 +51,15 @@ $printer -> text("Hello world!\n"); /* Very large text */ title($printer, "Largest possible text:\n"); -$printer -> setTextSize(8,8); +$printer -> setTextSize(8, 8); $printer -> text("Hello\nworld!\n"); $printer -> cut(); $printer -> close(); -function title(Escpos $printer, $text) { - $printer -> selectPrintMode(Escpos::MODE_EMPHASIZED); - $printer -> text("\n" . $text); - $printer -> selectPrintMode(); // Reset +function title(Printer $printer, $text) +{ + $printer -> selectPrintMode(Printer::MODE_EMPHASIZED); + $printer -> text("\n" . $text); + $printer -> selectPrintMode(); // Reset } - -?> diff --git a/htdocs/includes/mike42/escpos-php/phpunit.xml b/htdocs/includes/mike42/escpos-php/phpunit.xml new file mode 100644 index 00000000000..158b7e0775b --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/phpunit.xml @@ -0,0 +1,21 @@ + + + + test/unit + + + test/integration + + + + + src + + + diff --git a/htdocs/includes/mike42/escpos-php/src/AbstractCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/AbstractCapabilityProfile.php deleted file mode 100644 index db2e8e01f58..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/AbstractCapabilityProfile.php +++ /dev/null @@ -1,61 +0,0 @@ - CodePage::CP437, - 1 => CodePage::CP932, - 2 => CodePage::CP850, - 3 => CodePage::CP860, - 4 => CodePage::CP863, - 5 => CodePage::CP865, - 6 => false, // Hiragana - 7 => false, // One-pass printing Kanji characters - 8 => false, // Page 8 [One-pass printing Kanji characters] - 11 => CodePage::CP851, - 12 => CodePage::CP853, - 13 => CodePage::CP857, - 14 => CodePage::CP737, - 15 => CodePage::ISO8859_7, - 16 => CodePage::CP1252, - 17 => CodePage::CP866, - 18 => CodePage::CP852, - 19 => CodePage::CP858, - 20 => false, // Thai Character Code 42 - 21 => CodePage::CP874, // Thai Character Code 11 - 22 => false, // Thai Character Code 13 - 23 => false, // Thai Character Code 14 - 24 => false, // Thai Character Code 16 - 25 => false, // Thai Character Code 17 - 26 => false, // Thai Character Code 18 - 30 => false, // TCVN-3: Vietnamese - 31 => false, // TCVN-3: Vietnamese - 32 => CodePage::CP720, - 33 => CodePage::CP775, - 34 => CodePage::CP855, - 35 => CodePage::CP861, - 36 => CodePage::CP862, - 37 => CodePage::CP864, - 38 => CodePage::CP869, - 39 => CodePage::ISO8859_2, - 40 => CodePage::ISO8859_15, - 41 => CodePage::CP1098, // PC1098: Farsi - 42 => CodePage::CP774, - 43 => CodePage::CP772, - 44 => CodePage::CP1125, - 45 => CodePage::CP1250, - 46 => CodePage::CP1251, - 47 => CodePage::CP1253, - 48 => CodePage::CP1254, - 49 => CodePage::CP1255, - 50 => CodePage::CP1256, - 51 => CodePage::CP1257, - 52 => CodePage::CP1258, - 53 => CodePage::RK1048, - 66 => false, // Devanagari - 67 => false, // Bengali - 68 => false, // Tamil - 69 => false, // Telugu - 70 => false, // Assamese - 71 => false, // Oriya - 72 => false, // Kannada - 73 => false, // Malayalam - 74 => false, // Gujarati - 75 => false, // Punjabi - 82 => false, // Marathi - 254 => false, - 255 => false); - } - - function getSupportsBarcodeB() { - return true; - } - - function getSupportsBitImage() { - return true; - } - - function getSupportsGraphics() { - return true; - } - - function getSupportsStarCommands() { - return false; - } - - function getSupportsQrCode() { - return true; - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/DummyPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/DummyPrintConnector.php deleted file mode 100644 index e1a197b7c7b..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/DummyPrintConnector.php +++ /dev/null @@ -1,78 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Print connector that writes to nowhere, but allows the user to retrieve the - * buffered data. Used for testing. - */ -final class DummyPrintConnector implements PrintConnector { - /** - * @var array Buffer of accumilated data. - */ - private $buffer; - - /** - * @var string data which the printer will provide on next read - */ - private $readData; - - /** - * Create new print connector - */ - public function __construct() { - $this -> buffer = array(); - } - - public function __destruct() { - if($this -> buffer !== null) { - trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); - } - } - - public function finalize() { - $this -> buffer = null; - } - - /** - * @return string Get the accumulated data that has been sent to this buffer. - */ - public function getData() { - return implode($this -> buffer); - } - - /* (non-PHPdoc) - * @see PrintConnector::read() - */ - public function read($len) { - return $len >= strlen($this -> readData) ? $this -> readData : substr($this -> readData, 0, $len); - } - - public function write($data) { - $this -> buffer[] = $data; - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/EposTepCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/EposTepCapabilityProfile.php deleted file mode 100644 index 2803fe3f69c..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/EposTepCapabilityProfile.php +++ /dev/null @@ -1,4 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * This class deals with images in raster formats, and converts them into formats - * which are suitable for use on thermal receipt printers. Currently, only PNG - * images (in) and ESC/POS raster format (out) are implemeted. - * - * Input formats: - * - Currently, only PNG is supported. - * - Other easily read raster formats (jpg, gif) will be added at a later date, as this is not complex. - * - The BMP format can be directly read by some commands, but this has not yet been implemented. - * - * Output formats: - * - Currently, only ESC/POS raster format is supported - * - ESC/POS 'column format' support is partially implemented, but is not yet used by Escpos.php library. - * - Output as multiple rows of column format image is not yet in the works. - * - * Libraries: - * - Currently, php-gd is used to read the input. Support for imagemagick where gd is not installed is - * also not complex to add, and is a likely future feature. - * - Support for native use of the BMP format is a goal, for maximum compatibility with target environments. - */ -class EscposImage { - /** - * @var string The image's bitmap data (if it is a Windows BMP). - */ - protected $imgBmpData; - - /** - * @var string image data in rows: 1 for black, 0 for white. - */ - protected $imgData; - - /** - * @var string cached raster format data to avoid re-computation - */ - protected $imgRasterData; - - /** - * @var int height of the image - */ - protected $imgHeight; - - /** - * @var int width of the image - */ - protected $imgWidth; - - /** - * Load up an image from a filename - * - * @param string $imgPath The path to the image to load, or null to skip - * loading the image (some other functions are available for - * populating the data). Supported graphics types depend on your PHP configuration. - */ - public function __construct($imgPath = null) { - /* Can't use bitmaps yet */ - $this -> imgBmpData = null; - $this -> imgRasterData = null; - if($imgPath === null) { - // Blank image - $this -> imgHeight = 0; - $this -> imgWidth = 0; - $this -> imgData = ""; - return; - } - - /* Load up using GD */ - if(!file_exists($imgPath)) { - throw new Exception("File '$imgPath' does not exist."); - } - $ext = pathinfo($imgPath, PATHINFO_EXTENSION); - if($ext == "bmp") { - // The plan is to implement BMP handling directly in - // PHP, as some printers understand this format themselves. - // TODO implement PHP bitmap handling - throw new Exception("Native bitmaps not yet supported. Please convert the file to a supported raster format."); - } - if($this -> isGdSupported()) { - // Prefer to use gd. It is installed by default, so - // most systems will have it, giving a consistent UX. - switch($ext) { - case "png": - $im = @imagecreatefrompng($imgPath); - $this -> readImageFromGdResource($im); - return; - case "jpg": - $im = @imagecreatefromjpeg($imgPath); - $this -> readImageFromGdResource($im); - return; - case "gif": - $im = @imagecreatefromgif($imgPath); - $this -> readImageFromGdResource($im); - return; - } - } - if($this -> isImagickSupported()) { - $im = new Imagick(); - try { - // Throws an ImagickException if the format is not supported or file is not found - $im -> readImage($imgPath); - } catch(ImagickException $e) { - // Wrap in normal exception, so that classes which call this do not themselves require imagick as a dependency. - throw new Exception($e); - } - /* Flatten by doing a composite over white, in case of transparency */ - $flat = new Imagick(); - $flat -> newImage($im -> getimagewidth(), $im -> getimageheight(), "white"); - $flat -> compositeimage($im, Imagick::COMPOSITE_OVER, 0, 0); - $this -> readImageFromImagick($flat); - return; - } - throw new Exception("Images are not supported on your PHP. Please install either the gd or imagick extension."); - } - - /** - * @return int height of the image in pixels - */ - public function getHeight() { - return $this -> imgHeight; - } - - /** - * @return int Number of bytes to represent a row of this image - */ - public function getHeightBytes() { - return (int)(($this -> imgHeight + 7) / 8); - } - - /** - * @return int Width of the image - */ - public function getWidth() { - return $this -> imgWidth; - } - - /** - * @return int Number of bytes to represent a row of this image - */ - public function getWidthBytes() { - return (int)(($this -> imgWidth + 7) / 8); - } - - /** - * @return string binary data of the original file, for function which accept bitmaps. - */ - public function getWindowsBMPData() { - return $this -> imgBmpData; - } - - /** - * @return boolean True if the image was a windows bitmap, false otherwise - */ - public function isWindowsBMP() { - return $this -> imgBmpData != null; - } - - /** - * Load actual image pixels from GD resource. - * - * @param resouce $im GD resource to use - * @throws Exception Where the image can't be read. - */ - public function readImageFromGdResource($im) { - if(!is_resource($im)) { - throw new Exception("Failed to load image."); - } else if(!$this -> isGdSupported()) { - throw new Exception(__FUNCTION__ . " requires 'gd' extension."); - } - /* Make a string of 1's and 0's */ - $this -> imgHeight = imagesy($im); - $this -> imgWidth = imagesx($im); - $this -> imgData = str_repeat("\0", $this -> imgHeight * $this -> imgWidth); - for($y = 0; $y < $this -> imgHeight; $y++) { - for($x = 0; $x < $this -> imgWidth; $x++) { - /* Faster to average channels, blend alpha and negate the image here than via filters (tested!) */ - $cols = imagecolorsforindex($im, imagecolorat($im, $x, $y)); - $greyness = (int)(($cols['red'] + $cols['green'] + $cols['blue']) / 3) >> 7; // 1 for white, 0 for black - $black = (1 - $greyness) >> ($cols['alpha'] >> 6); // 1 for black, 0 for white, taking into account transparency - $this -> imgData[$y * $this -> imgWidth + $x] = $black; - } - } - } - - /** - * Load actual image pixels from Imagick object - * - * @param Imagick $im Image to load from - */ - public function readImageFromImagick(Imagick $im) { - /* Threshold */ - $im -> setImageType(Imagick::IMGTYPE_TRUECOLOR); // Remove transparency (good for PDF's) - $max = $im->getQuantumRange(); - $max = $max["quantumRangeLong"]; - $im -> thresholdImage(0.5 * $max); - /* Make a string of 1's and 0's */ - $geometry = $im -> getimagegeometry(); - $this -> imgHeight = $im -> getimageheight(); - $this -> imgWidth = $im -> getimagewidth(); - $this -> imgData = str_repeat("\0", $this -> imgHeight * $this -> imgWidth); - - for($y = 0; $y < $this -> imgHeight; $y++) { - for($x = 0; $x < $this -> imgWidth; $x++) { - /* Faster to average channels, blend alpha and negate the image here than via filters (tested!) */ - $cols = $im -> getImagePixelColor($x, $y); - $cols = $cols -> getcolor(); - $greyness = (int)(($cols['r'] + $cols['g'] + $cols['b']) / 3) >> 7; // 1 for white, 0 for black - $this -> imgData[$y * $this -> imgWidth + $x] = (1 - $greyness); // 1 for black, 0 for white - } - } - - } - - /** - * Output the image in raster (row) format. This can result in padding on the right of the image, if its width is not divisible by 8. - * - * @throws Exception Where the generated data is unsuitable for the printer (indicates a bug or oversized image). - * @return string The image in raster format. - */ - public function toRasterFormat() { - if($this -> imgRasterData != null) { - /* Use previous calculation */ - return $this -> imgRasterData; - } - /* Loop through and convert format */ - $widthPixels = $this -> getWidth(); - $heightPixels = $this -> getHeight(); - $widthBytes = $this -> getWidthBytes(); - $heightBytes = $this -> getHeightBytes(); - $x = $y = $bit = $byte = $byteVal = 0; - $data = str_repeat("\0", $widthBytes * $heightPixels); - if(strlen($data) == 0) { - return $data; - } - do { - $byteVal |= (int)$this -> imgData[$y * $widthPixels + $x] << (7 - $bit); - $x++; - $bit++; - if($x >= $widthPixels) { - $x = 0; - $y++; - $bit = 8; - if($y >= $heightPixels) { - $data[$byte] = chr($byteVal); - break; - } - } - if($bit >= 8) { - $data[$byte] = chr($byteVal); - $byteVal = 0; - $bit = 0; - $byte++; - } - } while(true); - if(strlen($data) != ($this -> getWidthBytes() * $this -> getHeight())) { - throw new Exception("Bug in " . __FUNCTION__ . ", wrong number of bytes."); - } - $this -> imgRasterData = $data; - return $this -> imgRasterData; - } - - /** - * Output image in column format. This format results in padding at the base and right of the image, if its height and width are not divisible by 8. - */ - private function toColumnFormat() { - /* Note: This function is marked private, as it is not yet used/tested and may be buggy. */ - $widthPixels = $this -> getWidth(); - $heightPixels = $this -> getHeight(); - $widthBytes = $this -> getWidthBytes(); - $heightBytes = $this -> getHeightBytes(); - $x = $y = $bit = $byte = $byteVal = 0; - $data = str_repeat("\0", $widthBytes * $heightBytes * 8); - do { - $byteVal |= (int)$this -> imgData[$y * $widthPixels + $x] << (8 - $bit); - $y++; - $bit++; - if($y >= $heightPixels) { - $y = 0; - $x++; - $bit = 8; - if($x >= $widthPixels) { - $data[$byte] = chr($byteVal); - break; - } - } - if($bit >= 8) { - $data[$byte] = chr($byteVal); - $byteVal = 0; - $bit = 0; - $byte++; - } - } while(true); - if(strlen($data) != ($widthBytes * $heightBytes * 8)) { - throw new Exception("Bug in " . __FUNCTION__ . ", wrong number of bytes. Should be " . ($widthBytes * $heightBytes * 8) . " but was " . strlen($data)); - } - return $data; - } - - /** - * @return boolean True if GD is supported, false otherwise (a wrapper for the static version, for mocking in tests) - */ - protected function isGdSupported() { - return self::isGdLoaded(); - } - - /** - * @return boolean True if Imagick is supported, false otherwise (a wrapper for the static version, for mocking in tests) - */ - protected function isImagickSupported() { - return self::isImagickLoaded(); - } - - - /** - * @return boolean True if GD is loaded, false otherwise - */ - public static function isGdLoaded() { - return extension_loaded('gd'); - } - - /** - * @return boolean True if Imagick is loaded, false otherwise - */ - public static function isImagickLoaded() { - return extension_loaded('imagick'); - } - - /** - * Load a PDF for use on the printer - * - * @param string $pdfFile The file to load - * @param string $pageWidth The width, in pixels, of the printer's output. The first page of the PDF will be scaled to approximately fit in this area. - * @param array $range array indicating the first and last page (starting from 0) to load. If not set, the entire document is loaded. - * @throws Exception Where Imagick is not loaded, or where a missing file or invalid page number is requested. - * @return multitype:EscposImage Array of images, retrieved from the PDF file. - */ - public static function loadPdf($pdfFile, $pageWidth = 550, array $range = null) { - if(!extension_loaded('imagick')) { - throw new Exception(__FUNCTION__ . " requires imagick extension."); - } - /* - * Load first page at very low density (resolution), to figure out what - * density to use to achieve $pageWidth - */ - try { - $image = new Imagick(); - $testRes = 2; // Test resolution - $image -> setresolution($testRes, $testRes); - $image -> readimage($pdfFile."[0]"); - $geo = $image -> getimagegeometry(); - $image -> destroy(); - $width = $geo['width']; - $newRes = $pageWidth / $width * $testRes; - /* Load actual document (can be very slow!) */ - $rangeStr = ""; // Set to [0] [0-1] page range if $range is set - if($range != null) { - if(count($range) != 2 || !isset($range[0]) || !is_integer($range[0]) || !isset($range[1]) || !is_integer($range[1]) || $range[0] > $range[1]) { - throw new Exception("Invalid range. Must be two numbers in the array: The start and finish page indexes, starting from 0."); - } - $rangeStr = "[" . ($range[0] == $range[1] ? $range[0] : implode($range, "-")) . "]"; - } - $image -> setresolution($newRes, $newRes); - $image -> readImage($pdfFile."$rangeStr"); - $pages = $image -> getNumberImages(); - /* Convert images to Escpos objects */ - $ret = array(); - for($i = 0;$i < $pages; $i++) { - $image -> setIteratorIndex($i); - $ep = new EscposImage(); - $ep -> readImageFromImagick($image); - $ret[] = $ep; - } - return $ret; - } catch(ImagickException $e) { - // Wrap in normal exception, so that classes which call this do not themselves require imagick as a dependency. - throw new Exception($e); - } - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/EscposPrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/EscposPrintBuffer.php deleted file mode 100644 index 703bc0a57c0..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/EscposPrintBuffer.php +++ /dev/null @@ -1,304 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * This class manages newlines and character encoding for the target printer, and - * can be interchanged for an image-bassed buffer (ImagePrintBuffer) if you can't - * get it operating properly on your machine. - */ -class EscposPrintBuffer implements PrintBuffer { - /** - * @var boolean True to cache output as .gz, false to leave un-compressed (useful for debugging) - */ - const COMPRESS_CACHE = true; - - /** - * @var string The input encoding of the buffer. - */ - const INPUT_ENCODING = "UTF-8"; - - /** - * @var string Un-recorgnised characters will be replaced with this. - */ - const REPLACEMENT_CHAR = "?"; - - /** - * This array Maps ESC/POS character tables to names iconv encodings - */ - private $available = null; - - /** - * @var array Maps of UTF-8 to code-pages - */ - private $encode = null; - - /** - * @var Escpos Printer for output - */ - private $printer; - - /** - * Empty print buffer. - */ - function __construct() { - $this -> printer = null; - } - - public function flush() { - if($this -> printer == null) { - throw new LogicException("Not attached to a printer."); - } - // TODO Not yet implemented for this buffer: This indicates that the printer needs the current line to be ended. - } - - public function getPrinter() { - return $this -> printer; - } - - public function setPrinter(Escpos $printer = null) { - $this -> printer = $printer; - if($printer != null) { - $this -> loadAvailableCharacters(); - } - } - - public function writeText($text) { - if($this -> printer == null) { - throw new LogicException("Not attached to a printer."); - } - if($text == null) { - return; - } - if(!mb_detect_encoding($text, self::INPUT_ENCODING, true)) { - // Assume that the user has already put non-UTF8 into the target encoding. - return $this -> writeTextRaw($text); - } - $i = 0; - $j = 0; - $len = mb_strlen($text, self::INPUT_ENCODING); - while($i < $len) { - $matching = true; - if(($encoding = $this -> identifyText(mb_substr($text, $i, 1, self::INPUT_ENCODING))) === false) { - // Un-encodeable text - $encoding = $this -> getPrinter() -> getCharacterTable(); - } - $i++; - $j = 1; - do { - $char = mb_substr($text, $i, 1, self::INPUT_ENCODING); - $matching = !isset($this -> available[$char]) || isset($this -> available[$char][$encoding]); - if($matching) { - $i++; - $j++; - } - } while($matching && $i < $len); - $this -> writeTextUsingEncoding(mb_substr($text, $i - $j, $j, self::INPUT_ENCODING), $encoding); - } - } - - public function writeTextRaw($text) { - if($this -> printer == null) { - throw new LogicException("Not attached to a printer."); - } - if(strlen($text) == 0) { - return; - } - // Pass only printable characters - for($i = 0; $i < strlen($text); $i++) { - $c = substr($text, $i, 1); - if(!self::asciiCheck($c, true)) { - $text[$i] = self::REPLACEMENT_CHAR; - } - } - $this -> write($text); - } - - /** - * Return an encoding which we can start to use for outputting this text. Later parts of the text need not be included in the returned code page. - * - * @param string $text Input text to check. - * @return boolean|integer Code page number, or FALSE if the text is not printable on any supported encoding. - */ - private function identifyText($text) { - // TODO Replace this with an algorithm to choose the encoding which will encode the farthest into the string, to minimise code page changes. - $char = mb_substr($text, 0, 1, self::INPUT_ENCODING); - if(!isset($this -> available[$char])) { - /* Character not available anywhere */ - return false; - } - foreach($this -> available[$char] as $encodingNo => $true) { - /* Return first code-page where it is available */ - return $encodingNo; - } - return false; - } - - /** - * Based on the printer's connector, compute (or load a cached copy of) maps of UTF character to unicode characters for later use. - */ - private function loadAvailableCharacters() { - $supportedCodePages = $this -> printer -> getPrinterCapabilityProfile() -> getSupportedCodePages(); - $capabilityClassName = get_class($this -> printer -> getPrinterCapabilityProfile()); - $cacheFile = dirname(__FILE__) . "/cache/Characters-" . $capabilityClassName . ".ser" . (self::COMPRESS_CACHE ? ".gz" : ""); - $cacheKey = md5(serialize($supportedCodePages)); - /* Check for pre-generated file */ - if(file_exists($cacheFile)) { - $cacheData = file_get_contents($cacheFile); - if(self::COMPRESS_CACHE) { - $cacheData = gzdecode($cacheData); - } - if($cacheData) { - $dataArray = unserialize($cacheData); - if(isset($dataArray["key"]) && isset($dataArray["available"]) && isset($dataArray["encode"]) && $dataArray["key"] == $cacheKey) { - $this -> available = $dataArray["available"]; - $this -> encode = $dataArray["encode"]; - return; - } - } - } - /* Generate conversion tables */ - $encode = array(); - $available = array(); - $custom = $this -> printer -> getPrinterCapabilityProfile() -> getCustomCodePages(); - - foreach($supportedCodePages as $num => $characterMap) { - $encode[$num] = array(); - if($characterMap === false) { - continue; - } else if(strpos($characterMap, ":") !== false) { - /* Load a pre-defined custom map (vendor-specific code pages) */ - $i = strpos($characterMap, ":"); - if(substr($characterMap, 0, $i) !== "custom") { - continue; - } - $i++; - $mapName = substr($characterMap, $i, strlen($characterMap) - $i); - if(!isset($custom[$mapName]) || mb_strlen($custom[$mapName], self::INPUT_ENCODING) != 128) { - throw new Exception("Capability profile referenced invalid custom map '$mapName'."); - } - $map = $custom[$mapName]; - for($char = 128; $char <= 255; $char++) { - $utf8 = mb_substr($map, $char - 128, 1, self::INPUT_ENCODING); - if($utf8 == " ") { // Skip placeholders - continue; - } - if(!isset($available[$utf8])) { - $available[$utf8] = array(); - } - $available[$utf8][$num] = true; - $encode[$num][$utf8] = chr($char); - } - } else { - /* Generate map using iconv */ - for($char = 128; $char <= 255; $char++) { - $utf8 = @iconv($characterMap, self::INPUT_ENCODING, chr($char)); - if($utf8 == '') { - continue; - } - if(iconv(self::INPUT_ENCODING, $characterMap, $utf8) != chr($char)) { - // Avoid non-canonical conversions - continue; - } - if(!isset($available[$utf8])) { - $available[$utf8] = array(); - } - $available[$utf8][$num] = true; - $encode[$num][$utf8] = chr($char); - } - } - } - /* Use generated data */ - $dataArray = array("available" => $available, "encode" => $encode, "key" => $cacheKey); - $this -> available = $dataArray["available"]; - $this -> encode = $dataArray["encode"]; - $cacheData = serialize($dataArray); - if(self::COMPRESS_CACHE) { - $cacheData = gzencode($cacheData); - } - /* Attempt to cache, but don't worry if we can't */ - @file_put_contents($cacheFile, $cacheData); - } - - /** - * Encode a block of text using the specified map, and write it to the printer. - * - * @param string $text Text to print, UTF-8 format. - * @param integer $encodingNo Encoding number to use- assumed to exist. - */ - private function writeTextUsingEncoding($text, $encodingNo) { - $encodeMap = $this -> encode[$encodingNo]; - $len = mb_strlen($text, self::INPUT_ENCODING); - $rawText = str_repeat(self::REPLACEMENT_CHAR, $len); - for($i = 0; $i < $len; $i++) { - $char = mb_substr($text, $i, 1, self::INPUT_ENCODING); - if(isset($encodeMap[$char])) { - $rawText[$i] = $encodeMap[$char]; - } else if(self::asciiCheck($char)) { - $rawText[$i] = $char; - } - } - if($this -> printer -> getCharacterTable() != $encodingNo) { - $this -> printer -> selectCharacterTable($encodingNo); - } - $this -> writeTextRaw($rawText); - } - - /** - * Write data to the underlying printer. - * - * @param string $data - */ - private function write($data) { - $this -> printer -> getPrintConnector() -> write($data); - } - - /** - * Return true if a character is an ASCII printable character. - * - * @param string $char Character to check - * @param boolean $extended True to allow 128-256 values also (excluded by default) - * @return boolean True if the character is printable, false if it is not. - */ - private static function asciiCheck($char, $extended = false) { - if(strlen($char) != 1) { - // Multi-byte string - return false; - } - $num = ord($char); - if($num > 31 && $num < 127) { // Printable - return true; - } - if($num == 10) { // New-line (printer will take these) - return true; - } - if($extended && $num > 127) { - return true; - } - return false; - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/FilePrintConnector.php b/htdocs/includes/mike42/escpos-php/src/FilePrintConnector.php deleted file mode 100644 index 8d87f0a527a..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/FilePrintConnector.php +++ /dev/null @@ -1,80 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * PrintConnector for passing print data to a file. - */ -class FilePrintConnector implements PrintConnector { - /** - * @var resource The file pointer to send data to. - */ - protected $fp; - - /** - * Construct new connector, given a filename - * - * @param string $filename - */ - public function __construct($filename) { - $this -> fp = fopen($filename, "wb+"); - if($this -> fp === false) { - throw new Exception("Cannot initialise FilePrintConnector."); - } - } - - public function __destruct() { - if($this -> fp !== false) { - trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); - } - } - - /** - * Close file pointer - */ - public function finalize() { - fclose($this -> fp); - $this -> fp = false; - } - - /* (non-PHPdoc) - * @see PrintConnector::read() - */ - public function read($len) { - rewind($this -> fp); - return fgets($this -> fp, $len + 1); - } - - /** - * Write data to the file - * - * @param string $data - */ - public function write($data) { - fwrite($this -> fp, $data); - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/ImagePrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/ImagePrintBuffer.php deleted file mode 100644 index 08ca64ac43e..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/ImagePrintBuffer.php +++ /dev/null @@ -1,99 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * This class renders text to small images on-the-fly. It attempts to mimic the - * behaviour of text output, whilst supporting any fonts & character encodings - * which your system can handle. This class currently requires Imagick. - */ -class ImagePrintBuffer implements PrintBuffer { - private $printer; - - function __construct() { - if(!EscposImage::isImagickLoaded()) { - throw new Exception("ImagePrintBuffer requires the imagick extension"); - } - } - - function flush() { - if($this -> printer == null) { - throw new LogicException("Not attached to a printer."); - } - } - - function getPrinter() { - return $this -> printer; - } - - function setPrinter(Escpos $printer = null) { - $this -> printer = $printer; - } - - function writeText($text) { - if($this -> printer == null) { - throw new LogicException("Not attached to a printer."); - } - if($text == null) { - return; - } - $text = trim($text, "\n"); - /* Create Imagick objects */ - $image = new Imagick(); - $draw = new ImagickDraw(); - $color = new ImagickPixel('#000000'); - $background = new ImagickPixel('white'); - - /* Create annotation */ - //$draw -> setFont('Arial');// (not necessary?) - $draw -> setFontSize(24); // Size 21 looks good for FONT B - $draw -> setFillColor($color); - $draw -> setStrokeAntialias(true); - $draw -> setTextAntialias(true); - $metrics = $image -> queryFontMetrics($draw, $text); - $draw -> annotation(0, $metrics['ascender'], $text); - - /* Create image & draw annotation on it */ - $image -> newImage($metrics['textWidth'], $metrics['textHeight'], $background); - $image -> setImageFormat('png'); - $image -> drawImage($draw); - //$image -> writeImage("test.png"); - - /* Save image */ - $escposImage = new EscposImage(); - $escposImage -> readImageFromImagick($image); - $size = Escpos::IMG_DEFAULT; - $this -> printer -> bitImage($escposImage, $size); - } - - function writeTextRaw($text) { - if($this -> printer == null) { - throw new LogicException("Not attached to a printer."); - } - $this -> printer -> getPrintConnector() -> write($data); - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfile.php new file mode 100644 index 00000000000..9a91390594e --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfile.php @@ -0,0 +1,348 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos; + +use \InvalidArgumentException; + +/** + * Store compatibility information about one printer. + */ +class CapabilityProfile +{ + + /** + * + * @var string $codePageCacheKey + * Hash of the code page data structure, to identify it for caching. + */ + protected $codePageCacheKey; + + /** + * + * @var array $codePages + * Associtive array of CodePage objects, indicating which encodings the printer supports. + */ + protected $codePages; + + /** + * + * @var array $colors + * Not used. + */ + protected $colors; + + /** + * + * @var array $features + * Feature values. + */ + protected $features; + + /** + * + * @var array $fonts + * Not used + */ + protected $fonts; + + /** + * + * @var array $media + * Not used + */ + protected $media; + + /** + * + * @var string $name + * Name of the profile, including model number. + */ + protected $name; + + /** + * + * @var string $notes + * Notes on the profile, null if not set. + */ + protected $notes; + + /** + * + * @var string $profileId + * ID of the profile. + */ + protected $profileId; + + + /** + * @var string $vendor + * Name of manufacturer. + */ + protected $vendor; + + /** + * + * @var array $encodings + * Data structure containing encodings loaded from disk, null if not loaded yet. + */ + protected static $encodings = null; + + /** + * + * @var array $profiles + * Data structure containing profiles loaded from disk, null if not loaded yet. + */ + protected static $profiles = null; + + /** + * Construct new CapabilityProfile. + * The encoding data must be loaded from disk before calling. + * + * @param string $profileId + * ID of the profile + * @param array $profileData + * Profile data from disk. + */ + protected function __construct($profileId, array $profileData) + { + // Basic primitive fields + $this->profileId = $profileId; + $this->name = $profileData['name']; + $this->notes = $profileData['notes']; + $this->vendor = $profileData['vendor']; + // More complex fields that are not currently loaded into custom objects + $this->features = $profileData['features']; + $this->colors = $profileData['colors']; + $this->fonts = $profileData['fonts']; + $this->media = $profileData['media']; + // More complex fields that are loaded into custom objects + $this->codePages = []; + $this->codePageCacheKey = md5(json_encode($profileData['codePages'])); + foreach ($profileData['codePages'] as $k => $v) { + $this->codePages[$k] = new CodePage($v, self::$encodings[$v]); + } + } + + /** + * + * @return string Hash of the code page data structure, to identify it for caching. + */ + public function getCodePageCacheKey() + { + return $this->codePageCacheKey; + } + + /** + * + * @return array Associtive array of CodePage objects, indicating which encodings the printer supports. + */ + public function getCodePages() + { + return $this->codePages; + } + + /** + * + * @param string $featureName + * Name of the feature to retrieve. + * @throws \InvalidArgumentException Where the feature does not exist. + * The exception will contain suggestions for the closest-named features. + * @return mixed feature value. + */ + public function getFeature($featureName) + { + if (isset($this->features[$featureName])) { + return $this->features[$featureName]; + } + $suggestionsArr = $this->suggestFeatureName($featureName); + $suggestionsStr = implode(", ", $suggestionsArr); + $str = "The feature '$featureName' does not exist. Try one that does exist, such as $suggestionsStr"; + throw new \InvalidArgumentException($str); + } + + /** + * + * @return string ID of the profile. + */ + public function getId() + { + return $this->profileId; + } + + /** + * + * @return string Name of the printer. + */ + public function getName() + { + return $this->name; + } + + /** + * + * @return boolean True if Barcode B command is supported, false otherwise + */ + public function getSupportsBarcodeB() + { + return $this->getFeature('barcodeB') === true; + } + + /** + * + * @return boolean True if Bit Image Raster command is supported, false otherwise + */ + public function getSupportsBitImageRaster() + { + return $this->getFeature('bitImageRaster') === true; + } + + /** + * + * @return boolean True if Graphics command is supported, false otherwise + */ + public function getSupportsGraphics() + { + return $this->getFeature('graphics') === true; + } + + /** + * + * @return boolean True if PDF417 code command is supported, false otherwise + */ + public function getSupportsPdf417Code() + { + // TODO submit 'pdf417Code' as a new feature to be tracked in upstream profiles + return $this->getFeature('qrCode') === true; + } + + /** + * + * @return boolean True if QR code command is supported, false otherwise + */ + public function getSupportsQrCode() + { + return $this->getFeature('qrCode') === true; + } + + /** + * + * @return boolean True if Star mode commands are supported, false otherwise + */ + public function getSupportsStarCommands() + { + return $this->getFeature('starCommands') === true; + } + + /** + * + * @return string Vendor of this printer. + */ + public function getVendor() + { + return $this->vendor; + } + + /** + * + * @param string $featureName + * Feature that does not exist + * @return array Three most similar feature names that do exist. + */ + protected function suggestFeatureName($featureName) + { + return self::suggestNearest($featureName, array_keys($this->features), 3); + } + + /** + * + * @return array Names of all profiles that exist. + */ + public static function getProfileNames() + { + self::loadCapabilitiesDataFile(); + return array_keys(self::$profiles); + } + + /** + * Retrieve the CapabilityProfile with the given ID. + * + * @param string $profileName + * The ID of the profile to load. + * @throws InvalidArgumentException Where the ID does not exist. Some similarly-named profiles will be suggested in the Exception text. + * @return CapabilityProfile The CapabilityProfile that was requested. + */ + public static function load($profileName) + { + self::loadCapabilitiesDataFile(); + if (! isset(self::$profiles[$profileName])) { + $suggestionsArray = self::suggestProfileName($profileName); + $suggestionsStr = implode(", ", $suggestionsArray); + throw new InvalidArgumentException("The CapabilityProfile '$profileName' does not exist. Try one that does exist, such as $suggestionsStr."); + } + return new CapabilityProfile($profileName, self::$profiles[$profileName]); + } + + /** + * Ensure that the capabilities.json data file has been loaded. + */ + protected static function loadCapabilitiesDataFile() + { + if (self::$profiles === null) { + $filename = dirname(__FILE__) . "/resources/capabilities.json"; + $capabilitiesData = json_decode(file_get_contents($filename), true); + self::$profiles = $capabilitiesData['profiles']; + self::$encodings = $capabilitiesData['encodings']; + } + } + + /** + * Return choices with smallest edit distance to an invalid input. + * + * @param string $input + * Input that is not a valid choice + * @param array $choices + * Array of valid choices. + * @param int $num + * Number of suggestions to return + */ + public static function suggestNearest($input, array $choices, $num) + { + $distances = array_fill_keys($choices, PHP_INT_MAX); + foreach ($distances as $word => $_) { + $distances[$word] = levenshtein($input, $word); + } + asort($distances); + return array_slice(array_keys($distances), 0, min($num, count($choices))); + } + + /** + * + * @param string $profileName + * profile name that does not exist + * @return array Three similar profile names that do exist, plus 'simple' and 'default' for good measure. + */ + protected static function suggestProfileName($profileName) + { + $suggestions = self::suggestNearest($profileName, array_keys(self::$profiles), 3); + $alwaysSuggest = [ + 'simple', + 'default' + ]; + foreach ($alwaysSuggest as $item) { + if (array_search($item, $suggestions) === false) { + array_push($suggestions, $item); + } + } + return $suggestions; + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/DefaultCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/DefaultCapabilityProfile.php new file mode 100644 index 00000000000..c574aed178b --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/DefaultCapabilityProfile.php @@ -0,0 +1,22 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ +namespace Mike42\Escpos\CapabilityProfiles; + +use Mike42\Escpos\CapabilityProfile; + +class DefaultCapabilityProfile +{ + public static function getInstance() + { + return CapabilityProfile::load('default'); + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/EposTepCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/EposTepCapabilityProfile.php new file mode 100644 index 00000000000..cc8e3ec5f3b --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/EposTepCapabilityProfile.php @@ -0,0 +1,22 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ +namespace Mike42\Escpos\CapabilityProfiles; + +use Mike42\Escpos\CapabilityProfile; + +class EposTepCapabilityProfile +{ + public static function getInstance() + { + return CapabilityProfile::load('TEP-200M'); + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/P822DCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/P822DCapabilityProfile.php new file mode 100644 index 00000000000..42ee3a0b4fa --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/P822DCapabilityProfile.php @@ -0,0 +1,22 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ +namespace Mike42\Escpos\CapabilityProfiles; + +use Mike42\Escpos\CapabilityProfile; + +class P822DCapabilityProfile +{ + public static function getInstance() + { + return CapabilityProfile::load('P822D'); + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/SimpleCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/SimpleCapabilityProfile.php new file mode 100644 index 00000000000..cb141b8b9b8 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/SimpleCapabilityProfile.php @@ -0,0 +1,22 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ +namespace Mike42\Escpos\CapabilityProfiles; + +use Mike42\Escpos\CapabilityProfile; + +class SimpleCapabilityProfile +{ + public static function getInstance() + { + return CapabilityProfile::load('simple'); + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/StarCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/StarCapabilityProfile.php new file mode 100644 index 00000000000..6e2f64c2c93 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfiles/StarCapabilityProfile.php @@ -0,0 +1,22 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ +namespace Mike42\Escpos\CapabilityProfiles; + +use Mike42\Escpos\CapabilityProfile; + +class StarCapabilityProfile +{ + public static function getInstance() + { + return CapabilityProfile::load('SP2000'); + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CodePage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CodePage.php new file mode 100644 index 00000000000..25f58b95369 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CodePage.php @@ -0,0 +1,181 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos; + +use \InvalidArgumentException; + +/** + * Class to handle data about a particular CodePage, as loaded from the receipt print + * database. + * + * Also computes map between UTF-8 and this encoding if necessary, using the iconv library. + */ +class CodePage +{ + /** + * The input encoding for generating character maps with iconv. + */ + const INPUT_ENCODING = "UTF-8"; + + /** + * @var string $data + * Data string, null if not known (can be computed with iconv) + */ + protected $data; + + /** + * @var string $iconv + * Iconv encoding name, null if not known + */ + protected $iconv; + + /** + * @var string $id + * Internal ID of the CodePage + */ + protected $id; + + /** + * @var string $name + * Name of the code page. Substituted with the ID if not set. + */ + protected $name; + + /** + * @var string $notes + * Notes on this code page, or null if not set. + */ + protected $notes; + + /** + * + * @param string $id + * Unique internal identifier for the CodePage. + * @param array $codePageData + * Associative array of CodePage data, as + * specified by the upstream receipt-print-hq/escpos-printer-db database. + * May contain 'name', 'data', 'iconv', and 'notes' fields. + */ + public function __construct($id, array $codePageData) + { + $this->id = $id; + $this->name = isset($codePageData['name']) ? $codePageData['name'] : $id; + $this->data = isset($codePageData['data']) ? implode("", $codePageData['data']) : null; + $this->iconv = isset($codePageData['iconv']) ? $codePageData['iconv'] : null; + $this->notes = isset($codePageData['notes']) ? $codePageData['notes'] : null; + } + + /** + * Get a 128-character data string representing this encoding. + * It will be + * calculated and cached if it was not previously known. + * + * @throws InvalidArgumentException Where the data is now known or computable. + * @return string Data for this encoding. + */ + public function getData() + { + if ($this->data !== null) { + // Return data if known + return $this->data; + } + if ($this->iconv !== null) { + // Calculate with iconv if we know the encoding name + $this->data = self::generateEncodingMap($this->iconv); + return $this->data; + } + // Can't encode.. + throw new InvalidArgumentException("Cannot encode this code page"); + } + + /** + * + * @return string Iconv encoding name, or blank if not set. + */ + public function getIconv() + { + return $this->iconv; + } + + /** + * + * @return string Unique identifier of the code page. + */ + public function getId() + { + return $this->id; + } + + /** + * Name of the code page. + */ + public function getName() + { + return $this->name; + } + + /** + * The notes may explain quirks about a code-page, such as a source if it's non-standard or un-encodeable. + * + * @return string Notes on the code page, or null if not set. + */ + public function getNotes() + { + return $this->notes; + } + + /** + * + * @return boolean True if we can encode with this code page (ie, we know what data it holds). + * + * Many printers contain vendor-specific code pages, which are named but have not been identified or + * typed out. For our purposes, this is an "un-encodeable" code page. + */ + public function isEncodable() + { + return $this->iconv !== null || $this->data !== null; + } + + /** + * Given an iconv encoding name, generate a 128-character UTF-8 string, containing code points 128-255. + * + * This string is used to map UTF-8 characters to their location in this code page. + * + * @param string $iconvName + * Name of the encoding + * @return string 128-character string in UTF-8. + */ + protected static function generateEncodingMap($iconvName) + { + // Start with array of blanks (" " indicates unknown character). + $charMap = array_fill(0, 128, " "); + // Loop through 128 code points + for ($char = 128; $char <= 255; $char ++) { + // Try to identify the UTF-8 character that would go here + $utf8 = @iconv($iconvName, self::INPUT_ENCODING, chr($char)); + if ($utf8 == '') { + continue; + } + if (iconv(self::INPUT_ENCODING, $iconvName, $utf8) != chr($char)) { + // Avoid non-canonical conversions (no known examples) + continue; + } + // Replace the ' ' with the correct character if we found it + $charMap[$char - 128] = $utf8; + } + // Join into a 128-character string and return. + $charMapStr = implode("", $charMap); + assert(mb_strlen($charMapStr, self::INPUT_ENCODING) == 128); + return $charMapStr; + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Devices/AuresCustomerDisplay.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Devices/AuresCustomerDisplay.php new file mode 100644 index 00000000000..3bf9101a4cf --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Devices/AuresCustomerDisplay.php @@ -0,0 +1,150 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\Devices; + +use Mike42\Escpos\Printer; + +/** + * A class for sending ESC/POS-like code to an Aures customer display. + * The display has some features that printers do not, such as an ability to "clear" the screen. + */ +class AuresCustomerDisplay extends Printer +{ + + /** + * Indicates that the text should wrap and type over + * existing text on the screen, rather than scroll. + */ + const TEXT_OVERWRITE = 1; + + /** + * Indicates that overflowing text should cause the + * display to scroll vertically, like a computer terminal. + */ + const TEXT_VERTICAL_SCROLL = 2; + + /** + * Indicates that overflowing text should cause the + * display to scroll horizontally, like a news ticker. + */ + const TEXT_HORIZONTAL_SCROLL = 3; + + /** + * + * {@inheritdoc} + * + * @see \Mike42\Escpos\Printer::initialize() + */ + public function initialize() + { + // Select ESC/POS mode first + $this->selectEscposMode(); + parent::initialize(); + // ESC @ does not reset character table on this printer + $this->selectCharacterTable(0); + // Default to horizontal scroll mode. Behaves most like a printer. + $this->selectTextScrollMode(AuresCustomerDisplay::TEXT_VERTICAL_SCROLL); + } + + /** + * Selects ESC/POS mode. + * + * This device supports other modes, which are not used. + */ + protected function selectEscposMode() + { + $this->connector->write("\x02\x05\x43\x31\x03"); + } + + /** + * + * @param int $mode + * The text scroll mode to use. One of + * AuresCustomerDisplay::TEXT_OVERWRITE, + * AuresCustomerDisplay::TEXT_VERTICAL_SCROLL or + * AuresCustomerDisplay::TEXT_HORIZONTAL_SCROLL + */ + public function selectTextScrollMode($mode = AuresCustomerDisplay::TEXT_VERTICAL_SCROLL) + { + self::validateInteger($mode, 1, 3, __FUNCTION__); + $this->connector->write("\x1F" . chr($mode)); + } + + /** + * Clear the display. + */ + public function clear() + { + $this->connector->write("\x0c"); + } + + /** + * Instruct the display to show the firmware version. + */ + public function showFirmwareVersion() + { + $this->connector->write("\x02\x05\x56\x01\x03"); + } + + /** + * Instruct the display to begin a self-test/demo sequence. + */ + public function selfTest() + { + $this->connector->write("\x02\x05\x44\x08\x03"); + } + + /** + * Instruct the display to show a pre-loaded logo. + * + * Note that this driver is not capable of uploading a + * logo, but that the vendor supplies software + * which has this function. + */ + public function showLogo() + { + $this->connector->write("\x02\xFC\x55\xAA\x55\xAA"); + } + + /** + * + * {@inheritdoc} + * + * @see \Mike42\Escpos\Printer::text() + */ + public function text($str = "") + { + self::validateString($str, __FUNCTION__); + // Need to intercept line-feeds, since "\n" is insufficient on this device. + foreach (explode("\n", $str) as $id => $line) { + if ($id > 0) { + $this->feed(); + } + parent::text($line); + } + } + + /** + * + * {@inheritdoc} + * + * @see \Mike42\Escpos\Printer::feed() + */ + public function feed($lines = 1) + { + self::validateInteger($lines, 1, 255, __FUNCTION__); + for ($i = 0; $i < $lines; $i ++) { + $this->connector->write("\r\n"); + } + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/EscposImage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/EscposImage.php new file mode 100644 index 00000000000..9a625acb47c --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/EscposImage.php @@ -0,0 +1,460 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos; + +use Exception; +use InvalidArgumentException; + +/** + * This class deals with images in raster formats, and converts them into formats + * which are suitable for use on thermal receipt printers. Currently, only PNG + * images (in) and ESC/POS raster format (out) are implemeted. + * + * Input formats: + * - Currently, only PNG is supported. + * - Other easily read raster formats (jpg, gif) will be added at a later date, as this is not complex. + * - The BMP format can be directly read by some commands, but this has not yet been implemented. + * + * Output formats: + * - Currently, only ESC/POS raster format is supported + * - ESC/POS 'column format' support is partially implemented, but is not yet used by Escpos.php library. + * - Output as multiple rows of column format image is not yet in the works. + * + * Libraries: + * - Currently, php-gd is used to read the input. Support for imagemagick where gd is not installed is + * also not complex to add, and is a likely future feature. + * - Support for native use of the BMP format is a goal, for maximum compatibility with target environments. + */ +abstract class EscposImage +{ + /** + * @var int $imgHeight + * height of the image. + */ + protected $imgHeight = 0; + + /** + * @var int $imgWidth + * width of the image + */ + protected $imgWidth = 0; + + /** + * @var string $imgData + * Image data in rows: 1 for black, 0 for white. + */ + private $imgData = null; + + /** + * @var array:string $imgColumnData + * Cached column-format data to avoid re-computation + */ + private $imgColumnData = []; + + /** + * @var string $imgRasterData + * Cached raster format data to avoid re-computation + */ + private $imgRasterData = null; + + /** + * @var string $filename + * Filename of image on disk - null if not loaded from disk. + */ + private $filename = null; + + /** + * @var boolean $allowOptimisations + * True to allow faster library-specific rendering shortcuts, false to always just use + * image libraries to read pixels (more reproducible between systems). + */ + private $allowOptimisations = true; + + /** + * Construct a new EscposImage. + * + * @param string $filename Path to image filename, or null to create an empty image. + * @param boolean $allowOptimisations True (default) to use any library-specific tricks + * to speed up rendering, false to force the image to be read in pixel-by-pixel, + * which is easier to unit test and more reproducible between systems, but slower. + */ + public function __construct($filename = null, $allowOptimisations = true) + { + $this -> filename = $filename; + $this -> allowOptimisations = $allowOptimisations; + } + + /** + * @return int height of the image in pixels + */ + public function getHeight() + { + return $this -> imgHeight; + } + + /** + * @return int Number of bytes to represent a row of this image + */ + public function getHeightBytes() + { + return (int)(($this -> imgHeight + 7) / 8); + } + + /** + * @return int Width of the image + */ + public function getWidth() + { + return $this -> imgWidth; + } + + /** + * @return int Number of bytes to represent a row of this image + */ + public function getWidthBytes() + { + return (int)(($this -> imgWidth + 7) / 8); + } + + /** + * Output the image in raster (row) format. This can result in padding on the + * right of the image, if its width is not divisible by 8. + * + * @throws Exception Where the generated data is unsuitable for the printer + * (indicates a bug or oversized image). + * @return string The image in raster format. + */ + public function toRasterFormat() + { + // Just wraps implementations for caching & lazy loading + if ($this -> imgRasterData !== null) { + /* Return cached value */ + return $this -> imgRasterData; + } + if ($this -> allowOptimisations) { + /* Use optimised code if allowed */ + $this -> imgRasterData = $this -> getRasterFormatFromFile($this -> filename); + } + if ($this -> imgRasterData === null) { + /* Load in full image and render the slow way if no faster implementation + is available, or if we've been asked not to use it */ + if ($this -> imgData === null) { + $this -> loadImageData($this -> filename); + } + $this -> imgRasterData = $this -> getRasterFormat(); + } + return $this -> imgRasterData; + } + + /** + * Output the image in column format. + * + * @param boolean $doubleDensity True for double density (24px) lines, false for single-density (8px) lines. + * @return string[] an array, one item per line of output. All lines will be of equal size. + */ + public function toColumnFormat($doubleDensity = false) + { + $densityIdx = $doubleDensity ? 1 : 0; + // Just wraps implementations for caching and lazy loading + if (isset($this -> imgColumnData[$densityIdx])) { + /* Return cached value */ + return $this -> imgColumnData[$densityIdx]; + } + $this -> imgColumnData[$densityIdx] = null; + if ($this -> allowOptimisations) { + /* Use optimised code if allowed */ + $data = $this -> getColumnFormatFromFile($this -> filename, $doubleDensity); + $this -> imgColumnData[$densityIdx] = $data; + } + if ($this -> imgColumnData[$densityIdx] === null) { + /* Load in full image and render the slow way if no faster implementation + is available, or if we've been asked not to use it */ + if ($this -> imgData === null) { + $this -> loadImageData($this -> filename); + } + $this -> imgColumnData[$densityIdx] = $this -> getColumnFormat($doubleDensity); + } + return $this -> imgColumnData[$densityIdx]; + } + + /** + * Load an image from disk. This default implementation always gives a zero-sized image. + * + * @param string|null $filename Filename to load from. + */ + protected function loadImageData($filename = null) + { + // Load image in to string of 1's and 0's, also set width & height + $this -> setImgWidth(0); + $this -> setImgHeight(0); + $this -> setImgData(""); + } + + /** + * Set image data. + * + * @param string $data Image data to use, string of 1's (black) and 0's (white) in row-major order. + */ + protected function setImgData($data) + { + $this -> imgData = $data; + } + + /** + * Set image width. + * + * @param int $width width of the image + */ + protected function setImgWidth($width) + { + $this -> imgWidth = $width; + } + + /** + * Set image height. + * + * @param int $height height of the image. + */ + protected function setImgHeight($height) + { + $this -> imgHeight = $height; + } + + /** + * @param string $filename + * Filename to load from + * @return string|NULL + * Raster format data, or NULL if no optimised renderer is available in + * this implementation. + */ + protected function getRasterFormatFromFile($filename = null) + { + // No optimised implementation to provide + return null; + } + + /** + * @param string $filename + * Filename to load from + * @param boolean $highDensityVertical + * True for high density output (24px lines), false for regular density (8px) + * @return string[]|NULL + * Column format data as array, or NULL if optimised renderer isn't + * available in this implementation. + */ + protected function getColumnFormatFromFile($filename = null, $highDensityVertical = true) + { + // No optimised implementation to provide + return null; + } + + /** + * Get column fromat from loaded image pixels, line by line. + * + * @throws Exception + * Where wrong number of bytes has been generated. + * @return string + * Raster format data + */ + private function getRasterFormat() + { + /* Loop through and convert format */ + $widthPixels = $this -> getWidth(); + $heightPixels = $this -> getHeight(); + $widthBytes = $this -> getWidthBytes(); + $heightBytes = $this -> getHeightBytes(); + $x = $y = $bit = $byte = $byteVal = 0; + $data = str_repeat("\0", $widthBytes * $heightPixels); + if (strlen($data) == 0) { + return $data; + } + do { + $byteVal |= (int)$this -> imgData[$y * $widthPixels + $x] << (7 - $bit); + $x++; + $bit++; + if ($x >= $widthPixels) { + $x = 0; + $y++; + $bit = 8; + if ($y >= $heightPixels) { + $data[$byte] = chr($byteVal); + break; + } + } + if ($bit >= 8) { + $data[$byte] = chr($byteVal); + $byteVal = 0; + $bit = 0; + $byte++; + } + } while (true); + if (strlen($data) != ($this -> getWidthBytes() * $this -> getHeight())) { + throw new Exception("Bug in " . __FUNCTION__ . ", wrong number of bytes."); + } + return $data; + } + + /** + * Get column fromat from loaded image pixels, line by line. + * + * @param boolean $highDensity + * True for high density output (24px lines), false for regular density (8px) + * @return string[] + * Array of column format data, one item per row. + */ + private function getColumnFormat($highDensity) + { + $out = []; + $i = 0; + while (($line = $this -> getColumnFormatLine($i, $highDensity)) !== null) { + $out[] = $line; + $i++; + } + return $out; + } + + /** + * Output image in column format. Must be called once for each line of output. + * + * @param int $lineNo + * Line number to retrieve + * @param bool $highDensity + * True for high density output (24px lines), false for regular density (8px) + * @throws Exception + * Where wrong number of bytes has been generated. + * @return NULL|string + * Column format data, or null if there is no more data (when iterating) + */ + private function getColumnFormatLine($lineNo, $highDensity) + { + // Currently double density in both directions, very experimental + $widthPixels = $this -> getWidth(); + $heightPixels = $this -> getHeight(); + $widthBytes = $this -> getWidthBytes(); + $heightBytes = $this -> getHeightBytes(); + $lineHeight = $highDensity ? 3 : 1; // Vertical density. 1 or 3 (for 8 and 24 pixel lines) + // Initialise to zero + $x = $y = $bit = $byte = $byteVal = 0; + $data = str_repeat("\x00", $widthPixels * $lineHeight); + $yStart = $lineHeight * 8 * $lineNo; + if ($yStart >= $heightPixels) { + return null; + } + if (strlen($data) == 0) { + return $data; + } + do { + $yReal = $y + $yStart; + if ($yReal < $heightPixels) { + $byteVal |= (int)$this -> imgData[$yReal * $widthPixels + $x] << (7 - $bit); + } + $y++; + $bit++; + if ($y >= $lineHeight * 8) { + $y = 0; + $x++; + $bit = 8; + if ($x >= $widthPixels) { + $data[$byte] = chr($byteVal); + break; + } + } + if ($bit >= 8) { + $data[$byte] = chr($byteVal); + $byteVal = 0; + $bit = 0; + $byte++; + } + } while (true); + if (strlen($data) != $widthPixels * $lineHeight) { + throw new Exception("Bug in " . __FUNCTION__ . ", wrong number of bytes."); + } + return $data; + } + + /** + * @return boolean True if GD is loaded, false otherwise + */ + public static function isGdLoaded() + { + return extension_loaded('gd'); + } + + /** + * @return boolean True if Imagick is loaded, false otherwise + */ + public static function isImagickLoaded() + { + return extension_loaded('imagick'); + } + + + /** + * This is a convinience method to load an image from file, auto-selecting + * an EscposImage implementation which uses an available library. + * + * The sub-classes can be constructed directly if you know that you will + * have Imagick or GD on the print server. + * + * @param string $filename + * File to load from + * @param bool $allowOptimisations + * True to allow the fastest rendering shortcuts, false to force the library + * to read the image into an internal raster format and use PHP to render + * the image (slower but less fragile). + * @param array $preferred + * Order to try to load libraries in- escpos-php supports pluggable image + * libraries. Items can be 'imagick', 'gd', 'native'. + * @throws Exception + * Where no suitable library could be found for the type of file being loaded. + * @return EscposImage + * + */ + public static function load( + $filename, + $allowOptimisations = true, + array $preferred = ['imagick', 'gd', 'native'] + ) { + /* Fail early if file is not readble */ + if (!file_exists($filename) || !is_readable($filename)) { + throw new Exception("File '$filename' does not exist, or is not readable."); + } + $ext = pathinfo($filename, PATHINFO_EXTENSION); + /* Choose the first implementation which can handle this format */ + foreach ($preferred as $implemetnation) { + if ($implemetnation === 'imagick') { + if (!self::isImagickLoaded()) { + // Skip option if Imagick is not loaded + continue; + } + return new \Mike42\Escpos\ImagickEscposImage($filename, $allowOptimisations); + } elseif ($implemetnation === 'gd') { + if (!self::isGdLoaded()) { + // Skip option if GD not loaded + continue; + } + return new \Mike42\Escpos\GdEscposImage($filename, $allowOptimisations); + } elseif ($implemetnation === 'native') { + if (!in_array($ext, ['wbmp', 'pbm', 'bmp'])) { + // Pure PHP is fastest way to generate raster output from wbmp and pbm formats. + continue; + } + return new \Mike42\Escpos\NativeEscposImage($filename, $allowOptimisations); + } else { + // Something else on the 'preferred' list. + throw new InvalidArgumentException("'$implemetnation' is not a known EscposImage implementation"); + } + } + throw new InvalidArgumentException("No suitable EscposImage implementation found for '$filename'."); + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php new file mode 100644 index 00000000000..32edf76ef7c --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php @@ -0,0 +1,86 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos; + +use Mike42\Escpos\EscposImage; +use Exception; + +/** + * Implementation of EscposImage using the GD PHP plugin. + */ +class GdEscposImage extends EscposImage +{ + /** + * Load an image from disk, into memory, using GD. + * + * @param string|null $filename The filename to load from + * @throws Exception if the image format is not supported, + * or the file cannot be opened. + */ + protected function loadImageData($filename = null) + { + if ($filename === null) { + /* Set to blank image */ + return parent::loadImageData($filename); + } + + $ext = pathinfo($filename, PATHINFO_EXTENSION); + switch ($ext) { + case "png": + $im = @imagecreatefrompng($filename); + break; + case "jpg": + $im = @imagecreatefromjpeg($filename); + break; + case "gif": + $im = @imagecreatefromgif($filename); + break; + default: + throw new Exception("Image format not supported in GD"); + } + $this -> readImageFromGdResource($im); + } + + /** + * Load actual image pixels from GD resource. + * + * @param resource $im GD resource to use + * @throws Exception Where the image can't be read. + */ + public function readImageFromGdResource($im) + { + if (!is_resource($im)) { + throw new Exception("Failed to load image."); + } elseif (!EscposImage::isGdLoaded()) { + throw new Exception(__FUNCTION__ . " requires 'gd' extension."); + } + /* Make a string of 1's and 0's */ + $imgHeight = imagesy($im); + $imgWidth = imagesx($im); + $imgData = str_repeat("\0", $imgHeight * $imgWidth); + for ($y = 0; $y < $imgHeight; $y++) { + for ($x = 0; $x < $imgWidth; $x++) { + /* Faster to average channels, blend alpha and negate the image here than via filters (tested!) */ + $cols = imagecolorsforindex($im, imagecolorat($im, $x, $y)); + // 1 for white, 0 for black, ignoring transparency + $greyness = (int)(($cols['red'] + $cols['green'] + $cols['blue']) / 3) >> 7; + // 1 for black, 0 for white, taking into account transparency + $black = (1 - $greyness) >> ($cols['alpha'] >> 6); + $imgData[$y * $imgWidth + $x] = $black; + } + } + $this -> setImgWidth($imgWidth); + $this -> setImgHeight($imgHeight); + $this -> setImgData($imgData); + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php new file mode 100644 index 00000000000..13851a4d034 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php @@ -0,0 +1,273 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos; + +use Exception; +use Imagick; +use Mike42\Escpos\EscposImage; + +/** + * Implementation of EscposImage using the Imagick PHP plugin. + */ +class ImagickEscposImage extends EscposImage +{ + /** + * Load actual image pixels from Imagick object + * + * @param Imagick $im Image to load from + */ + public function readImageFromImagick(\Imagick $im) + { + /* Strip transparency */ + $im = self::alphaRemove($im); + /* Threshold */ + $im -> setImageType(\Imagick::IMGTYPE_TRUECOLOR); // Remove transparency (good for PDF's) + $max = $im->getQuantumRange(); + $max = $max["quantumRangeLong"]; + $im -> thresholdImage(0.5 * $max); + /* Make a string of 1's and 0's */ + $imgHeight = $im -> getimageheight(); + $imgWidth = $im -> getimagewidth(); + $imgData = str_repeat("\0", $imgHeight * $imgWidth); + for ($y = 0; $y < $imgHeight; $y++) { + for ($x = 0; $x < $imgWidth; $x++) { + /* Faster to average channels, blend alpha and negate the image here than via filters (tested!) */ + $cols = $im -> getImagePixelColor($x, $y); + $cols = $cols -> getcolor(); + $greyness = (int)(($cols['r'] + $cols['g'] + $cols['b']) / 3) >> 7; // 1 for white, 0 for black + $imgData[$y * $imgWidth + $x] = (1 - $greyness); // 1 for black, 0 for white + } + } + $this -> setImgWidth($imgWidth); + $this -> setImgHeight($imgHeight); + $this -> setImgData($imgData); + } + + /** + * @param string $filename + * Filename to load from + * @param boolean $highDensityVertical + * True for high density output (24px lines), false for regular density (8px) + * @return string[]|NULL + * Column format data as array, or NULL if optimised renderer isn't + * available in this implementation. + */ + protected function getColumnFormatFromFile($filename = null, $highDensityVertical = true) + { + if ($filename === null) { + return null; + } + $im = $this -> getImageFromFile($filename); + $this -> setImgWidth($im -> getimagewidth()); + $this -> setImgHeight($im -> getimageheight()); + + /* Strip transparency */ + $im = self::alphaRemove($im); + $im -> setformat('pbm'); + $im -> getimageblob(); // Forces 1-bit rendering now, so that subsequent operations are faster + $im -> rotateImage('#fff', 90.0); + $im -> flopImage(); + $lineHeight = $highDensityVertical ? 3 : 1; + $blobs = $this -> getColumnFormatFromImage($im, $lineHeight * 8); + return $blobs; + } + + /** + * Load an image from disk, into memory, using Imagick. + * + * @param string|null $filename The filename to load from + * @throws Exception if the image format is not supported, + * or the file cannot be opened. + */ + protected function loadImageData($filename = null) + { + if ($filename === null) { + /* Set to blank image */ + return parent::loadImageData($filename); + } + + $im = $this -> getImageFromFile($filename); + $this -> readImageFromImagick($im); + } + + /** + * Return data in column format as array of slices. + * Operates recursively to save cloning larger image many times. + * + * @param Imagick $im + * @param int $lineHeight + * Height of printed line in dots. 8 or 24. + * @return string[] + */ + private function getColumnFormatFromImage(Imagick $im, $lineHeight) + { + $imgWidth = $im->getimagewidth(); + if ($imgWidth == $lineHeight) { + // Return glob of this panel + return [$this -> getRasterBlobFromImage($im)]; + } elseif ($imgWidth > $lineHeight) { + // Calculations + $slicesLeft = ceil($imgWidth / $lineHeight / 2); + $widthLeft = $slicesLeft * $lineHeight; + $widthRight = $imgWidth - $widthLeft; + // Slice up (left) + $left = clone $im; + $left -> extentimage($widthLeft, $left -> getimageheight(), 0, 0); + // Slice up (right - ensure width is divisible by lineHeight also) + $right = clone $im; + $widthRightRounded = $widthRight < $lineHeight ? $lineHeight : $widthRight; + $right -> extentimage($widthRightRounded, $right -> getimageheight(), $widthLeft, 0); + // Recurse + $leftBlobs = $this -> getColumnFormatFromImage($left, $lineHeight); + $rightBlobs = $this -> getColumnFormatFromImage($right, $lineHeight); + return array_merge($leftBlobs, $rightBlobs); + } else { + /* Image is smaller than full width */ + $im -> extentimage($lineHeight, $im -> getimageheight(), 0, 0); + return [$this -> getRasterBlobFromImage($im)]; + } + } + + /** + * Load Imagick file from image + * + * @param string $filename Filename to load + * @throws Exception Wrapped Imagick error if image can't be loaded + * @return Imagick Loaded image + */ + private function getImageFromFile($filename) + { + $im = new Imagick(); + try { + $im->setResourceLimit(6, 1); // Prevent libgomp1 segfaults, grumble grumble. + $im -> readimage($filename); + } catch (\ImagickException $e) { + /* Re-throw as normal exception */ + throw new Exception($e); + } + return $im; + } + + /** + * Pull blob (from PBM-formatted image only!), and spit out a blob or raster data. + * Will crash out on anything which is not a valid 'P4' file. + * + * @param Imagick $im Image which has format PBM. + * @return string raster data from the image + */ + private function getRasterBlobFromImage(Imagick $im) + { + $blob = $im -> getimageblob(); + /* Find where header ends */ + $i = strpos($blob, "P4\n") + 2; + while ($blob[$i + 1] == '#') { + $i = strpos($blob, "\n", $i + 1); + } + $i = strpos($blob, "\n", $i + 1); + /* Return raster data only */ + $subBlob = substr($blob, $i + 1); + return $subBlob; + } + + /** + * @param string $filename + * Filename to load from + * @return string|NULL + * Raster format data, or NULL if no optimised renderer is available in + * this implementation. + */ + protected function getRasterFormatFromFile($filename = null) + { + if ($filename === null) { + return null; + } + $im = $this -> getImageFromFile($filename); + $this -> setImgWidth($im -> getimagewidth()); + $this -> setImgHeight($im -> getimageheight()); + /* Convert to PBM and extract raster portion */ + $im = self::alphaRemove($im); + $im -> setFormat('pbm'); + return $this -> getRasterBlobFromImage($im); + } + + /** + * Load a PDF for use on the printer + * + * @param string $pdfFile + * The file to load + * @param int $pageWidth + * The width, in pixels, of the printer's output. The first page of the + * PDF will be scaled to approximately fit in this area. + * @throws Exception Where Imagick is not loaded, or where a missing file + * or invalid page number is requested. + * @return array Array of images, retrieved from the PDF file. + */ + public static function loadPdf($pdfFile, $pageWidth = 550) + { + if (!EscposImage::isImagickLoaded()) { + throw new Exception(__FUNCTION__ . " requires imagick extension."); + } + /* + * Load first page at very low density (resolution), to figure out what + * density to use to achieve $pageWidth + */ + try { + $image = new \Imagick(); + $testRes = 2; // Test resolution + $image -> setresolution($testRes, $testRes); + /* Load document just to measure geometry */ + $image -> readimage($pdfFile); + $geo = $image -> getimagegeometry(); + $image -> destroy(); + $width = $geo['width']; + $newRes = $pageWidth / $width * $testRes; + /* Load entire document in */ + $image -> setresolution($newRes, $newRes); + $image -> readImage($pdfFile); + $pages = $image -> getNumberImages(); + /* Convert images to Escpos objects */ + $ret = []; + for ($i = 0; $i < $pages; $i++) { + $image -> setIteratorIndex($i); + $ep = new ImagickEscposImage(); + $ep -> readImageFromImagick($image); + $ret[] = $ep; + } + return $ret; + } catch (\ImagickException $e) { + /* Wrap in normal exception, so that classes which call this do not + * themselves require imagick as a dependency. */ + throw new Exception($e); + } + } + + /** + * Paste image over white canvas to stip transparency reliably on different + * versions of ImageMagick. + * + * There are other methods for this: + * - flattenImages() is deprecated + * - setImageAlphaChannel(Imagick::ALPHACHANNEL_REMOVE) is not available on + * ImageMagick < 6.8. + * + * @param Imagick $im Image to flatten + * @return Imagick Flattened image + */ + private static function alphaRemove(Imagick $im) + { + $flat = new \Imagick(); + $flat -> newImage($im -> getimagewidth(), $im -> getimageheight(), "white", $im -> getimageformat()); + $flat -> compositeimage($im, \Imagick::COMPOSITE_OVER, 0, 0); + return $flat; + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/NativeEscposImage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/NativeEscposImage.php new file mode 100644 index 00000000000..e85c942b2c3 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/NativeEscposImage.php @@ -0,0 +1,24 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos; + +use Mike42\Escpos\EscposImage; + +/** + * Implementation of EscposImage using only native PHP. + * TODO: wbmp, pbm, bmp files. + */ +class NativeEscposImage extends EscposImage +{ + +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php new file mode 100644 index 00000000000..4e04176521e --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php @@ -0,0 +1,300 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintBuffers; + +use LogicException; +use Mike42\Escpos\Printer; + +/** + * This class manages newlines and character encoding for the target printer, and + * can be interchanged for an image-bassed buffer (ImagePrintBuffer) if you can't + * get it operating properly on your machine. + */ +class EscposPrintBuffer implements PrintBuffer +{ + /** + * True to cache output as .z, false to leave un-compressed (useful for debugging) + */ + const COMPRESS_CACHE = true; + + /** + * The input encoding of the buffer. + */ + const INPUT_ENCODING = "UTF-8"; + + /** + * Un-recognised characters will be replaced with this. + */ + const REPLACEMENT_CHAR = "?"; + + /** + * @var array $available + * This array Maps ESC/POS character tables to names iconv encodings + */ + private $available = null; + + /** + * @var array $encode + * Maps of UTF-8 to code-pages + */ + private $encode = null; + + /** + * @var Printer|null $printer + * Printer for output + */ + private $printer; + + /** + * Empty print buffer. + */ + public function __construct() + { + $this -> printer = null; + } + + public function flush() + { + if ($this -> printer == null) { + throw new LogicException("Not attached to a printer."); + } + // TODO Not yet implemented for this buffer: This indicates that the printer needs the current line to be ended. + } + + public function getPrinter() + { + return $this -> printer; + } + + public function setPrinter(Printer $printer = null) + { + $this -> printer = $printer; + if ($printer != null) { + $this -> loadAvailableCharacters(); + } + } + + public function writeText($text) + { + if ($this -> printer == null) { + throw new LogicException("Not attached to a printer."); + } + if ($text == null) { + return; + } + if (!mb_detect_encoding($text, self::INPUT_ENCODING, true)) { + // Assume that the user has already put non-UTF8 into the target encoding. + return $this -> writeTextRaw($text); + } + $i = 0; + $j = 0; + $len = mb_strlen($text, self::INPUT_ENCODING); + while ($i < $len) { + $matching = true; + if (($encoding = $this -> identifyText(mb_substr($text, $i, 1, self::INPUT_ENCODING))) === false) { + // Un-encodeable text + $encoding = $this -> getPrinter() -> getCharacterTable(); + } + $i++; + $j = 1; + do { + $char = mb_substr($text, $i, 1, self::INPUT_ENCODING); + $matching = !isset($this -> available[$char]) || isset($this -> available[$char][$encoding]); + if ($matching) { + $i++; + $j++; + } + } while ($matching && $i < $len); + $this -> writeTextUsingEncoding(mb_substr($text, $i - $j, $j, self::INPUT_ENCODING), $encoding); + } + } + + public function writeTextRaw($text) + { + if ($this -> printer == null) { + throw new LogicException("Not attached to a printer."); + } + if (strlen($text) == 0) { + return; + } + // Pass only printable characters + $j = 0; + $l = strlen($text); + $outp = str_repeat(self::REPLACEMENT_CHAR, $l); + for ($i = 0; $i < $l; $i++) { + $c = substr($text, $i, 1); + if ($c == "\r") { + /* Skip past Windows line endings (raw usage). */ + continue; + } else if (self::asciiCheck($c, true)) { + $outp[$j] = $c; + } + $j++; + } + $this -> write(substr($outp, 0, $j)); + } + + /** + * Return an encoding which we can start to use for outputting this text. + * Later parts of the text need not be included in the returned code page. + * + * @param string $text Input text to check. + * @return boolean|integer Code page number, or FALSE if the text is not + * printable on any supported encoding. + */ + private function identifyText($text) + { + // TODO Replace this with an algorithm to choose the encoding which will + // encode the farthest into the string, to minimise code page changes. + $char = mb_substr($text, 0, 1, self::INPUT_ENCODING); + if (!isset($this -> available[$char])) { + /* Character not available anywhere */ + return false; + } + foreach ($this -> available[$char] as $encodingNo => $true) { + /* Return first code-page where it is available */ + return $encodingNo; + } + return false; + } + + /** + * Based on the printer's connector, compute (or load a cached copy of) maps + * of UTF character to unicode characters for later use. + */ + private function loadAvailableCharacters() + { + $profile = $this -> printer -> getPrinterCapabilityProfile(); + $supportedCodePages = $profile -> getCodePages(); + $profileName = $profile -> getId(); + $cacheFile = dirname(__FILE__) . "/cache/Characters-" . $profileName . ".ser" . + (self::COMPRESS_CACHE ? ".z" : ""); + $cacheKey = $profile -> getCodePageCacheKey(); + /* Check for pre-generated file */ + if (file_exists($cacheFile)) { + $cacheData = file_get_contents($cacheFile); + if (self::COMPRESS_CACHE) { + $cacheData = gzuncompress($cacheData); + } + if ($cacheData) { + $dataArray = unserialize($cacheData); + if (isset($dataArray["key"]) && isset($dataArray["available"]) && + isset($dataArray["encode"]) && $dataArray["key"] == $cacheKey) { + $this -> available = $dataArray["available"]; + $this -> encode = $dataArray["encode"]; + return; + } + } + } + + /* Generate conversion tables */ + $encode = []; + $available = []; + + foreach ($supportedCodePages as $num => $codePage) { + $encode[$num] = []; + if (!$codePage -> isEncodable()) { + continue; + } + $map = $codePage -> getData(); + for ($char = 128; $char <= 255; $char++) { + $utf8 = mb_substr($map, $char - 128, 1, self::INPUT_ENCODING); + if ($utf8 == " ") { // Skip placeholders + continue; + } + if (!isset($available[$utf8])) { + $available[$utf8] = []; + } + $available[$utf8][$num] = true; + $encode[$num][$utf8] = chr($char); + } + } + + /* Use generated data */ + $dataArray = ["available" => $available, "encode" => $encode, "key" => $cacheKey]; + $this -> available = $dataArray["available"]; + $this -> encode = $dataArray["encode"]; + $cacheData = serialize($dataArray); + if (self::COMPRESS_CACHE) { + $cacheData = gzcompress($cacheData); + } + /* Attempt to cache, but don't worry if we can't */ + @file_put_contents($cacheFile, $cacheData); + } + + /** + * Encode a block of text using the specified map, and write it to the printer. + * + * @param string $text Text to print, UTF-8 format. + * @param integer $encodingNo Encoding number to use- assumed to exist. + */ + private function writeTextUsingEncoding($text, $encodingNo) + { + $encodeMap = $this -> encode[$encodingNo]; + $len = mb_strlen($text, self::INPUT_ENCODING); + $rawText = str_repeat(self::REPLACEMENT_CHAR, $len); + $j = 0; + for ($i = 0; $i < $len; $i++) { + $char = mb_substr($text, $i, 1, self::INPUT_ENCODING); + if (isset($encodeMap[$char])) { + $rawText[$j] = $encodeMap[$char]; + } elseif (self::asciiCheck($char)) { + $rawText[$j] = $char; + } elseif ($char === "\r") { + /* Skip past Windows line endings (UTF-8 usage) */ + continue; + } + $j++; + } + if ($this -> printer -> getCharacterTable() != $encodingNo) { + $this -> printer -> selectCharacterTable($encodingNo); + } + $this -> writeTextRaw(substr($rawText, 0, $j)); + } + + /** + * Write data to the underlying printer. + * + * @param string $data + */ + private function write($data) + { + $this -> printer -> getPrintConnector() -> write($data); + } + + /** + * Return true if a character is an ASCII printable character. + * + * @param string $char Character to check + * @param boolean $extended True to allow 128-256 values also (excluded by default) + * @return boolean True if the character is printable, false if it is not. + */ + private static function asciiCheck($char, $extended = false) + { + if (strlen($char) != 1) { + // Multi-byte string + return false; + } + $num = ord($char); + if ($num > 31 && $num < 127) { // Printable + return true; + } + if ($num == 10) { // New-line (printer will take these) + return true; + } + if ($extended && $num > 127) { + return true; + } + return false; + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php new file mode 100644 index 00000000000..d4fdefaf130 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php @@ -0,0 +1,135 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintBuffers; + +use Exception; +use LogicException; +use Mike42\Escpos\Printer; +use Mike42\Escpos\EscposImage; +use Mike42\Escpos\ImagickEscposImage; + +/** + * This class renders text to small images on-the-fly. It attempts to mimic the + * behaviour of text output, whilst supporting any fonts & character encodings + * which your system can handle. This class currently requires Imagick. + */ +class ImagePrintBuffer implements PrintBuffer +{ + private $printer; + + /** + * @var string|null font to use + */ + private $font; + + private $fontSize; + + public function __construct() + { + if (!EscposImage::isImagickLoaded()) { + throw new Exception("ImagePrintBuffer requires the imagick extension"); + } + $this -> font = null; + $this -> fontSize = 24; + } + + public function flush() + { + if ($this -> printer == null) { + throw new LogicException("Not attached to a printer."); + } + } + + public function getPrinter() + { + return $this -> printer; + } + + public function setPrinter(Printer $printer = null) + { + $this -> printer = $printer; + } + + public function writeText($text) + { + if ($this -> printer == null) { + throw new LogicException("Not attached to a printer."); + } + if ($text == null) { + return; + } + $text = trim($text, "\n"); + /* Create Imagick objects */ + $image = new \Imagick(); + $draw = new \ImagickDraw(); + $color = new \ImagickPixel('#000000'); + $background = new \ImagickPixel('white'); + + /* Create annotation */ + if ($this->font !== null) { + // Allow fallback on defaults as necessary + $draw->setFont($this->font); + } + /* In Arial, size 21 looks good as a substitute for FONT_B, 24 for FONT_A */ + $draw -> setFontSize($this -> fontSize); + $draw -> setFillColor($color); + $draw -> setStrokeAntialias(true); + $draw -> setTextAntialias(true); + $metrics = $image -> queryFontMetrics($draw, $text); + $draw -> annotation(0, $metrics['ascender'], $text); + + /* Create image & draw annotation on it */ + $image -> newImage($metrics['textWidth'], $metrics['textHeight'], $background); + $image -> setImageFormat('png'); + $image -> drawImage($draw); + // debugging if you want to view the images yourself + //$image -> writeImage("test.png"); + + /* Save image */ + $escposImage = new ImagickEscposImage(); + $escposImage -> readImageFromImagick($image); + $size = Printer::IMG_DEFAULT; + $this -> printer -> bitImage($escposImage, $size); + } + + public function writeTextRaw($text) + { + if ($this -> printer == null) { + throw new LogicException("Not attached to a printer."); + } + $this -> printer -> getPrintConnector() -> write($text); + } + + /** + * Set path on disk to TTF font that will be used to render text to image, + * or 'null' to use a default. + * + * ImageMagick will also accept a font name, but this will not port as well + * between systems. + * + * @param string $font + * Font name or a filename + */ + public function setFont($font) + { + $this->font = $font; + } + + /** + * Numeric font size for rendering text to image + */ + public function setFontSize($fontSize) + { + $this->fontSize = $fontSize; + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/PrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/PrintBuffer.php new file mode 100644 index 00000000000..fcad6e9e0bb --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/PrintBuffer.php @@ -0,0 +1,63 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintBuffers; + +use Mike42\Escpos\Printer; + +/** + * Print buffers manage newlines and character encoding for the target printer. + * They are used as a swappable component: text or image-based output. + * + * - Text output (EscposPrintBuffer) is the fast default, and is recommended for + * most people, as the text output can be more directly manipulated by ESC/POS + * commands. + * - Image output (ImagePrintBuffer) is designed to accept more encodings than the + * physical printer supports, by rendering the text to small images on-the-fly. + * This takes a lot more CPU than sending text, but is necessary for some users. + * - If your use case fits outside these, then a further speed/flexibility trade-off + * can be made by printing directly from generated HTML or PDF. + */ +interface PrintBuffer +{ + /** + * Cause the buffer to send any partial input and wait on a newline. + * If the printer is already on a new line, this does nothing. + */ + public function flush(); + + /** + * Used by Escpos to check if a printer is set. + */ + public function getPrinter(); + + /** + * Used by Escpos to hook up one-to-one link between buffers and printers. + * + * @param Printer|null $printer New printer + */ + public function setPrinter(Printer $printer = null); + + /** + * Accept UTF-8 text for printing. + * + * @param string $text Text to print + */ + public function writeText($text); + + /** + * Accept 8-bit text in the current encoding and add it to the buffer. + * + * @param string $text Text to print, already the target encoding. + */ + public function writeTextRaw($text); +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-OCD-300.ser.z b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-OCD-300.ser.z new file mode 100644 index 0000000000000000000000000000000000000000..c0b9adb9d97ed1f7e2788ef0c595a4917e6288fb GIT binary patch literal 6934 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 literal 0 HcmV?d00001 diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-POS-5890.ser.z b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-POS-5890.ser.z new file mode 100644 index 0000000000000000000000000000000000000000..948e135c9b97fbf6a2689ab65ec22971e255ce1c GIT binary patch literal 12537 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 literal 0 HcmV?d00001 diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-SP2000.ser.z b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-SP2000.ser.z new file mode 100644 index 0000000000000000000000000000000000000000..c5ac146d0b5890f6412f7acea7426d393e4de759 GIT binary patch literal 9267 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 literal 0 HcmV?d00001 diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-TEP-200M.ser.z b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/cache/Characters-TEP-200M.ser.z new file mode 100644 index 0000000000000000000000000000000000000000..3e6b190290ee024bb10117596baa233a0a29f35d GIT binary patch literal 13740 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 = new Client(['base_uri' => $host]); + $this->printerId = $printerId; + $this->apiToken = $apiToken; + + $this->stream = ''; + } + + /** + * Print connectors should cause a NOTICE if they are deconstructed + * when they have not been finalized. + */ + public function __destruct() + { + if (! empty($this->stream)) { + trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); + } + } + + /** + * Finish using this print connector (close file, socket, send + * accumulated output, etc). + */ + public function finalize() + { + /** @var Request $request */ + $request = $this->httpClient->post( + 'printers/'.$this->printerId.'/print?api_token='.$this->apiToken, + null, + $this->stream + ); + + /** @var Response $response */ + $response = $request->send(); + + if (! $response->isSuccessful()) { + throw new Exception( + sprintf('Failed to print. API returned "%s: %s"', $response->getStatusCode(), $response->getReasonPhrase()) + ); + } + + $this->stream = ''; + } + + /** + * Read data from the printer. + * + * @param string $len Length of data to read. + * @return string Data read from the printer. + */ + public function read($len) + { + return $this->stream; + } + + /** + * Write data to the print connector. + * + * @param string $data The data to write + */ + public function write($data) + { + $this->stream .= $data; + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php new file mode 100644 index 00000000000..497887f37cd --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php @@ -0,0 +1,182 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintConnectors; + +use Exception; +use BadMethodCallException; + +/** + * Print connector that passes print data to CUPS print commands. + * Your printer mut be installed on the local CUPS instance to use this connector. + */ +class CupsPrintConnector implements PrintConnector +{ + + /** + * @var array $buffer + * Buffer of accumilated data. + */ + private $buffer; + + /** + * + * @var string $printerName + * The name of the target printer. + */ + private $printerName; + + /** + * Construct new CUPS print connector. + * + * @param string $dest + * The CUPS printer name to print to. This must be loaded using a raw driver. + * @throws BadMethodCallException + */ + public function __construct($dest) + { + $valid = $this->getLocalPrinters(); + if (count($valid) == 0) { + throw new BadMethodCallException("You do not have any printers installed on " . + "this system via CUPS. Check 'lpr -a'."); + } + + if (array_search($dest, $valid, true) === false) { + throw new BadMethodCallException("'$dest' is not a printer on this system. " . + "Printers are: [" . implode(", ", $valid) . "]"); + } + $this->buffer = array (); + $this->printerName = $dest; + } + + /** + * Cause a NOTICE if deconstructed before the job was printed. + */ + public function __destruct() + { + if ($this->buffer !== null) { + trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); + } + } + + /** + * Send job to printer. + */ + public function finalize() + { + $data = implode($this->buffer); + $this->buffer = null; + + // Build command to work on data + $tmpfname = tempnam(sys_get_temp_dir(), 'print-'); + file_put_contents($tmpfname, $data); + $cmd = sprintf( + "lp -d %s %s", + escapeshellarg($this->printerName), + escapeshellarg($tmpfname) + ); + try { + $this->getCmdOutput($cmd); + } catch (Exception $e) { + unlink($tmpfname); + throw $e; + } + unlink($tmpfname); + } + + /** + * Run a command and throw an exception if it fails, or return the output if it works. + * (Basically exec() with good error handling) + * + * @param string $cmd + * Command to run + */ + protected function getCmdOutput($cmd) + { + $descriptors = array ( + 1 => array ( + "pipe", + "w" + ), + 2 => array ( + "pipe", + "w" + ) + ); + $process = proc_open($cmd, $descriptors, $fd); + if (! is_resource($process)) { + throw new Exception("Command '$cmd' failed to start."); + } + /* Read stdout */ + $outputStr = stream_get_contents($fd [1]); + fclose($fd [1]); + /* Read stderr */ + $errorStr = stream_get_contents($fd [2]); + fclose($fd [2]); + /* Finish up */ + $retval = proc_close($process); + if ($retval != 0) { + throw new Exception("Command $cmd failed: $errorStr"); + } + return $outputStr; + } + + /** + * Read data from the printer. + * + * @param string $len Length of data to read. + * @return Data read from the printer, or false where reading is not possible. + */ + public function read($len) + { + return false; + } + + /** + * @param string $data + */ + public function write($data) + { + $this->buffer [] = $data; + } + + /** + * Load a list of CUPS printers. + * + * @return array A list of printer names installed on this system. Any item + * on this list is valid for constructing a printer. + */ + protected function getLocalPrinters() + { + $outpStr = $this->getCmdOutput("lpstat -a"); + $outpLines = explode("\n", trim($outpStr)); + foreach ($outpLines as $line) { + $ret [] = $this->chopLpstatLine($line); + } + return $ret; + } + + /** + * Get the item before the first space in a string + * + * @param string $line + * @return string the string, up to the first space, or the whole string if it contains no spaces. + */ + private function chopLpstatLine($line) + { + if (($pos = strpos($line, " ")) === false) { + return $line; + } else { + return substr($line, 0, $pos); + } + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php new file mode 100644 index 00000000000..b376cd87d83 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php @@ -0,0 +1,78 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintConnectors; + +/** + * Print connector that writes to nowhere, but allows the user to retrieve the + * buffered data. Used for testing. + */ +final class DummyPrintConnector implements PrintConnector +{ + /** + * @var array $buffer + * Buffer of accumilated data. + */ + private $buffer; + + /** + * @var string data which the printer will provide on next read + */ + private $readData; + + /** + * Create new print connector + */ + public function __construct() + { + $this -> buffer = []; + } + + public function clear() + { + $this -> buffer = []; + } + + public function __destruct() + { + if ($this -> buffer !== null) { + trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); + } + } + + public function finalize() + { + $this -> buffer = null; + } + + /** + * @return string Get the accumulated data that has been sent to this buffer. + */ + public function getData() + { + return implode($this -> buffer); + } + + /** + * {@inheritDoc} + * @see PrintConnector::read() + */ + public function read($len) + { + return $len >= strlen($this -> readData) ? $this -> readData : substr($this -> readData, 0, $len); + } + + public function write($data) + { + $this -> buffer[] = $data; + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php new file mode 100644 index 00000000000..ca44ad0ad7e --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php @@ -0,0 +1,82 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintConnectors; + +use Exception; + +/** + * PrintConnector for passing print data to a file. + */ +class FilePrintConnector implements PrintConnector +{ + /** + * @var resource $fp + * The file pointer to send data to. + */ + protected $fp; + + /** + * Construct new connector, given a filename + * + * @param string $filename + */ + public function __construct($filename) + { + $this -> fp = fopen($filename, "wb+"); + if ($this -> fp === false) { + throw new Exception("Cannot initialise FilePrintConnector."); + } + } + + public function __destruct() + { + if ($this -> fp !== false) { + trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); + } + } + + /** + * Close file pointer + */ + public function finalize() + { + if ($this -> fp !== false) { + fclose($this -> fp); + $this -> fp = false; + } + } + + /* (non-PHPdoc) + * @see PrintConnector::read() + */ + public function read($len) + { + if ($this -> fp === false) { + throw new Exception("PrintConnector has been closed, cannot read input."); + } + return fread($this -> fp, $len); + } + + /** + * Write data to the file + * + * @param string $data + */ + public function write($data) + { + if ($this -> fp === false) { + throw new Exception("PrintConnector has been closed, cannot send output."); + } + fwrite($this -> fp, $data); + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/NetworkPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/NetworkPrintConnector.php new file mode 100644 index 00000000000..10aa6640a01 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/NetworkPrintConnector.php @@ -0,0 +1,41 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintConnectors; + +use Exception; + +/** + * PrintConnector for directly opening a network socket to a printer to send it commands. + */ +class NetworkPrintConnector extends FilePrintConnector +{ + /** + * Construct a new NetworkPrintConnector + * + * @param string $ip IP address or hostname to use. + * @param string $port The port number to connect on. + * @param string $timeout The connection timeout, in seconds. + * @throws Exception Where the socket cannot be opened. + */ + public function __construct($ip, $port = "9100", $timeout = false) + { + // Default to 60 if default_socket_timeout isn't defined in the ini + $defaultSocketTimeout = ini_get("default_socket_timeout") ?: 60; + $timeout = $timeout ?: $defaultSocketTimeout; + + $this -> fp = @fsockopen($ip, $port, $errno, $errstr, $timeout); + if ($this -> fp === false) { + throw new Exception("Cannot initialise NetworkPrintConnector: " . $errstr); + } + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/PrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/PrintConnector.php new file mode 100644 index 00000000000..4198dbc133b --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/PrintConnector.php @@ -0,0 +1,47 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintConnectors; + +/** + * Interface passed to Escpos class for receiving print data. Print connectors + * are responsible for transporting this to the actual printer. + */ +interface PrintConnector +{ + /** + * Print connectors should cause a NOTICE if they are deconstructed + * when they have not been finalized. + */ + public function __destruct(); + + /** + * Finish using this print connector (close file, socket, send + * accumulated output, etc). + */ + public function finalize(); + + /** + * Read data from the printer. + * + * @param string $len Length of data to read. + * @return Data read from the printer, or false where reading is not possible. + */ + public function read($len); + + /** + * Write data to the print connector. + * + * @param string $data The data to write + */ + public function write($data); +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/RawbtPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/RawbtPrintConnector.php new file mode 100644 index 00000000000..622f7263d9e --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/RawbtPrintConnector.php @@ -0,0 +1,81 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintConnectors; + +/** + * Print connector for android RawBT application + * https://play.google.com/store/apps/details?id=ru.a402d.rawbtprinter + */ +final class RawbtPrintConnector implements PrintConnector +{ + /** + * @var array $buffer + * Buffer of accumilated data. + */ + private $buffer; + + /** + * @var string data which the printer will provide on next read + */ + private $readData; + + /** + * Create new print connector + */ + public function __construct() + { + ob_start(); + $this->buffer = []; + } + + public function clear() + { + $this->buffer = []; + } + + public function __destruct() + { + if ($this->buffer !== null) { + trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); + } + } + + public function finalize() + { + ob_end_clean(); + echo "intent:base64," . base64_encode($this->getData()) . "#Intent;scheme=rawbt;package=ru.a402d.rawbtprinter;end;"; + $this->buffer = null; + } + + /** + * @return string Get the accumulated data that has been sent to this buffer. + */ + public function getData() + { + return implode($this->buffer); + } + + /** + * {@inheritDoc} + * @see PrintConnector::read() + */ + public function read($len) + { + return $len >= strlen($this->readData) ? $this->readData : substr($this->readData, 0, $len); + } + + public function write($data) + { + $this->buffer[] = $data; + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/UriPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/UriPrintConnector.php new file mode 100644 index 00000000000..c51d2bf3350 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/UriPrintConnector.php @@ -0,0 +1,44 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintConnectors; + +class UriPrintConnector +{ + const URI_ASSEMBLER_PATTERN = "~^(.+):/{2}(.+?)(?::(\d{1,4}))?$~"; + + public static function get($uri) + { + // Parse URI + $is_uri = preg_match(self::URI_ASSEMBLER_PATTERN, $uri, $uri_parts); + if ($is_uri !== 1) { + throw new \InvalidArgumentException("Malformed connector URI: {$uri}"); + } + // Extract parts + $protocol = $uri_parts[1]; + $printer = $uri_parts[2]; + $port = isset($uri_parts[3]) ? $uri_parts[3] : 9100; + // Initialise the most applicable print connector + switch ($protocol) { + case "file": + return new FilePrintConnector($printer); + case "tcp": + return new NetworkPrintConnector($printer, $port); + case "smb": + return new WindowsPrintConnector($uri); + } + // Fallthrough + throw new \InvalidArgumentException("URI sheme is not supported: {$protocol}://"); + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/WindowsPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/WindowsPrintConnector.php new file mode 100644 index 00000000000..9bab87cddb8 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/WindowsPrintConnector.php @@ -0,0 +1,391 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos\PrintConnectors; + +use Exception; +use BadMethodCallException; + +/** + * Connector for sending print jobs to + * - local ports on windows (COM1, LPT1, etc) + * - shared (SMB) printers from any platform (smb://server/foo) + * For USB printers or other ports, the trick is to share the printer with a + * generic text driver, then connect to the shared printer locally. + */ +class WindowsPrintConnector implements PrintConnector +{ + /** + * @var array $buffer + * Accumulated lines of output for later use. + */ + private $buffer; + + /** + * @var string $hostname + * The hostname of the target machine, or null if this is a local connection. + */ + private $hostname; + + /** + * @var boolean $isLocal + * True if a port is being used directly (must be Windows), false if network shares will be used. + */ + private $isLocal; + + /** + * @var int $platform + * Platform we're running on, for selecting different commands. See PLATFORM_* constants. + */ + private $platform; + + /** + * @var string $printerName + * The name of the target printer (eg "Foo Printer") or port ("COM1", "LPT1"). + */ + private $printerName; + + /** + * @var string $userName + * Login name for network printer, or null if not using authentication. + */ + private $userName; + + /** + * @var string $userPassword + * Password for network printer, or null if no password is required. + */ + private $userPassword; + + /** + * @var string $workgroup + * Workgroup that the printer is located on + */ + private $workgroup; + + /** + * Represents Linux + */ + const PLATFORM_LINUX = 0; + + /** + * Represents Mac + */ + const PLATFORM_MAC = 1; + + /** + * Represents Windows + */ + const PLATFORM_WIN = 2; + + /** + * Valid local ports. + */ + const REGEX_LOCAL = "/^(LPT\d|COM\d)$/"; + + /** + * Valid printer name. + */ + const REGEX_PRINTERNAME = "/^[\d\w-]+(\s[\d\w-]+)*$/"; + + /** + * Valid smb:// URI containing hostname & printer with optional user & optional password only. + */ + const REGEX_SMB = "/^smb:\/\/([\s\d\w-]+(:[\s\d\w+-]+)?@)?([\d\w-]+\.)*[\d\w-]+\/([\d\w-]+\/)?[\d\w-]+(\s[\d\w-]+)*$/"; + + /** + * @param string $dest + * @throws BadMethodCallException + */ + public function __construct($dest) + { + $this -> platform = $this -> getCurrentPlatform(); + $this -> isLocal = false; + $this -> buffer = null; + $this -> userName = null; + $this -> userPassword = null; + $this -> workgroup = null; + if (preg_match(self::REGEX_LOCAL, $dest) == 1) { + // Straight to LPT1, COM1 or other local port. Allowed only if we are actually on windows. + if ($this -> platform !== self::PLATFORM_WIN) { + throw new BadMethodCallException("WindowsPrintConnector can only be " . + "used to print to a local printer ('".$dest."') on a Windows computer."); + } + $this -> isLocal = true; + $this -> hostname = null; + $this -> printerName = $dest; + } elseif (preg_match(self::REGEX_SMB, $dest) == 1) { + // Connect to samba share, eg smb://host/printer + $part = parse_url($dest); + $this -> hostname = $part['host']; + /* Printer name and optional workgroup */ + $path = ltrim($part['path'], '/'); + if (strpos($path, "/") !== false) { + $pathPart = explode("/", $path); + $this -> workgroup = $pathPart[0]; + $this -> printerName = $pathPart[1]; + } else { + $this -> printerName = $path; + } + /* Username and password if set */ + if (isset($part['user'])) { + $this -> userName = $part['user']; + if (isset($part['pass'])) { + $this -> userPassword = $part['pass']; + } + } + } elseif (preg_match(self::REGEX_PRINTERNAME, $dest) == 1) { + // Just got a printer name. Assume it's on the current computer. + $hostname = gethostname(); + if (!$hostname) { + $hostname = "localhost"; + } + $this -> hostname = $hostname; + $this -> printerName = $dest; + } else { + throw new BadMethodCallException("Printer '" . $dest . "' is not a valid " . + "printer name. Use local port (LPT1, COM1, etc) or smb://computer/printer notation."); + } + $this -> buffer = []; + } + + public function __destruct() + { + if ($this -> buffer !== null) { + trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); + } + } + + public function finalize() + { + $data = implode($this -> buffer); + $this -> buffer = null; + if ($this -> platform == self::PLATFORM_WIN) { + $this -> finalizeWin($data); + } elseif ($this -> platform == self::PLATFORM_LINUX) { + $this -> finalizeLinux($data); + } else { + $this -> finalizeMac($data); + } + } + + /** + * Send job to printer -- platform-specific Linux code. + * + * @param string $data Print data + * @throws Exception + */ + protected function finalizeLinux($data) + { + /* Non-Windows samba printing */ + $device = "//" . $this -> hostname . "/" . $this -> printerName; + if ($this -> userName !== null) { + $user = ($this -> workgroup != null ? ($this -> workgroup . "\\") : "") . $this -> userName; + if ($this -> userPassword == null) { + // No password + $command = sprintf( + "smbclient %s -U %s -c %s -N -m SMB2", + escapeshellarg($device), + escapeshellarg($user), + escapeshellarg("print -") + ); + $redactedCommand = $command; + } else { + // With password + $command = sprintf( + "smbclient %s %s -U %s -c %s -m SMB2", + escapeshellarg($device), + escapeshellarg($this -> userPassword), + escapeshellarg($user), + escapeshellarg("print -") + ); + $redactedCommand = sprintf( + "smbclient %s %s -U %s -c %s -m SMB2", + escapeshellarg($device), + escapeshellarg("*****"), + escapeshellarg($user), + escapeshellarg("print -") + ); + } + } else { + // No authentication information at all + $command = sprintf( + "smbclient %s -c %s -N -m SMB2", + escapeshellarg($device), + escapeshellarg("print -") + ); + $redactedCommand = $command; + } + $retval = $this -> runCommand($command, $outputStr, $errorStr, $data); + if ($retval != 0) { + throw new Exception("Failed to print. Command \"$redactedCommand\" " . + "failed with exit code $retval: " . trim($errorStr) . trim($outputStr)); + } + } + + /** + * Send job to printer -- platform-specific Mac code. + * + * @param string $data Print data + * @throws Exception + */ + protected function finalizeMac($data) + { + throw new Exception("Mac printing not implemented."); + } + + /** + * Send data to printer -- platform-specific Windows code. + * + * @param string $data + */ + protected function finalizeWin($data) + { + /* Windows-friendly printing of all sorts */ + if (!$this -> isLocal) { + /* Networked printing */ + $device = "\\\\" . $this -> hostname . "\\" . $this -> printerName; + if ($this -> userName !== null) { + /* Log in */ + $user = "/user:" . ($this -> workgroup != null ? ($this -> workgroup . "\\") : "") . $this -> userName; + if ($this -> userPassword == null) { + $command = sprintf( + "net use %s %s", + escapeshellarg($device), + escapeshellarg($user) + ); + $redactedCommand = $command; + } else { + $command = sprintf( + "net use %s %s %s", + escapeshellarg($device), + escapeshellarg($user), + escapeshellarg($this -> userPassword) + ); + $redactedCommand = sprintf( + "net use %s %s %s", + escapeshellarg($device), + escapeshellarg($user), + escapeshellarg("*****") + ); + } + $retval = $this -> runCommand($command, $outputStr, $errorStr); + if ($retval != 0) { + throw new Exception("Failed to print. Command \"$redactedCommand\" " . + "failed with exit code $retval: " . trim($errorStr)); + } + } + /* Final print-out */ + $filename = tempnam(sys_get_temp_dir(), "escpos"); + file_put_contents($filename, $data); + if (!$this -> runCopy($filename, $device)) { + throw new Exception("Failed to copy file to printer"); + } + unlink($filename); + } else { + /* Drop data straight on the printer */ + if (!$this -> runWrite($data, $this -> printerName)) { + throw new Exception("Failed to write file to printer at " . $this -> printerName); + } + } + } + + /** + * @return string Current platform. Separated out for testing purposes. + */ + protected function getCurrentPlatform() + { + if (PHP_OS == "WINNT") { + return self::PLATFORM_WIN; + } + if (PHP_OS == "Darwin") { + return self::PLATFORM_MAC; + } + return self::PLATFORM_LINUX; + } + + /* (non-PHPdoc) + * @see PrintConnector::read() + */ + public function read($len) + { + /* Two-way communication is not supported */ + return false; + } + + /** + * Run a command, pass it data, and retrieve its return value, standard output, and standard error. + * + * @param string $command the command to run. + * @param string $outputStr variable to fill with standard output. + * @param string $errorStr variable to fill with standard error. + * @param string $inputStr text to pass to the command's standard input (optional). + * @return number + */ + protected function runCommand($command, &$outputStr, &$errorStr, $inputStr = null) + { + $descriptors = [ + 0 => ["pipe", "r"], + 1 => ["pipe", "w"], + 2 => ["pipe", "w"], + ]; + $process = proc_open($command, $descriptors, $fd); + if (is_resource($process)) { + /* Write to input */ + if ($inputStr !== null) { + fwrite($fd[0], $inputStr); + } + fclose($fd[0]); + /* Read stdout */ + $outputStr = stream_get_contents($fd[1]); + fclose($fd[1]); + /* Read stderr */ + $errorStr = stream_get_contents($fd[2]); + fclose($fd[2]); + /* Finish up */ + $retval = proc_close($process); + return $retval; + } else { + /* Method calling this should notice a non-zero exit and print an error */ + return -1; + } + } + + /** + * Copy a file. Separated out so that nothing is actually printed during test runs. + * + * @param string $from Source file + * @param string $to Destination file + * @return boolean True if copy was successful, false otherwise + */ + protected function runCopy($from, $to) + { + return copy($from, $to); + } + + /** + * Write data to a file. Separated out so that nothing is actually printed during test runs. + * + * @param string $data Data to print + * @param string $filename Destination file + * @return boolean True if write was successful, false otherwise + */ + protected function runWrite($data, $filename) + { + return file_put_contents($filename, $data) !== false; + } + + public function write($data) + { + $this -> buffer[] = $data; + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php new file mode 100644 index 00000000000..753d2ea8ad3 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php @@ -0,0 +1,1217 @@ +, + * incorporating modifications by others. See CONTRIBUTORS.md for a full list. + * + * This software is distributed under the terms of the MIT license. See LICENSE.md + * for details. + */ + +namespace Mike42\Escpos; + +use Exception; +use InvalidArgumentException; +use Mike42\Escpos\PrintBuffers\PrintBuffer; +use Mike42\Escpos\PrintBuffers\EscposPrintBuffer; +use Mike42\Escpos\PrintConnectors\PrintConnector; +use Mike42\Escpos\CapabilityProfile; + +/** + * Main class for ESC/POS code generation + */ +class Printer +{ + /** + * ASCII null control character + */ + const NUL = "\x00"; + + /** + * ASCII linefeed control character + */ + const LF = "\x0a"; + + /** + * ASCII escape control character + */ + const ESC = "\x1b"; + + /** + * ASCII form separator control character + */ + const FS = "\x1c"; + + /** + * ASCII form feed control character + */ + const FF = "\x0c"; + + /** + * ASCII group separator control character + */ + const GS = "\x1d"; + + /** + * ASCII data link escape control character + */ + const DLE = "\x10"; + + /** + * ASCII end of transmission control character + */ + const EOT = "\x04"; + + /** + * Indicates UPC-A barcode when used with Printer::barcode + */ + const BARCODE_UPCA = 65; + + /** + * Indicates UPC-E barcode when used with Printer::barcode + */ + const BARCODE_UPCE = 66; + + /** + * Indicates JAN13 barcode when used with Printer::barcode + */ + const BARCODE_JAN13 = 67; + + /** + * Indicates JAN8 barcode when used with Printer::barcode + */ + const BARCODE_JAN8 = 68; + + /** + * Indicates CODE39 barcode when used with Printer::barcode + */ + const BARCODE_CODE39 = 69; + + /** + * Indicates ITF barcode when used with Printer::barcode + */ + const BARCODE_ITF = 70; + + /** + * Indicates CODABAR barcode when used with Printer::barcode + */ + const BARCODE_CODABAR = 71; + + /** + * Indicates CODE93 barcode when used with Printer::barcode + */ + const BARCODE_CODE93 = 72; + + /** + * Indicates CODE128 barcode when used with Printer::barcode + */ + const BARCODE_CODE128 = 73; + + /** + * Indicates that HRI (human-readable interpretation) text should not be + * printed, when used with Printer::setBarcodeTextPosition + */ + const BARCODE_TEXT_NONE = 0; + + /** + * Indicates that HRI (human-readable interpretation) text should be printed + * above a barcode, when used with Printer::setBarcodeTextPosition + */ + const BARCODE_TEXT_ABOVE = 1; + + /** + * Indicates that HRI (human-readable interpretation) text should be printed + * below a barcode, when used with Printer::setBarcodeTextPosition + */ + const BARCODE_TEXT_BELOW = 2; + + /** + * Use the first color (usually black), when used with Printer::setColor + */ + const COLOR_1 = 0; + + /** + * Use the second color (usually red or blue), when used with Printer::setColor + */ + const COLOR_2 = 1; + + /** + * Make a full cut, when used with Printer::cut + */ + const CUT_FULL = 65; + + /** + * Make a partial cut, when used with Printer::cut + */ + const CUT_PARTIAL = 66; + + /** + * Use Font A, when used with Printer::setFont + */ + const FONT_A = 0; + + /** + * Use Font B, when used with Printer::setFont + */ + const FONT_B = 1; + + /** + * Use Font C, when used with Printer::setFont + */ + const FONT_C = 2; + + /** + * Use default (high density) image size, when used with Printer::graphics, + * Printer::bitImage or Printer::bitImageColumnFormat + */ + const IMG_DEFAULT = 0; + + /** + * Use lower horizontal density for image printing, when used with Printer::graphics, + * Printer::bitImage or Printer::bitImageColumnFormat + */ + const IMG_DOUBLE_WIDTH = 1; + + /** + * Use lower vertical density for image printing, when used with Printer::graphics, + * Printer::bitImage or Printer::bitImageColumnFormat + */ + const IMG_DOUBLE_HEIGHT = 2; + + /** + * Align text to the left, when used with Printer::setJustification + */ + const JUSTIFY_LEFT = 0; + + /** + * Center text, when used with Printer::setJustification + */ + const JUSTIFY_CENTER = 1; + + /** + * Align text to the right, when used with Printer::setJustification + */ + const JUSTIFY_RIGHT = 2; + + /** + * Use Font A, when used with Printer::selectPrintMode + */ + const MODE_FONT_A = 0; + + /** + * Use Font B, when used with Printer::selectPrintMode + */ + const MODE_FONT_B = 1; + + /** + * Use text emphasis, when used with Printer::selectPrintMode + */ + const MODE_EMPHASIZED = 8; + + /** + * Use double height text, when used with Printer::selectPrintMode + */ + const MODE_DOUBLE_HEIGHT = 16; + + /** + * Use double width text, when used with Printer::selectPrintMode + */ + const MODE_DOUBLE_WIDTH = 32; + + /** + * Underline text, when used with Printer::selectPrintMode + */ + const MODE_UNDERLINE = 128; + + /** + * Indicates standard PDF417 code + */ + const PDF417_STANDARD = 0; + + /** + * Indicates truncated PDF417 code + */ + const PDF417_TRUNCATED = 1; + + /** + * Indicates error correction level L when used with Printer::qrCode + */ + const QR_ECLEVEL_L = 0; + + /** + * Indicates error correction level M when used with Printer::qrCode + */ + const QR_ECLEVEL_M = 1; + + /** + * Indicates error correction level Q when used with Printer::qrCode + */ + const QR_ECLEVEL_Q = 2; + + /** + * Indicates error correction level H when used with Printer::qrCode + */ + const QR_ECLEVEL_H = 3; + + /** + * Indicates QR model 1 when used with Printer::qrCode + */ + const QR_MODEL_1 = 1; + + /** + * Indicates QR model 2 when used with Printer::qrCode + */ + const QR_MODEL_2 = 2; + + /** + * Indicates micro QR code when used with Printer::qrCode + */ + const QR_MICRO = 3; + + /** + * Indicates a request for printer status when used with + * Printer::getPrinterStatus (experimental) + */ + const STATUS_PRINTER = 1; + + /** + * Indicates a request for printer offline cause when used with + * Printer::getPrinterStatus (experimental) + */ + const STATUS_OFFLINE_CAUSE = 2; + + /** + * Indicates a request for error cause when used with Printer::getPrinterStatus + * (experimental) + */ + const STATUS_ERROR_CAUSE = 3; + + /** + * Indicates a request for error cause when used with Printer::getPrinterStatus + * (experimental) + */ + const STATUS_PAPER_ROLL = 4; + + /** + * Indicates a request for ink A status when used with Printer::getPrinterStatus + * (experimental) + */ + const STATUS_INK_A = 7; + + /** + * Indicates a request for ink B status when used with Printer::getPrinterStatus + * (experimental) + */ + const STATUS_INK_B = 6; + + /** + * Indicates a request for peeler status when used with Printer::getPrinterStatus + * (experimental) + */ + const STATUS_PEELER = 8; + + /** + * Indicates no underline when used with Printer::setUnderline + */ + const UNDERLINE_NONE = 0; + + /** + * Indicates single underline when used with Printer::setUnderline + */ + const UNDERLINE_SINGLE = 1; + + /** + * Indicates double underline when used with Printer::setUnderline + */ + const UNDERLINE_DOUBLE = 2; + + /** + * @var PrintBuffer|null $buffer + * The printer's output buffer. + */ + protected $buffer; + + /** + * @var PrintConnector $connector + * Connector showing how to print to this printer + */ + protected $connector; + + /** + * @var CapabilityProfile $profile + * Profile showing supported features for this printer + */ + protected $profile; + + /** + * @var int $characterTable + * Current character code table + */ + protected $characterTable; + + /** + * Construct a new print object + * + * @param PrintConnector $connector The PrintConnector to send data to. If not set, output is sent to standard output. + * @param CapabilityProfile|null $profile Supported features of this printer. If not set, the "default" CapabilityProfile will be used, which is suitable for Epson printers. + * @throws InvalidArgumentException + */ + public function __construct(PrintConnector $connector, CapabilityProfile $profile = null) + { + /* Set connector */ + $this -> connector = $connector; + + /* Set capability profile */ + if ($profile === null) { + $profile = CapabilityProfile::load('default'); + } + $this -> profile = $profile; + /* Set buffer */ + $buffer = new EscposPrintBuffer(); + $this -> buffer = null; + $this -> setPrintBuffer($buffer); + $this -> initialize(); + } + + /** + * Print a barcode. + * + * @param string $content The information to encode. + * @param int $type The barcode standard to output. Supported values are + * `Printer::BARCODE_UPCA`, `Printer::BARCODE_UPCE`, `Printer::BARCODE_JAN13`, + * `Printer::BARCODE_JAN8`, `Printer::BARCODE_CODE39`, `Printer::BARCODE_ITF`, + * `Printer::BARCODE_CODABAR`, `Printer::BARCODE_CODE93`, and `Printer::BARCODE_CODE128`. + * If not specified, `Printer::BARCODE_CODE39` will be used. Note that some + * barcode formats only support specific lengths or sets of characters, and that + * available barcode types vary between printers. + * @throws InvalidArgumentException Where the length or characters used in $content is invalid for the requested barcode format. + */ + public function barcode($content, $type = Printer::BARCODE_CODE39) + { + /* Validate input */ + self::validateInteger($type, 65, 73, __FUNCTION__, "Barcode type"); + $len = strlen($content); + switch ($type) { + case self::BARCODE_UPCA: + self::validateInteger($len, 11, 12, __FUNCTION__, "UPCA barcode content length"); + self::validateStringRegex($content, __FUNCTION__, "/^[0-9]{11,12}$/", "UPCA barcode content"); + break; + case self::BARCODE_UPCE: + self::validateIntegerMulti($len, [[6, 8], [11, 12]], __FUNCTION__, "UPCE barcode content length"); + self::validateStringRegex($content, __FUNCTION__, "/^([0-9]{6,8}|[0-9]{11,12})$/", "UPCE barcode content"); + break; + case self::BARCODE_JAN13: + self::validateInteger($len, 12, 13, __FUNCTION__, "JAN13 barcode content length"); + self::validateStringRegex($content, __FUNCTION__, "/^[0-9]{12,13}$/", "JAN13 barcode content"); + break; + case self::BARCODE_JAN8: + self::validateInteger($len, 7, 8, __FUNCTION__, "JAN8 barcode content length"); + self::validateStringRegex($content, __FUNCTION__, "/^[0-9]{7,8}$/", "JAN8 barcode content"); + break; + case self::BARCODE_CODE39: + self::validateInteger($len, 1, 255, __FUNCTION__, "CODE39 barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. + self::validateStringRegex($content, __FUNCTION__, "/^([0-9A-Z \$\%\+\-\.\/]+|\*[0-9A-Z \$\%\+\-\.\/]+\*)$/", "CODE39 barcode content"); + break; + case self::BARCODE_ITF: + self::validateInteger($len, 2, 255, __FUNCTION__, "ITF barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. + self::validateStringRegex($content, __FUNCTION__, "/^([0-9]{2})+$/", "ITF barcode content"); + break; + case self::BARCODE_CODABAR: + self::validateInteger($len, 1, 255, __FUNCTION__, "Codabar barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. + self::validateStringRegex($content, __FUNCTION__, "/^[A-Da-d][0-9\$\+\-\.\/\:]+[A-Da-d]$/", "Codabar barcode content"); + break; + case self::BARCODE_CODE93: + self::validateInteger($len, 1, 255, __FUNCTION__, "Code93 barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. + self::validateStringRegex($content, __FUNCTION__, "/^[\\x00-\\x7F]+$/", "Code93 barcode content"); + break; + case self::BARCODE_CODE128: + self::validateInteger($len, 1, 255, __FUNCTION__, "Code128 barcode content length"); // 255 is a limitation of the "function b" command, not the barcode format. + // The CODE128 encoder is quite complex, so only a very basic header-check is applied here. + self::validateStringRegex($content, __FUNCTION__, "/^\{[A-C][\\x00-\\x7F]+$/", "Code128 barcode content"); + break; + } + if (!$this -> profile -> getSupportsBarcodeB()) { + // A simpler barcode command which supports fewer codes + self::validateInteger($type, 65, 71, __FUNCTION__); + $this -> connector -> write(self::GS . "k" . chr($type - 65) . $content . self::NUL); + return; + } + // More advanced function B, used in preference + $this -> connector -> write(self::GS . "k" . chr($type) . chr(strlen($content)) . $content); + } + + /** + * Print an image, using the older "bit image" command. This creates padding on the right of the image, + * if its width is not divisible by 8. + * + * Should only be used if your printer does not support the graphics() command. + * See also bitImageColumnFormat(). + * + * @param EscposImage $img The image to print + * @param int $size Size modifier for the image. Must be either `Printer::IMG_DEFAULT` + * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and + * `Printer::IMG_DOUBLE_WIDTH` flags. + */ + public function bitImage(EscposImage $img, $size = Printer::IMG_DEFAULT) + { + self::validateInteger($size, 0, 3, __FUNCTION__); + $rasterData = $img -> toRasterFormat(); + $header = Printer::dataHeader([$img -> getWidthBytes(), $img -> getHeight()], true); + $this -> connector -> write(self::GS . "v0" . chr($size) . $header); + $this -> connector -> write($rasterData); + } + + /** + * Print an image, using the older "bit image" command in column format. + * + * Should only be used if your printer does not support the graphics() or + * bitImage() commands. + * + * @param EscposImage $img The image to print + * @param int $size Size modifier for the image. Must be either `Printer::IMG_DEFAULT` + * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and + * `Printer::IMG_DOUBLE_WIDTH` flags. + */ + public function bitImageColumnFormat(EscposImage $img, $size = Printer::IMG_DEFAULT) + { + $highDensityVertical = ! (($size & self::IMG_DOUBLE_HEIGHT) == Printer::IMG_DOUBLE_HEIGHT); + $highDensityHorizontal = ! (($size & self::IMG_DOUBLE_WIDTH) == Printer::IMG_DOUBLE_WIDTH); + // Experimental column format printing + // This feature is not yet complete and may produce unpredictable results. + $this -> setLineSpacing(16); // 16-dot line spacing. This is the correct value on both TM-T20 and TM-U220 + // Header and density code (0, 1, 32, 33) re-used for every line + $densityCode = ($highDensityHorizontal ? 1 : 0) + ($highDensityVertical ? 32 : 0); + $colFormatData = $img -> toColumnFormat($highDensityVertical); + $header = Printer::dataHeader([$img -> getWidth()], true); + foreach ($colFormatData as $line) { + // Print each line, double density etc for printing are set here also + $this -> connector -> write(self::ESC . "*" . chr($densityCode) . $header . $line); + $this -> feed(); + // sleep(0.1); // Reduces the amount of trouble that a TM-U220 has keeping up with large images + } + $this -> setLineSpacing(); // Revert to default line spacing + } + + /** + * Close the underlying buffer. With some connectors, the + * job will not actually be sent to the printer until this is called. + */ + public function close() + { + $this -> connector -> finalize(); + } + + /** + * Cut the paper. + * + * @param int $mode Cut mode, either Printer::CUT_FULL or Printer::CUT_PARTIAL. If not specified, `Printer::CUT_FULL` will be used. + * @param int $lines Number of lines to feed + */ + public function cut($mode = Printer::CUT_FULL, $lines = 3) + { + // TODO validation on cut() inputs + $this -> connector -> write(self::GS . "V" . chr($mode) . chr($lines)); + } + + /** + * Print and feed line / Print and feed n lines. + * + * @param int $lines Number of lines to feed + */ + public function feed($lines = 1) + { + self::validateInteger($lines, 1, 255, __FUNCTION__); + if ($lines <= 1) { + $this -> connector -> write(self::LF); + } else { + $this -> connector -> write(self::ESC . "d" . chr($lines)); + } + } + + /** + * Some printers require a form feed to release the paper. On most printers, this + * command is only useful in page mode, which is not implemented in this driver. + */ + public function feedForm() + { + $this -> connector -> write(self::FF); + } + + /** + * Some slip printers require `ESC q` sequence to release the paper. + */ + public function release() + { + $this -> connector -> write(self::ESC . chr(113)); + } + + /** + * Print and reverse feed n lines. + * + * @param int $lines number of lines to feed. If not specified, 1 line will be fed. + */ + public function feedReverse($lines = 1) + { + self::validateInteger($lines, 1, 255, __FUNCTION__); + $this -> connector -> write(self::ESC . "e" . chr($lines)); + } + + /** + * @return number + */ + public function getCharacterTable() + { + return $this -> characterTable; + } + + /** + * @return PrintBuffer + */ + public function getPrintBuffer() + { + return $this -> buffer; + } + + /** + * @return PrintConnector + */ + public function getPrintConnector() + { + return $this -> connector; + } + + /** + * @return CapabilityProfile + */ + public function getPrinterCapabilityProfile() + { + return $this -> profile; + } + + /** + * Print an image to the printer. + * + * Size modifiers are: + * - Printer::IMG_DEFAULT (leave image at original size) + * - Printer::IMG_DOUBLE_WIDTH + * - Printer::IMG_DOUBLE_HEIGHT + * + * See the example/ folder for detailed examples. + * + * The functions bitImage() and bitImageColumnFormat() take the same + * parameters, and can be used if your printer doesn't support the newer + * graphics commands. + * + * @param EscposImage $img The image to print. + * @param int $size Size modifier for the image. Must be either `Printer::IMG_DEFAULT` + * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and + * `Printer::IMG_DOUBLE_WIDTH` flags. + */ + public function graphics(EscposImage $img, $size = Printer::IMG_DEFAULT) + { + self::validateInteger($size, 0, 3, __FUNCTION__); + $rasterData = $img -> toRasterFormat(); + $imgHeader = Printer::dataHeader([$img -> getWidth(), $img -> getHeight()], true); + $tone = '0'; + $colors = '1'; + $xm = (($size & self::IMG_DOUBLE_WIDTH) == Printer::IMG_DOUBLE_WIDTH) ? chr(2) : chr(1); + $ym = (($size & self::IMG_DOUBLE_HEIGHT) == Printer::IMG_DOUBLE_HEIGHT) ? chr(2) : chr(1); + $header = $tone . $xm . $ym . $colors . $imgHeader; + $this -> wrapperSendGraphicsData('0', 'p', $header . $rasterData); + $this -> wrapperSendGraphicsData('0', '2'); + } + + /** + * Initialize printer. This resets formatting back to the defaults. + */ + public function initialize() + { + $this -> connector -> write(self::ESC . "@"); + $this -> characterTable = 0; + } + + /** + * Print a two-dimensional data code using the PDF417 standard. + * + * @param string $content Text or numbers to store in the code + * @param int $width Width of a module (pixel) in the printed code. + * Default is 3 dots. + * @param int $heightMultiplier Multiplier for height of a module. + * Default is 3 times the width. + * @param int $dataColumnCount Number of data columns to use. 0 (default) + * is to auto-calculate. Smaller numbers will result in a narrower code, + * making larger pixel sizes possible. Larger numbers require smaller pixel sizes. + * @param float $ec Error correction ratio, from 0.01 to 4.00. Default is 0.10 (10%). + * @param int $options Standard code Printer::PDF417_STANDARD with + * start/end bars, or truncated code Printer::PDF417_TRUNCATED with start bars only. + * @throws Exception If this profile indicates that PDF417 code is not supported + */ + public function pdf417Code($content, $width = 3, $heightMultiplier = 3, $dataColumnCount = 0, $ec = 0.10, $options = Printer::PDF417_STANDARD) + { + self::validateString($content, __FUNCTION__, 'content'); + self::validateInteger($width, 2, 8, __FUNCTION__, 'width'); + self::validateInteger($heightMultiplier, 2, 8, __FUNCTION__, 'heightMultiplier'); + self::validateInteger($dataColumnCount, 0, 30, __FUNCTION__, 'dataColumnCount'); + self::validateFloat($ec, 0.01, 4.00, __FUNCTION__, 'ec'); + self::validateInteger($options, 0, 1, __FUNCTION__, 'options'); + if ($content == "") { + return; + } + if (!$this -> profile -> getSupportsPdf417Code()) { + // TODO use software rendering via a library instead + throw new Exception("PDF417 codes are not supported on your printer."); + } + $cn = '0'; // Code type for pdf417 code + // Select model: standard or truncated + $this -> wrapperSend2dCodeData(chr(70), $cn, chr($options)); + // Column count + $this -> wrapperSend2dCodeData(chr(65), $cn, chr($dataColumnCount)); + // Set dot sizes + $this -> wrapperSend2dCodeData(chr(67), $cn, chr($width)); + $this -> wrapperSend2dCodeData(chr(68), $cn, chr($heightMultiplier)); + // Set error correction ratio: 1% to 400% + $ec_int = (int)ceil(floatval($ec) * 10); + $this -> wrapperSend2dCodeData(chr(69), $cn, chr($ec_int), '1'); + // Send content & print + $this -> wrapperSend2dCodeData(chr(80), $cn, $content, '0'); + $this -> wrapperSend2dCodeData(chr(81), $cn, '', '0'); + } + + /** + * Generate a pulse, for opening a cash drawer if one is connected. + * The default settings should open an Epson drawer. + * + * @param int $pin 0 or 1, for pin 2 or pin 5 kick-out connector respectively. + * @param int $on_ms pulse ON time, in milliseconds. + * @param int $off_ms pulse OFF time, in milliseconds. + */ + public function pulse($pin = 0, $on_ms = 120, $off_ms = 240) + { + self::validateInteger($pin, 0, 1, __FUNCTION__); + self::validateInteger($on_ms, 1, 511, __FUNCTION__); + self::validateInteger($off_ms, 1, 511, __FUNCTION__); + $this -> connector -> write(self::ESC . "p" . chr($pin + 48) . chr($on_ms / 2) . chr($off_ms / 2)); + } + + /** + * Print the given data as a QR code on the printer. + * + * @param string $content The content of the code. Numeric data will be more efficiently compacted. + * @param int $ec Error-correction level to use. One of Printer::QR_ECLEVEL_L (default), Printer::QR_ECLEVEL_M, Printer::QR_ECLEVEL_Q or Printer::QR_ECLEVEL_H. Higher error correction results in a less compact code. + * @param int $size Pixel size to use. Must be 1-16 (default 3) + * @param int $model QR code model to use. Must be one of Printer::QR_MODEL_1, Printer::QR_MODEL_2 (default) or Printer::QR_MICRO (not supported by all printers). + */ + public function qrCode($content, $ec = Printer::QR_ECLEVEL_L, $size = 3, $model = Printer::QR_MODEL_2) + { + self::validateString($content, __FUNCTION__); + self::validateInteger($ec, 0, 3, __FUNCTION__); + self::validateInteger($size, 1, 16, __FUNCTION__); + self::validateInteger($model, 1, 3, __FUNCTION__); + if ($content == "") { + return; + } + if (!$this -> profile -> getSupportsQrCode()) { + // TODO use software rendering via phpqrcode instead + throw new Exception("QR codes are not supported on your printer."); + } + $cn = '1'; // Code type for QR code + // Select model: 1, 2 or micro. + $this -> wrapperSend2dCodeData(chr(65), $cn, chr(48 + $model) . chr(0)); + // Set dot size. + $this -> wrapperSend2dCodeData(chr(67), $cn, chr($size)); + // Set error correction level: L, M, Q, or H + $this -> wrapperSend2dCodeData(chr(69), $cn, chr(48 + $ec)); + // Send content & print + $this -> wrapperSend2dCodeData(chr(80), $cn, $content, '0'); + $this -> wrapperSend2dCodeData(chr(81), $cn, '', '0'); + } + + /** + * Switch character table (code page) manually. Used in conjunction with textRaw() to + * print special characters which can't be encoded automatically. + * + * @param int $table The table to select. Available code tables are model-specific. + */ + public function selectCharacterTable($table = 0) + { + self::validateInteger($table, 0, 255, __FUNCTION__); + $supported = $this -> profile -> getCodePages(); + if (!isset($supported[$table])) { + throw new InvalidArgumentException("There is no code table $table allowed by this printer's capability profile."); + } + $this -> characterTable = $table; + if ($this -> profile -> getSupportsStarCommands()) { + /* Not an ESC/POS command: STAR printers stash all the extra code pages under a different command. */ + $this -> connector -> write(self::ESC . self::GS . "t" . chr($table)); + return; + } + $this -> connector -> write(self::ESC . "t" . chr($table)); + } + + /** + * Select print mode(s). + * + * Several MODE_* constants can be OR'd together passed to this function's `$mode` argument. The valid modes are: + * - Printer::MODE_FONT_A + * - Printer::MODE_FONT_B + * - Printer::MODE_EMPHASIZED + * - Printer::MODE_DOUBLE_HEIGHT + * - Printer::MODE_DOUBLE_WIDTH + * - Printer::MODE_UNDERLINE + * + * @param int $mode The mode to use. Default is Printer::MODE_FONT_A, with no special formatting. This has a similar effect to running initialize(). + */ + public function selectPrintMode($mode = Printer::MODE_FONT_A) + { + $allModes = Printer::MODE_FONT_B | self::MODE_EMPHASIZED | self::MODE_DOUBLE_HEIGHT | self::MODE_DOUBLE_WIDTH | self::MODE_UNDERLINE; + if (!is_integer($mode) || $mode < 0 || ($mode & $allModes) != $mode) { + throw new InvalidArgumentException("Invalid mode"); + } + + $this -> connector -> write(self::ESC . "!" . chr($mode)); + } + + /** + * Set barcode height. + * + * @param int $height Height in dots. If not specified, 8 will be used. + */ + public function setBarcodeHeight($height = 8) + { + self::validateInteger($height, 1, 255, __FUNCTION__); + $this -> connector -> write(self::GS . "h" . chr($height)); + } + + /** + * Set barcode bar width. + * + * @param int $width Bar width in dots. If not specified, 3 will be used. + * Values above 6 appear to have no effect. + */ + public function setBarcodeWidth($width = 3) + { + self::validateInteger($width, 1, 255, __FUNCTION__); + $this -> connector -> write(self::GS . "w" . chr($width)); + } + + /** + * Set the position for the Human Readable Interpretation (HRI) of barcode characters. + * + * @param int $position. Use Printer::BARCODE_TEXT_NONE to hide the text (default), + * or any combination of Printer::BARCODE_TEXT_ABOVE and Printer::BARCODE_TEXT_BELOW + * flags to display the text. + */ + public function setBarcodeTextPosition($position = Printer::BARCODE_TEXT_NONE) + { + self::validateInteger($position, 0, 3, __FUNCTION__, "Barcode text position"); + $this -> connector -> write(self::GS . "H" . chr($position)); + } + + /** + * Turn double-strike mode on/off. + * + * @param boolean $on true for double strike, false for no double strike + */ + public function setDoubleStrike($on = true) + { + self::validateBoolean($on, __FUNCTION__); + $this -> connector -> write(self::ESC . "G". ($on ? chr(1) : chr(0))); + } + + /** + * Select print color on printers that support multiple colors. + * + * @param int $color Color to use. Must be either Printer::COLOR_1 (default), or Printer::COLOR_2. + */ + public function setColor($color = Printer::COLOR_1) + { + self::validateInteger($color, 0, 1, __FUNCTION__, "Color"); + $this -> connector -> write(self::ESC . "r" . chr($color)); + } + + /** + * Turn emphasized mode on/off. + * + * @param boolean $on true for emphasis, false for no emphasis + */ + public function setEmphasis($on = true) + { + self::validateBoolean($on, __FUNCTION__); + $this -> connector -> write(self::ESC . "E". ($on ? chr(1) : chr(0))); + } + + /** + * Select font. Most printers have two fonts (Fonts A and B), and some have a third (Font C). + * + * @param int $font The font to use. Must be either Printer::FONT_A, Printer::FONT_B, or Printer::FONT_C. + */ + public function setFont($font = Printer::FONT_A) + { + self::validateInteger($font, 0, 2, __FUNCTION__); + $this -> connector -> write(self::ESC . "M" . chr($font)); + } + + /** + * Select justification. + * + * @param int $justification One of Printer::JUSTIFY_LEFT, Printer::JUSTIFY_CENTER, or Printer::JUSTIFY_RIGHT. + */ + public function setJustification($justification = Printer::JUSTIFY_LEFT) + { + self::validateInteger($justification, 0, 2, __FUNCTION__); + $this -> connector -> write(self::ESC . "a" . chr($justification)); + } + + /** + * Set the height of the line. + * + * Some printers will allow you to overlap lines with a smaller line feed. + * + * @param int|null $height The height of each line, in dots. If not set, the printer + * will reset to its default line spacing. + */ + public function setLineSpacing($height = null) + { + if ($height === null) { + // Reset to default + $this -> connector -> write(self::ESC . "2"); // Revert to default line spacing + return; + } + self::validateInteger($height, 1, 255, __FUNCTION__); + $this -> connector -> write(self::ESC . "3" . chr($height)); + } + + /** + * Set print area left margin. Reset to default with Printer::initialize() + * + * @param int $margin The left margin to set on to the print area, in dots. + */ + public function setPrintLeftMargin($margin = 0) + { + self::validateInteger($margin, 0, 65535, __FUNCTION__); + $this -> connector -> write(Printer::GS . 'L' . self::intLowHigh($margin, 2)); + } + + /** + * Set print area width. This can be used to add a right margin to the print area. + * Reset to default with Printer::initialize() + * + * @param int $width The width of the page print area, in dots. + */ + public function setPrintWidth($width = 512) + { + self::validateInteger($width, 1, 65535, __FUNCTION__); + $this -> connector -> write(Printer::GS . 'W' . self::intLowHigh($width, 2)); + } + + /** + * Attach a different print buffer to the printer. Buffers are responsible for handling text output to the printer. + * + * @param PrintBuffer $buffer The buffer to use. + * @throws InvalidArgumentException Where the buffer is already attached to a different printer. + */ + public function setPrintBuffer(PrintBuffer $buffer) + { + if ($buffer === $this -> buffer) { + return; + } + if ($buffer -> getPrinter() != null) { + throw new InvalidArgumentException("This buffer is already attached to a printer."); + } + if ($this -> buffer !== null) { + $this -> buffer -> setPrinter(null); + } + $this -> buffer = $buffer; + $this -> buffer -> setPrinter($this); + } + + /** + * Set black/white reverse mode on or off. In this mode, text is printed white on a black background. + * + * @param boolean $on True to enable, false to disable. + */ + public function setReverseColors($on = true) + { + self::validateBoolean($on, __FUNCTION__); + $this -> connector -> write(self::GS . "B" . ($on ? chr(1) : chr(0))); + } + + /** + * Set the size of text, as a multiple of the normal size. + * + * @param int $widthMultiplier Multiple of the regular height to use (range 1 - 8) + * @param int $heightMultiplier Multiple of the regular height to use (range 1 - 8) + */ + public function setTextSize($widthMultiplier, $heightMultiplier) + { + self::validateInteger($widthMultiplier, 1, 8, __FUNCTION__); + self::validateInteger($heightMultiplier, 1, 8, __FUNCTION__); + $c = pow(2, 4) * ($widthMultiplier - 1) + ($heightMultiplier - 1); + $this -> connector -> write(self::GS . "!" . chr($c)); + } + + /** + * Set underline for printed text. + * + * Argument can be true/false, or one of UNDERLINE_NONE, + * UNDERLINE_SINGLE or UNDERLINE_DOUBLE. + * + * @param int $underline Either true/false, or one of Printer::UNDERLINE_NONE, Printer::UNDERLINE_SINGLE or Printer::UNDERLINE_DOUBLE. Defaults to Printer::UNDERLINE_SINGLE. + */ + public function setUnderline($underline = Printer::UNDERLINE_SINGLE) + { + /* Map true/false to underline constants */ + if ($underline === true) { + $underline = Printer::UNDERLINE_SINGLE; + } elseif ($underline === false) { + $underline = Printer::UNDERLINE_NONE; + } + /* Set the underline */ + self::validateInteger($underline, 0, 2, __FUNCTION__); + $this -> connector -> write(self::ESC . "-" . chr($underline)); + } + + /** + * Print each line upside-down (180 degrees rotated). + * + * @param boolean $on True to enable, false to disable. + */ + public function setUpsideDown($on = true) + { + self::validateBoolean($on, __FUNCTION__); + $this -> connector -> write(self::ESC . "{" . ($on ? chr(1) : chr(0))); + } + + /** + * Add text to the buffer. + * + * Text should either be followed by a line-break, or feed() should be called + * after this to clear the print buffer. + * + * @param string $str Text to print + */ + public function text($str = "") + { + self::validateString($str, __FUNCTION__); + $this -> buffer -> writeText((string)$str); + } + + /** + * Add Chinese text to the buffer. This is a specific workaround for the common Zijang printer- The printer will be switched to a two-byte mode and sent GBK-encoded text. + * + * Support for this will be merged into a print buffer. + * + * @param string $str Text to print, as UTF-8 + */ + public function textChinese($str = "") + { + self::validateString($str, __FUNCTION__); + $this -> connector -> write(self::FS . "&"); + $str = iconv("UTF-8", "GBK//IGNORE", $str); + $this -> buffer -> writeTextRaw((string)$str); + $this -> connector -> write(self::FS . "."); + } + + /** + * Add text to the buffer without attempting to interpret chararacter codes. + * + * Text should either be followed by a line-break, or feed() should be called + * after this to clear the print buffer. + * + * @param string $str Text to print + */ + public function textRaw($str = "") + { + self::validateString($str, __FUNCTION__); + $this -> buffer -> writeTextRaw((string)$str); + } + + /** + * Wrapper for GS ( k, to calculate and send correct data length. + * + * @param string $fn Function to use + * @param string $cn Output code type. Affects available data + * @param string $data Data to send. + * @param string $m Modifier/variant for function. Often '0' where used. + * @throws InvalidArgumentException Where the input lengths are bad. + */ + protected function wrapperSend2dCodeData($fn, $cn, $data = '', $m = '') + { + if (strlen($m) > 1 || strlen($cn) != 1 || strlen($fn) != 1) { + throw new InvalidArgumentException("wrapperSend2dCodeData: cn and fn must be one character each."); + } + $header = $this -> intLowHigh(strlen($data) + strlen($m) + 2, 2); + $this -> connector -> write(self::GS . "(k" . $header . $cn . $fn . $m . $data); + } + + /** + * Wrapper for GS ( L, to calculate and send correct data length. + * + * @param string $m Modifier/variant for function. Usually '0'. + * @param string $fn Function number to use, as character. + * @param string $data Data to send. + * @throws InvalidArgumentException Where the input lengths are bad. + */ + protected function wrapperSendGraphicsData($m, $fn, $data = '') + { + if (strlen($m) != 1 || strlen($fn) != 1) { + throw new InvalidArgumentException("wrapperSendGraphicsData: m and fn must be one character each."); + } + $header = $this -> intLowHigh(strlen($data) + 2, 2); + $this -> connector -> write(self::GS . "(L" . $header . $m . $fn . $data); + } + + /** + * Convert widths and heights to characters. Used before sending graphics to set the size. + * + * @param array $inputs + * @param boolean $long True to use 4 bytes, false to use 2 + * @return string + */ + protected static function dataHeader(array $inputs, $long = true) + { + $outp = []; + foreach ($inputs as $input) { + if ($long) { + $outp[] = Printer::intLowHigh($input, 2); + } else { + self::validateInteger($input, 0, 255, __FUNCTION__); + $outp[] = chr($input); + } + } + return implode("", $outp); + } + + /** + * Generate two characters for a number: In lower and higher parts, or more parts as needed. + * + * @param int $input Input number + * @param int $length The number of bytes to output (1 - 4). + */ + protected static function intLowHigh($input, $length) + { + $maxInput = (256 << ($length * 8) - 1); + self::validateInteger($length, 1, 4, __FUNCTION__); + self::validateInteger($input, 0, $maxInput, __FUNCTION__); + $outp = ""; + for ($i = 0; $i < $length; $i++) { + $outp .= chr($input % 256); + $input = (int)($input / 256); + } + return $outp; + } + + /** + * Throw an exception if the argument given is not a boolean + * + * @param boolean $test the input to test + * @param string $source the name of the function calling this + */ + protected static function validateBoolean($test, $source) + { + if (!($test === true || $test === false)) { + throw new InvalidArgumentException("Argument to $source must be a boolean"); + } + } + + /** + * Throw an exception if the argument given is not a float within the specified range + * + * @param float $test the input to test + * @param float $min the minimum allowable value (inclusive) + * @param float $max the maximum allowable value (inclusive) + * @param string $source the name of the function calling this + * @param string $argument the name of the invalid parameter + */ + protected static function validateFloat($test, $min, $max, $source, $argument = "Argument") + { + if (!is_numeric($test)) { + throw new InvalidArgumentException("$argument given to $source must be a float, but '$test' was given."); + } + if ($test < $min || $test > $max) { + throw new InvalidArgumentException("$argument given to $source must be in range $min to $max, but $test was given."); + } + } + + /** + * Throw an exception if the argument given is not an integer within the specified range + * + * @param int $test the input to test + * @param int $min the minimum allowable value (inclusive) + * @param int $max the maximum allowable value (inclusive) + * @param string $source the name of the function calling this + * @param string $argument the name of the invalid parameter + */ + protected static function validateInteger($test, $min, $max, $source, $argument = "Argument") + { + self::validateIntegerMulti($test, [[$min, $max]], $source, $argument); + } + + /** + * Throw an exception if the argument given is not an integer within one of the specified ranges + * + * @param int $test the input to test + * @param array $ranges array of two-item min/max ranges. + * @param string $source the name of the function calling this + * @param string $source the name of the function calling this + * @param string $argument the name of the invalid parameter + */ + protected static function validateIntegerMulti($test, array $ranges, $source, $argument = "Argument") + { + if (!is_integer($test)) { + throw new InvalidArgumentException("$argument given to $source must be a number, but '$test' was given."); + } + $match = false; + foreach ($ranges as $range) { + $match |= $test >= $range[0] && $test <= $range[1]; + } + if (!$match) { + // Put together a good error "range 1-2 or 4-6" + $rangeStr = "range "; + for ($i = 0; $i < count($ranges); $i++) { + $rangeStr .= $ranges[$i][0] . "-" . $ranges[$i][1]; + if ($i == count($ranges) - 1) { + continue; + } elseif ($i == count($ranges) - 2) { + $rangeStr .= " or "; + } else { + $rangeStr .= ", "; + } + } + throw new InvalidArgumentException("$argument given to $source must be in $rangeStr, but $test was given."); + } + } + + /** + * Throw an exception if the argument given can't be cast to a string + * + * @param string $test the input to test + * @param string $source the name of the function calling this + * @param string $argument the name of the parameter being validated + * @throws InvalidArgumentException Where the argument is not valid + */ + protected static function validateString($test, $source, $argument = "Argument") + { + if (is_object($test) && !method_exists($test, '__toString')) { + throw new InvalidArgumentException("$argument to $source must be a string"); + } + } + + /** + * Throw an exception if the argument doesn't match the given regex. + * + * @param string $test the input to test + * @param string $source the name of the function calling this + * @param string $regex valid values for this attribute, as a regex + * @param string $argument the name of the parameter being validated + * @throws InvalidArgumentException Where the argument is not valid + */ + protected static function validateStringRegex($test, $source, $regex, $argument = "Argument") + { + if (preg_match($regex, $test) === 0) { + throw new InvalidArgumentException("$argument given to $source is invalid. It should match regex '$regex', but '$test' was given."); + } + } +} diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/resources/capabilities.json b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/resources/capabilities.json new file mode 100644 index 00000000000..c60cac0deb7 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/resources/capabilities.json @@ -0,0 +1,1760 @@ +{ + "encodings": { + "CP1001": { + "name": "Unimplemented Star-specific CP1001" + }, + "CP1098": { + "name": "CP1098" + }, + "CP1125": { + "iconv": "CP1125", + "name": "CP1125", + "python_encode": "cp1125" + }, + "CP1250": { + "iconv": "CP1250", + "name": "CP1250", + "python_encode": "cp1250" + }, + "CP1251": { + "iconv": "CP1251", + "name": "CP1251", + "python_encode": "cp1251" + }, + "CP1252": { + "iconv": "CP1252", + "name": "CP1252", + "python_encode": "cp1252" + }, + "CP1253": { + "iconv": "CP1253", + "name": "CP1253", + "python_encode": "cp1253" + }, + "CP1254": { + "iconv": "CP1254", + "name": "CP1254", + "python_encode": "cp1254" + }, + "CP1255": { + "iconv": "CP1255", + "name": "CP1255", + "python_encode": "cp1255" + }, + "CP1256": { + "iconv": "CP1256", + "name": "CP1256", + "python_encode": "cp1256" + }, + "CP1257": { + "iconv": "CP1257", + "name": "CP1257", + "python_encode": "cp1257" + }, + "CP1258": { + "iconv": "CP1258", + "name": "CP1258", + "python_encode": "cp1258" + }, + "CP2001": { + "name": "Unimplemented Star-specific CP2001" + }, + "CP3001": { + "name": "Unimplemented Star-specific CP3001" + }, + "CP3002": { + "name": "Unimplemented Star-specific CP3002" + }, + "CP3011": { + "data": [ + "\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5", + "\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00a2\u00a3\u00a5\u20a7\u0192", + "\u00e1\u00ed\u00f3\u00fa\u00f1\u00d1\u00aa\u00ba\u00bf\u2310\u00ac\u00bd\u00bc\u00a1\u00ab\u00bb", + "\u2591\u2592\u2593\u2502\u2524\u0100\u2562\u0146\u2555\u2563\u2551\u2557\u255d\u255c\u255b\u2510", + "\u2514\u2534\u252c\u251c\u2500\u253c\u0101\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567", + "\u0160\u2564\u010d\u010c\u2558\u2552\u0123\u012a\u012b\u2518\u250c\u2588\u2584\u016b\u016a\u2580", + "\u03b1\u00df\u0393\u03c0\u03a3\u03c3\u00b5\u03c4\u03a6\u0398\u03a9\u03b4\u221e\u03c6\u03b5\u2229", + "\u0112\u0113\u0122\u0137\u0136\u013c\u013b\u017e\u017d\u2219\u00b7\u221a\u0145\u0161\u25a0 " + ], + "name": "CP3011 Latvian" + }, + "CP3012": { + "data": [ + "\u0410\u0411\u0412\u0413\u0414\u0415\u0416\u0417\u0418\u0419\u041a\u041b\u041c\u041d\u041e\u041f", + "\u0420\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042a\u042b\u042c\u042d\u042e\u042f", + "\u0430\u0431\u0432\u0433\u0434\u0435\u0436\u0437\u0438\u0439\u043a\u043b\u043c\u043d\u043e\u043f", + "\u2591\u2592\u2593\u2502\u2524\u0100\u2562\u0146\u2555\u2563\u2551\u2557\u255d\u014c\u255b\u2510", + "\u2514\u2534\u252c\u251c\u2500\u253c\u0101\u255f\u255a\u2554\u2569\u2566\u2560\u2550\u256c\u2567", + "\u0160\u2564\u010d\u010c\u2558\u2552\u0123\u012a\u012b\u2518\u250c\u2588\u2584\u016b\u016a\u2580", + "\u0440\u0441\u0442\u0443\u0444\u0445\u0446\u0447\u0448\u0449\u044a\u044b\u044c\u044d\u044e\u044f", + "\u0112\u0113\u0122\u0137\u0136\u013c\u013b\u017e\u017d\u2219\u00b7\u221a\u0145\u0161\u25a0 " + ], + "name": "CP3012 Cyrillic" + }, + "CP3021": { + "name": "Unimplemented Star-specific CP3021" + }, + "CP3041": { + "name": "Unimplemented Star-specific CP3041" + }, + "CP3840": { + "name": "Unimplemented Star-specific CP3840" + }, + "CP3841": { + "name": "Unimplemented Star-specific CP3841" + }, + "CP3843": { + "name": "Unimplemented Star-specific CP3843" + }, + "CP3844": { + "name": "Unimplemented Star-specific CP3844" + }, + "CP3845": { + "name": "Unimplemented Star-specific CP3845" + }, + "CP3846": { + "name": "Unimplemented Star-specific CP3846" + }, + "CP3847": { + "name": "Unimplemented Star-specific CP3847" + }, + "CP3848": { + "name": "Unimplemented Star-specific CP3848" + }, + "CP437": { + "iconv": "CP437", + "name": "CP437", + "python_encode": "cp437" + }, + "CP720": { + "name": "CP720", + "python_encode": "cp720" + }, + "CP737": { + "iconv": "CP737", + "name": "CP737", + "python_encode": "cp737" + }, + "CP747": { + "name": "CP747" + }, + "CP772": { + "iconv": "CP772", + "name": "CP772" + }, + "CP774": { + "iconv": "CP774", + "name": "CP774" + }, + "CP775": { + "iconv": "CP775", + "name": "CP775", + "python_encode": "cp775" + }, + "CP850": { + "iconv": "CP850", + "name": "CP850", + "python_encode": "cp850" + }, + "CP851": { + "name": "Greek CP851", + "notes": "Not used, due to inconsistencies between implementations." + }, + "CP852": { + "iconv": "CP852", + "name": "CP852", + "python_encode": "cp852" + }, + "CP853": { + "name": "CP853" + }, + "CP855": { + "iconv": "CP855", + "name": "CP855", + "python_encode": "cp855" + }, + "CP857": { + "iconv": "CP857", + "name": "CP857", + "python_encode": "cp857" + }, + "CP858": { + "name": "CP858", + "python_encode": "cp858" + }, + "CP860": { + "iconv": "CP860", + "name": "CP860", + "python_encode": "cp860" + }, + "CP861": { + "iconv": "CP861", + "name": "CP861", + "python_encode": "cp861" + }, + "CP862": { + "iconv": "CP862", + "name": "CP862", + "python_encode": "cp862" + }, + "CP863": { + "iconv": "CP863", + "name": "CP863", + "python_encode": "cp863" + }, + "CP864": { + "iconv": "CP864", + "name": "CP864", + "python_encode": "cp864" + }, + "CP865": { + "iconv": "CP865", + "name": "CP865", + "python_encode": "cp865" + }, + "CP866": { + "iconv": "CP866", + "name": "CP866", + "python_encode": "cp866" + }, + "CP869": { + "iconv": "CP869", + "name": "CP869", + "python_encode": "cp869" + }, + "CP874": { + "iconv": "CP874", + "name": "CP874", + "python_encode": "cp874" + }, + "CP928": { + "name": "CP928" + }, + "CP932": { + "iconv": "CP932", + "name": "CP932", + "python_encode": "cp932" + }, + "ISO_8859-15": { + "iconv": "ISO_8859-15", + "name": "ISO_8859-15", + "python_encode": "iso8859-15" + }, + "ISO_8859-2": { + "iconv": "ISO_8859-2", + "name": "ISO_8859-2", + "python_encode": "iso8859_2" + }, + "ISO_8859-7": { + "iconv": "ISO_8859-7", + "name": "ISO_8859-7", + "python_encode": "iso8859_7" + }, + "OXHOO-EUROPEAN": { + "data": [ + "\u00c7\u00fc\u00e9\u00e2\u00e4\u00e0\u00e5\u00e7\u00ea\u00eb\u00e8\u00ef\u00ee\u00ec\u00c4\u00c5", + "\u00c9\u00e6\u00c6\u00f4\u00f6\u00f2\u00fb\u00f9\u00ff\u00d6\u00dc\u00f1\u00d1\u00aa\u00ba\u00bf", + "\u00e1\u00ed\u00f3\u00fa\u00a2\u00a3\u00a5\u20a7\u0192\u00a1\u00c3\u00e3\u00d5\u00f5\u00d8\u00f8", + "\u00b7\u00a8\u00b0`\u00b4\u00bd\u00bc\u00d7\u00f7\u2264\u2265\u00ab\u00bb\u2260\u221a\u00af", + "\u2320\u2321\u221e\u25e4\u21b5\u2191\u2193\u2192\u2190\u250c\u2510\u2514\u2518\u2022\u00ae\u00a9", + "\u2122\u2020\u00a7\u00b6\u0393\u25e2\u0398 ", + "\u00df \u03b5 ", + "\u03c4 " + ], + "name": "Oxhoo-specific European" + }, + "RK1048": { + "iconv": "RK1048", + "name": "RK1048" + }, + "TCVN-3-1": { + "data": [ + " ", + " ", + " \u0103\u00e2\u00ea\u00f4\u01a1\u01b0\u0111 ", + " \u00e0\u1ea3\u00e3\u00e1\u1ea1 \u1eb1\u1eb3\u1eb5\u1eaf ", + " \u1eb7\u1ea7\u1ea9\u1eab\u1ea5\u1ead\u00e8 \u1ebb\u1ebd", + "\u00e9\u1eb9\u1ec1\u1ec3\u1ec5\u1ebf\u1ec7\u00ec\u1ec9 \u0129\u00ed\u1ecb\u00f2", + " \u1ecf\u00f5\u00f3\u1ecd\u1ed3\u1ed5\u1ed7\u1ed1\u1ed9\u1edd\u1edf\u1ee1\u1edb\u1ee3\u00f9", + " \u1ee7\u0169\u00fa\u1ee5\u1eeb\u1eed\u1eef\u1ee9\u1ef1\u1ef3\u1ef7\u1ef9\u00fd\u1ef5 " + ], + "name": "Vietnamese TCVN-3 1" + }, + "TCVN-3-2": { + "data": [ + " ", + " ", + " \u0102\u00c2 \u00d0 \u00ca\u00d4\u01a0\u01af ", + " \u00c0\u1ea2\u00c3\u00c1\u1ea0 \u1eb0\u1eb2\u1eb4\u1eae ", + " \u1eb6\u1ea6\u1ea8\u1eaa\u1ea4\u1eac\u00c8 \u1eba\u1ebc", + "\u00c9\u1eb8\u1ec0\u1ec2\u1ec4\u1ebe\u1ec6\u00cc\u1ec8 \u0128\u00cd\u1eca\u00d2", + " \u1ece\u00d5\u00d3\u1ecc\u1ed2\u1ed4\u1ed6\u1ed0\u1ed8\u1edc\u1ede\u1ee0\u1eda\u1ee2\u00d9", + " \u1ee6\u0168\u00da\u1ee4\u1eea\u1eec\u1eee\u1ee8\u1ef0\u1ef2\u1ef6\u1ef8\u00dd\u1ef4 " + ], + "name": "Vietnamese TCVN-3 1" + }, + "Unknown": { + "name": "Unknown", + "notes": "Code page that has not yet been identified." + } + }, + "profiles": { + "AF-240": { + "codePages": { + "0": "OXHOO-EUROPEAN" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": false, + "barcodeB": false, + "bitImageColumn": false, + "bitImageRaster": false, + "graphics": false, + "highDensity": false, + "paperFullCut": false, + "paperPartCut": false, + "pdf417Code": false, + "pulseBel": false, + "pulseStandard": false, + "qrCode": false, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 20, + "name": "Font A" + } + }, + "media": { + "width": { + "mm": 120, + "pixels": 100 + } + }, + "name": "AF-240 Customer Display", + "notes": "This is a two-line, ESC/POS-aware customer display from Oxhoo. The ESC/POS command mode can be activated persistently by sending:\n\n echo -ne \"\\n\\x02\\x05\\x43\\x31\\x03\" > /dev/ttyUSB0\n", + "vendor": "Oxhoo" + }, + "NT-5890K": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "6": "Unknown", + "7": "Unknown", + "8": "Unknown", + "9": "Unknown", + "10": "Unknown", + "16": "CP1252", + "17": "CP866", + "18": "CP852", + "19": "CP858", + "20": "Unknown", + "21": "Unknown", + "22": "Unknown", + "23": "Unknown", + "24": "CP747", + "25": "CP1257", + "27": "CP1258", + "28": "CP864", + "31": "Unknown", + "32": "CP1255", + "50": "CP437", + "52": "CP437", + "53": "CP858", + "54": "CP852", + "55": "CP860", + "56": "CP861", + "57": "CP863", + "58": "CP865", + "59": "CP866", + "60": "CP855", + "61": "CP857", + "62": "CP862", + "63": "CP864", + "64": "CP737", + "65": "CP851", + "66": "CP869", + "68": "CP772", + "69": "CP774", + "71": "CP1252", + "72": "CP1250", + "73": "CP1251", + "74": "CP3840", + "76": "CP3843", + "77": "CP3844", + "78": "CP3845", + "79": "CP3846", + "80": "CP3847", + "81": "CP3848", + "83": "CP2001", + "84": "CP3001", + "85": "CP3002", + "86": "CP3011", + "87": "CP3012", + "88": "CP3021", + "89": "CP3041", + "90": "CP1253", + "91": "CP1254", + "92": "CP1256", + "93": "CP720", + "94": "CP1258", + "95": "CP775", + "96": "Unknown", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": false, + "barcodeB": false, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": false, + "highDensity": true, + "paperFullCut": false, + "paperPartCut": false, + "pdf417Code": false, + "pulseBel": false, + "pulseStandard": true, + "qrCode": false, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 32, + "name": "Font A" + }, + "1": { + "columns": 42, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": 57.5, + "pixels": 384 + } + }, + "name": "NT-5890K", + "notes": "", + "vendor": "Netum" + }, + "OCD-100": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "6": "Unknown", + "7": "Unknown", + "8": "Unknown", + "9": "CP852", + "10": "CP862", + "11": "CP866", + "12": "CP1251", + "13": "CP1254", + "14": "CP1255", + "15": "CP1257", + "16": "CP1252", + "17": "CP1253", + "19": "CP858" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": false, + "barcodeB": false, + "bitImageColumn": false, + "bitImageRaster": false, + "graphics": false, + "highDensity": false, + "paperFullCut": false, + "paperPartCut": false, + "pdf417Code": false, + "pulseBel": false, + "pulseStandard": false, + "qrCode": false, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 20, + "name": "Font A" + } + }, + "media": { + "width": { + "mm": 180, + "pixels": 100 + } + }, + "name": "OCD-100 Customer Display", + "notes": "This is a two-line, ESC/POS-aware customer display from Aures. It has some graphics support via custom fonts, but is otherwise text-only. This profile is also suitable for the OCD-150 pole-mounted display.\n", + "vendor": "Aures" + }, + "OCD-300": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "6": "Unknown", + "7": "Unknown", + "8": "Unknown", + "9": "CP852", + "10": "CP862", + "11": "CP866", + "12": "CP1251", + "13": "CP1254", + "14": "CP1255", + "15": "CP1257", + "16": "CP1252", + "17": "CP1253", + "18": "CP1250", + "19": "CP858", + "20": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": false, + "barcodeB": false, + "bitImageColumn": false, + "bitImageRaster": false, + "graphics": false, + "highDensity": false, + "paperFullCut": false, + "paperPartCut": false, + "pdf417Code": false, + "pulseBel": false, + "pulseStandard": false, + "qrCode": false, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 20, + "name": "Font A" + } + }, + "media": { + "width": { + "mm": 130.2, + "pixels": 240 + } + }, + "name": "OCD-300 Customer Display", + "notes": "This is a two-line, ESC/POS-aware customer display from Aures. It has some graphics support via vendor-provided tools, but is otherwise text-only.\n", + "vendor": "Aures" + }, + "P822D": { + "codePages": { + "0": "CP437", + "1": "Unknown", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "6": "Unknown", + "7": "Unknown", + "8": "Unknown", + "9": "Unknown", + "10": "Unknown", + "16": "CP1252", + "17": "CP866", + "18": "CP852", + "19": "CP858", + "20": "Unknown", + "21": "Unknown", + "22": "Unknown", + "23": "Unknown", + "24": "CP747", + "25": "CP1257", + "27": "Unknown", + "28": "CP864", + "29": "CP1001", + "30": "Unknown", + "31": "Unknown", + "32": "CP1255", + "33": "CP720", + "34": "CP1256", + "35": "CP1257", + "50": "CP437", + "51": "Unknown", + "52": "CP437", + "53": "CP858", + "54": "CP852", + "55": "CP860", + "56": "CP861", + "57": "CP863", + "58": "CP865", + "59": "CP866", + "60": "CP855", + "61": "CP857", + "62": "CP862", + "63": "CP864", + "64": "CP737", + "65": "CP851", + "66": "CP869", + "67": "CP928", + "68": "CP772", + "69": "CP774", + "70": "CP874", + "71": "CP1252", + "72": "CP1250", + "73": "CP1251", + "74": "CP3840", + "75": "CP3841", + "76": "CP3843", + "77": "CP3844", + "78": "CP3845", + "79": "CP3846", + "80": "CP3847", + "81": "CP3848", + "82": "CP1001", + "83": "CP2001", + "84": "CP3001", + "85": "CP3002", + "86": "CP3011", + "87": "CP3012", + "88": "CP3021", + "89": "CP3041", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": false, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "P822D", + "notes": "", + "vendor": "PBM" + }, + "POS-5890": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "6": "Unknown", + "7": "Unknown", + "8": "Unknown", + "9": "Unknown", + "10": "Unknown", + "16": "CP1252", + "17": "CP866", + "18": "CP852", + "19": "CP858", + "20": "Unknown", + "21": "Unknown", + "22": "Unknown", + "23": "Unknown", + "24": "CP747", + "25": "CP1257", + "27": "CP1258", + "28": "CP864", + "31": "Unknown", + "32": "CP1255", + "50": "CP437", + "52": "CP437", + "53": "CP858", + "54": "CP852", + "55": "CP860", + "56": "CP861", + "57": "CP863", + "58": "CP865", + "59": "CP866", + "60": "CP855", + "61": "CP857", + "62": "CP862", + "63": "CP864", + "64": "CP737", + "65": "CP851", + "66": "CP869", + "68": "CP772", + "69": "CP774", + "71": "CP1252", + "72": "CP1250", + "73": "CP1251", + "74": "CP3840", + "76": "CP3843", + "77": "CP3844", + "78": "CP3845", + "79": "CP3846", + "80": "CP3847", + "81": "CP3848", + "83": "CP2001", + "84": "CP3001", + "85": "CP3002", + "86": "CP3011", + "87": "CP3012", + "88": "CP3021", + "89": "CP3041", + "90": "CP1253", + "91": "CP1254", + "92": "CP1256", + "93": "CP720", + "94": "CP1258", + "95": "CP775", + "96": "Unknown", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": false, + "barcodeB": false, + "bitImageColumn": false, + "bitImageRaster": true, + "graphics": false, + "highDensity": true, + "paperFullCut": false, + "paperPartCut": false, + "pdf417Code": false, + "pulseBel": false, + "pulseStandard": true, + "qrCode": false, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 32, + "name": "Font A" + }, + "1": { + "columns": 42, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": 57.5, + "pixels": 384 + } + }, + "name": "POS5890 Series", + "notes": "POS-5890 thermal printer series, also marketed under various other names.\n", + "vendor": "Zjiang" + }, + "SP2000": { + "codePages": { + "0": "CP437", + "1": "CP437", + "2": "CP932", + "3": "CP437", + "4": "CP858", + "5": "CP852", + "6": "CP860", + "7": "CP861", + "8": "CP863", + "9": "CP865", + "10": "CP866", + "11": "CP855", + "12": "CP857", + "13": "CP862", + "14": "CP864", + "15": "CP737", + "16": "CP851", + "17": "CP869", + "18": "CP928", + "19": "CP772", + "20": "CP774", + "21": "CP874", + "32": "CP1252", + "33": "CP1250", + "34": "CP1251", + "64": "CP3840", + "65": "CP3841", + "66": "CP3843", + "67": "CP3844", + "68": "CP3845", + "69": "CP3846", + "70": "CP3847", + "71": "CP3848", + "72": "CP1001", + "73": "CP2001", + "74": "CP3001", + "75": "CP3002", + "76": "CP3011", + "77": "CP3012", + "78": "CP3021", + "79": "CP3041", + "96": "Unknown", + "97": "Unknown", + "98": "Unknown", + "99": "Unknown", + "100": "Unknown", + "101": "Unknown", + "102": "Unknown", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": true + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "SP2000 Series", + "notes": "Star SP2000 impact printer series with ESC/POS emulation enabled", + "vendor": "Star Micronics" + }, + "TEP-200M": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "6": "Unknown", + "7": "Unknown", + "8": "Unknown", + "11": "CP851", + "12": "CP853", + "13": "CP857", + "14": "CP737", + "15": "ISO_8859-7", + "16": "CP1252", + "17": "CP866", + "18": "CP852", + "19": "CP858", + "20": "Unknown", + "21": "CP874", + "22": "Unknown", + "23": "Unknown", + "24": "Unknown", + "25": "Unknown", + "26": "Unknown", + "30": "TCVN-3-1", + "31": "TCVN-3-2", + "32": "CP720", + "33": "CP775", + "34": "CP855", + "35": "CP861", + "36": "CP862", + "37": "CP864", + "38": "CP869", + "39": "ISO_8859-2", + "40": "ISO_8859-15", + "41": "CP1098", + "42": "CP774", + "43": "CP772", + "44": "CP1125", + "45": "CP1250", + "46": "CP1251", + "47": "CP1253", + "48": "CP1254", + "49": "CP1255", + "50": "CP1256", + "51": "CP1257", + "52": "CP1258", + "53": "RK1048", + "66": "Unknown", + "67": "Unknown", + "68": "Unknown", + "69": "Unknown", + "70": "Unknown", + "71": "Unknown", + "72": "Unknown", + "73": "Unknown", + "74": "Unknown", + "75": "Unknown", + "82": "Unknown", + "254": "Unknown", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "TEP200M Series", + "notes": "", + "vendor": "EPOS" + }, + "TM-P80": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "6": "Unknown", + "7": "Unknown", + "8": "Unknown", + "11": "CP851", + "12": "CP853", + "13": "CP857", + "14": "CP737", + "15": "ISO_8859-7", + "16": "CP1252", + "17": "CP866", + "18": "CP852", + "19": "CP858", + "20": "Unknown", + "21": "CP874", + "22": "Unknown", + "23": "Unknown", + "24": "Unknown", + "25": "Unknown", + "26": "Unknown", + "30": "TCVN-3-1", + "31": "TCVN-3-2", + "32": "CP720", + "33": "CP775", + "34": "CP855", + "35": "CP861", + "36": "CP862", + "37": "CP864", + "38": "CP869", + "39": "ISO_8859-2", + "40": "ISO_8859-15", + "41": "CP1098", + "42": "CP774", + "43": "CP772", + "44": "CP1125", + "45": "CP1250", + "46": "CP1251", + "47": "CP1253", + "48": "CP1254", + "49": "CP1255", + "50": "CP1256", + "51": "CP1257", + "52": "CP1258", + "53": "RK1048", + "66": "Unknown", + "67": "Unknown", + "68": "Unknown", + "69": "Unknown", + "70": "Unknown", + "71": "Unknown", + "72": "Unknown", + "73": "Unknown", + "74": "Unknown", + "75": "Unknown", + "82": "Unknown", + "254": "Unknown", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + }, + "2": { + "columns": 24, + "name": "Kanji" + } + }, + "media": { + "width": { + "mm": 72, + "pixels": 576 + } + }, + "name": "TM-P80", + "notes": "Portable printer (48-column mode)", + "vendor": "Epson" + }, + "TM-P80-42col": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "6": "Unknown", + "7": "Unknown", + "8": "Unknown", + "11": "CP851", + "12": "CP853", + "13": "CP857", + "14": "CP737", + "15": "ISO_8859-7", + "16": "CP1252", + "17": "CP866", + "18": "CP852", + "19": "CP858", + "20": "Unknown", + "21": "CP874", + "22": "Unknown", + "23": "Unknown", + "24": "Unknown", + "25": "Unknown", + "26": "Unknown", + "30": "TCVN-3-1", + "31": "TCVN-3-2", + "32": "CP720", + "33": "CP775", + "34": "CP855", + "35": "CP861", + "36": "CP862", + "37": "CP864", + "38": "CP869", + "39": "ISO_8859-2", + "40": "ISO_8859-15", + "41": "CP1098", + "42": "CP774", + "43": "CP772", + "44": "CP1125", + "45": "CP1250", + "46": "CP1251", + "47": "CP1253", + "48": "CP1254", + "49": "CP1255", + "50": "CP1256", + "51": "CP1257", + "52": "CP1258", + "53": "RK1048", + "66": "Unknown", + "67": "Unknown", + "68": "Unknown", + "69": "Unknown", + "70": "Unknown", + "71": "Unknown", + "72": "Unknown", + "73": "Unknown", + "74": "Unknown", + "75": "Unknown", + "82": "Unknown", + "254": "Unknown", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 60, + "name": "Font B" + }, + "2": { + "columns": 21, + "name": "Kanji" + } + }, + "media": { + "width": { + "mm": 63.6, + "pixels": 546 + } + }, + "name": "TM-P80 (42 column mode)", + "notes": "Portable printer (42-column mode)", + "vendor": "Epson" + }, + "TM-T88II": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "19": "CP858", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "TM-T88II", + "notes": "Epson TM-T88II profile. This printer is discontinued by the Vendor, and has similar feature support to the TM-T88III. The code page mapping is documented in the \"TM-T88II/T88III Technical Reference Guide\".\n", + "vendor": "Epson" + }, + "TM-T88III": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "16": "CP1252", + "17": "CP866", + "18": "CP862", + "19": "CP858", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "TM-T88III", + "notes": "Epson TM-T88III profile. This printer has similar feature support to the TM-T88II. The code page mapping is documented in the \"TM-T88II/T88III Technical Reference Guide\".\n", + "vendor": "Epson" + }, + "TM-T88IV": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "16": "CP1252", + "17": "CP866", + "18": "CP852", + "19": "CP858", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "TM-T88IV", + "notes": "Epson TM-T88IV profile\n", + "vendor": "Epson" + }, + "TM-T88IV-SA": { + "codePages": { + "0": "CP437", + "20": "Unknown", + "21": "CP874", + "26": "Unknown", + "30": "TCVN-3-1", + "31": "TCVN-3-2" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "TM-T88IV South Asia", + "notes": "Epson TM-T88IV profile (South Asia models)\n", + "vendor": "Epson" + }, + "TM-U220": { + "codePages": { + "0": "CP437" + }, + "colors": { + "0": "black", + "1": "alternate" + }, + "features": { + "barcodeA": false, + "barcodeB": false, + "bitImageColumn": true, + "bitImageRaster": false, + "graphics": false, + "highDensity": false, + "paperFullCut": false, + "paperPartCut": false, + "pdf417Code": false, + "pulseBel": false, + "pulseStandard": true, + "qrCode": false, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": 80, + "pixels": "Unknown" + } + }, + "name": "TM-U220", + "notes": "Two-color impact printer with 80mm output", + "vendor": "Epson" + }, + "TSP600": { + "codePages": { + "0": "CP437", + "1": "CP437", + "2": "CP932", + "3": "CP437", + "4": "CP858", + "5": "CP852", + "6": "CP860", + "7": "CP861", + "8": "CP863", + "9": "CP865", + "10": "CP866", + "11": "CP855", + "12": "CP857", + "13": "CP862", + "14": "CP864", + "15": "CP737", + "16": "CP851", + "17": "CP869", + "18": "CP928", + "19": "CP772", + "20": "CP774", + "21": "CP874", + "32": "CP1252", + "33": "CP1250", + "34": "CP1251", + "64": "CP3840", + "65": "CP3841", + "66": "CP3843", + "67": "CP3844", + "68": "CP3845", + "69": "CP3846", + "70": "CP3847", + "71": "CP3848", + "72": "CP1001", + "73": "CP2001", + "74": "CP3001", + "75": "CP3002", + "76": "CP3011", + "77": "CP3012", + "78": "CP3021", + "79": "CP3041", + "96": "Unknown", + "97": "Unknown", + "98": "Unknown", + "99": "Unknown", + "100": "Unknown", + "101": "Unknown", + "102": "Unknown", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": true + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "TSP600 Series", + "notes": "Star TSP600 thermal printer series with ESC/POS emulation enabled", + "vendor": "Star Micronics" + }, + "TUP500": { + "codePages": { + "0": "CP437", + "1": "CP437", + "2": "CP932", + "3": "CP437", + "4": "CP858", + "5": "CP852", + "6": "CP860", + "7": "CP861", + "8": "CP863", + "9": "CP865", + "10": "CP866", + "11": "CP855", + "12": "CP857", + "13": "CP862", + "14": "CP864", + "15": "CP737", + "16": "CP851", + "17": "CP869", + "18": "CP928", + "19": "CP772", + "20": "CP774", + "21": "CP874", + "32": "CP1252", + "33": "CP1250", + "34": "CP1251", + "64": "CP3840", + "65": "CP3841", + "66": "CP3843", + "67": "CP3844", + "68": "CP3845", + "69": "CP3846", + "70": "CP3847", + "71": "CP3848", + "72": "CP1001", + "73": "CP2001", + "74": "CP3001", + "75": "CP3002", + "76": "CP3011", + "77": "CP3012", + "78": "CP3021", + "79": "CP3041", + "96": "Unknown", + "97": "Unknown", + "98": "Unknown", + "99": "Unknown", + "100": "Unknown", + "101": "Unknown", + "102": "Unknown", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": true + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "TUP500 Series", + "notes": "Star TUP500 thermal printer series with ESC/POS emulation enabled", + "vendor": "Star Micronics" + }, + "default": { + "codePages": { + "0": "CP437", + "1": "CP932", + "2": "CP850", + "3": "CP860", + "4": "CP863", + "5": "CP865", + "6": "Unknown", + "7": "Unknown", + "8": "Unknown", + "11": "CP851", + "12": "CP853", + "13": "CP857", + "14": "CP737", + "15": "ISO_8859-7", + "16": "CP1252", + "17": "CP866", + "18": "CP852", + "19": "CP858", + "20": "Unknown", + "21": "CP874", + "22": "Unknown", + "23": "Unknown", + "24": "Unknown", + "25": "Unknown", + "26": "Unknown", + "30": "TCVN-3-1", + "31": "TCVN-3-2", + "32": "CP720", + "33": "CP775", + "34": "CP855", + "35": "CP861", + "36": "CP862", + "37": "CP864", + "38": "CP869", + "39": "ISO_8859-2", + "40": "ISO_8859-15", + "41": "CP1098", + "42": "CP774", + "43": "CP772", + "44": "CP1125", + "45": "CP1250", + "46": "CP1251", + "47": "CP1253", + "48": "CP1254", + "49": "CP1255", + "50": "CP1256", + "51": "CP1257", + "52": "CP1258", + "53": "RK1048", + "66": "Unknown", + "67": "Unknown", + "68": "Unknown", + "69": "Unknown", + "70": "Unknown", + "71": "Unknown", + "72": "Unknown", + "73": "Unknown", + "74": "Unknown", + "75": "Unknown", + "82": "Unknown", + "254": "Unknown", + "255": "Unknown" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": true, + "barcodeB": true, + "bitImageColumn": true, + "bitImageRaster": true, + "graphics": true, + "highDensity": true, + "paperFullCut": true, + "paperPartCut": true, + "pdf417Code": true, + "pulseBel": false, + "pulseStandard": true, + "qrCode": true, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "Default", + "notes": "Default ESC/POS profile, suitable for standards-compliant or Epson-branded printers. This profile allows the use of standard ESC/POS features, and can encode a variety of code pages.\n", + "vendor": "Generic" + }, + "simple": { + "codePages": { + "0": "CP437" + }, + "colors": { + "0": "black" + }, + "features": { + "barcodeA": false, + "barcodeB": false, + "bitImageColumn": false, + "bitImageRaster": true, + "graphics": false, + "highDensity": true, + "paperFullCut": false, + "paperPartCut": false, + "pdf417Code": false, + "pulseBel": false, + "pulseStandard": true, + "qrCode": false, + "starCommands": false + }, + "fonts": { + "0": { + "columns": 42, + "name": "Font A" + }, + "1": { + "columns": 56, + "name": "Font B" + } + }, + "media": { + "width": { + "mm": "Unknown", + "pixels": "Unknown" + } + }, + "name": "Simple", + "notes": "A profile for use in printers with unknown or poor compatibility. This profile indicates that a small number of features are supported, so that commands are not sent a printer that is unlikely to understand them.\n", + "vendor": "Generic" + } + } +} \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/src/NetworkPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/NetworkPrintConnector.php deleted file mode 100644 index 4dd2c39f115..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/NetworkPrintConnector.php +++ /dev/null @@ -1,39 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * PrintConnector for directly opening a network socket to a printer to send it commands. - */ -class NetworkPrintConnector extends FilePrintConnector { - public function __construct($ip, $port = "9100") { - $this -> fp = @fsockopen($ip, $port, $errno, $errstr); - if($this -> fp === false) { - throw new Exception("Cannot initialise NetworkPrintConnector: " . $errstr); - } - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/P822DCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/P822DCapabilityProfile.php deleted file mode 100644 index 7c3b5abe6dd..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/P822DCapabilityProfile.php +++ /dev/null @@ -1,90 +0,0 @@ - CodePage::CP437, - 1 => false, // Katakana - 2 => CodePage::CP850, - 3 => CodePage::CP860, - 4 => CodePage::CP863, - 5 => CodePage::CP865, - 6 => false, // Western Europe - 7 => false, // Greek - 8 => false, // Hebrew - 9 => false, // Eastern europe - 10 => false, // Iran - 16 => CodePage::CP1252 , - 17 => CodePage::CP866 , - 18 => CodePage::CP852 , - 19 => CodePage::CP858, - 20 => false, // Iran II - 21 => false, // latvian - 22 => false, //Arabic - 23 => false, // PT151, 1251 - 24 => CodePage::CP747, - 25 => CodePage::CP1257, - 27 => false, // Vietnam, - 28 => CodePage::CP864, - 29 => CodePage::CP1001, - 30 => false, // Uigur - 31 => false, // Hebrew - 32 => CodePage::CP1255, - 33 => CodePage::CP720, - 34 => CodePage::CP1256, - 35 => CodePage::CP1257, - 255 => false, // Thai - - 50 => CodePage::CP437, - 51 => false, // Jatakana, - 52 => CodePage::CP437, - 53 => CodePage::CP858, - 54 => CodePage::CP852, - 55 => CodePage::CP860, - 56 => CodePage::CP861, - 57 => CodePage::CP863, - 58 => CodePage::CP865, - 59 => CodePage::CP866, - 60 => CodePage::CP855, - 61 => CodePage::CP857, - 62 => CodePage::CP862, - 63 => CodePage::CP864, - 64 => CodePage::CP737, - 65 => CodePage::CP851, - 66 => CodePage::CP869, - 67 => CodePage::CP928, - 68 => CodePage::CP772, - 69 => CodePage::CP774, - 70 => CodePage::CP874, - 71 => CodePage::CP1252, - 72 => CodePage::CP1250, - 73 => CodePage::CP1251, - 74 => CodePage::CP3840, - 75 => CodePage::CP3841, - 76 => CodePage::CP3843, - 77 => CodePage::CP3844, - 78 => CodePage::CP3845, - 79 => CodePage::CP3846, - 80 => CodePage::CP3847, - 81 => CodePage::CP3848, - 82 => CodePage::CP1001, - 83 => CodePage::CP2001, - 84 => CodePage::CP3001, - 85 => CodePage::CP3002, - 86 => CodePage::CP3011, - 87 => CodePage::CP3012, - 88 => CodePage::CP3021, - 89 => CodePage::CP3041 - ); - } - - public function getSupportsGraphics() { - /* Ask the driver to use bitImage wherever possible instead of graphics */ - return false; - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/PrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/PrintBuffer.php deleted file mode 100644 index 9e3b110085f..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/PrintBuffer.php +++ /dev/null @@ -1,75 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Print buffers manage newlines and character encoding for the target printer. - * They are used as a swappable component: text or image-based output. - * - * - Text output (EscposPrintBuffer) is the fast default, and is recommended for - * most people, as the text output can be more directly manipulated by ESC/POS - * commands. - * - Image output (ImagePrintBuffer) is designed to accept more encodings than the - * physical printer supports, by rendering the text to small images on-the-fly. - * This takes a lot more CPU than sending text, but is necessary for some users. - * - If your use case fits outside these, then a further speed/flexibility trade-off - * can be made by printing directly from generated HTML or PDF. - */ -interface PrintBuffer { - /** - * Cause the buffer to send any partial input and wait on a newline. - * If the printer is already on a new line, this does nothing. - */ - function flush(); - - /** - * Used by Escpos to check if a printer is set. - */ - function getPrinter(); - - /** - * Used by Escpos to hook up one-to-one link between buffers and printers. - * - * @param Escpos $printer New printer - */ - function setPrinter(Escpos $printer = null); - - /** - * Accept UTF-8 text for printing. - * - * @param string $text Text to print - */ - function writeText($text); - - /** - * Accept 8-bit text in the current encoding and add it to the buffer. - * - * @param string $text Text to print, already the target encoding. - */ - function writeTextRaw($text); -} -?> \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/src/PrintConnector.php b/htdocs/includes/mike42/escpos-php/src/PrintConnector.php deleted file mode 100644 index f1d37be9c55..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/PrintConnector.php +++ /dev/null @@ -1,56 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Interface passed to Escpos class for receiving print data. Print connectors - * are responsible for transporting this to the actual printer. - */ -interface PrintConnector { - /** - * Print connectors should cause a NOTICE if they are deconstructed - * when they have not been finalized. - */ - public function __destruct(); - - /** - * Finish using this print connector (close file, socket, send - * accumulated output, etc). - */ - public function finalize(); - - /** - * @param string $data - * @return Data read from the printer, or false where reading is not possible. - */ - public function read($len); - - /** - * @param string $data - */ - public function write($data); -} diff --git a/htdocs/includes/mike42/escpos-php/src/SimpleCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/SimpleCapabilityProfile.php deleted file mode 100644 index 7076b5e16cb..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/SimpleCapabilityProfile.php +++ /dev/null @@ -1,17 +0,0 @@ - CodePage::CP437); - } - - public function getSupportsGraphics() { - /* Ask the driver to use bitImage wherever possible instead of graphics */ - return false; - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/StarCapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/StarCapabilityProfile.php deleted file mode 100644 index f61774a5e30..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/StarCapabilityProfile.php +++ /dev/null @@ -1,82 +0,0 @@ - "ÇüéâäàåçêëèïîìÄÅ" . - "ÉæÆôöòûùÿÖÜ¢£¥₧ƒ" . - "áíóúñѪº¿⌐¬½¼¡«»" . - "░▒▓│┤Ā╢ņ╕╣║╗╝╜╛┐" . - "└┴┬├─┼ā╟╚╔╩╦╠═╬╧" . - "Š╤čČ╘╒ģĪī┘┌█▄ūŪ▀" . - "αßΓπΣσµτΦΘΩδ∞φε∩" . - "ĒēĢķĶļĻžŽ∙·√Ņš■ ", - 'CP3012' => "АБВГДЕЖЗИЙКЛМНОП" . - "РСТУФХЦЧШЩЪЫЬЭЮЯ" . - "абвгдежзийклмноп" . - "░▒▓│┤Ā╢ņ╕╣║╗╝Ō╛┐" . - "└┴┬├─┼ā╟╚╔╩╦╠═╬╧" . - "Š╤čČ╘╒ģĪī┘┌█▄ūŪ▀" . - "рстуфхцчшщъыьэюя" . - "ĒēĢķĶļĻžŽ∙·√Ņš■ " - ); - } - - function getSupportedCodePages() { - return array( - 0 => CodePage::CP437, // "Normal" - 1 => CodePage::CP437, - 2 => CodePage::CP932, - 3 => CodePage::CP437, - 4 => CodePage::CP858, - 5 => CodePage::CP852, - 6 => CodePage::CP860, - 7 => CodePage::CP861, - 8 => CodePage::CP863, - 9 => CodePage::CP865, - 10 => CodePage::CP866, - 11 => CodePage::CP855, - 12 => CodePage::CP857, - 13 => CodePage::CP862, - 14 => CodePage::CP864, - 15 => CodePage::CP737, - 16 => CodePage::CP851, - 17 => CodePage::CP869, - 18 => CodePage::CP928, - 19 => CodePage::CP772, - 20 => CodePage::CP774, - 21 => CodePage::CP874, - 32 => CodePage::CP1252, - 33 => CodePage::CP1250, - 34 => CodePage::CP1251, - 64 => CodePage::CP3840, - 65 => CodePage::CP3841, - 66 => CodePage::CP3843, - 67 => CodePage::CP3844, - 68 => CodePage::CP3845, - 69 => CodePage::CP3846, - 70 => CodePage::CP3847, - 71 => CodePage::CP3848, - 72 => CodePage::CP1001, - 73 => CodePage::CP2001, - 74 => CodePage::CP3001, - 75 => CodePage::CP3002, - 76 => 'custom:CP3011', - 77 => 'custom:CP3012', - 78 => CodePage::CP3021, - 79 => CodePage::CP3041, - 96 => false, // Thai Character Code 42 - 97 => false, // Thai Character Code 11 - 98 => false, // Thai Character Code 13 - 99 => false, // Thai Character Code 14 - 100 => false, // Thai Character Code 16 - 101 => false, // Thai Character Code 17 - 102 => false, // Thai Character Code 18 - 255 => false); - } - - function getSupportsStarCommands() { - /* Allows Escpos.php to substitute emulated ESC/POS commands with native ones for this printer. */ - return true; - } -} \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/src/WindowsPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/WindowsPrintConnector.php deleted file mode 100644 index 717e9c1a572..00000000000 --- a/htdocs/includes/mike42/escpos-php/src/WindowsPrintConnector.php +++ /dev/null @@ -1,356 +0,0 @@ -, - * incorporating modifications by: - * - Roni Saha - * - Gergely Radics - * - Warren Doyle - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * Connector for sending print jobs to - * - local ports on windows (COM1, LPT1, etc) - * - shared (SMB) printers from any platform (\\server\foo) - * For USB printers or other ports, the trick is to share the printer with a generic text driver, then access it locally. - */ -class WindowsPrintConnector implements PrintConnector { - /** - * @var array Accumulated lines of output for later use. - */ - private $buffer; - - /** - * @var string The hostname of the target machine, or null if this is a local connection. - */ - private $hostname; - - /** - * @var boolean True if a port is being used directly (must be Windows), false if network shares will be used. - */ - private $isLocal; - - /** - * @var int Platform we're running on, for selecting different commands. See PLATFORM_* constants. - */ - private $platform; - - /** - * @var string The name of the target printer (eg "Foo Printer") or port ("COM1", "LPT1"). - */ - private $printerName; - - /** - * @var string Login name for network printer, or null if not using authentication. - */ - private $userName; - - /** - * @var string Password for network printer, or null if no password is required. - */ - private $userPassword; - - /** - * @var string Workgroup that the printer is located on - */ - private $workgroup; - - /** - * @var int represents Linux - */ - const PLATFORM_LINUX = 0; - - /** - * @var int represents Mac - */ - const PLATFORM_MAC = 1; - - /** - * @var int represents Windows - */ - const PLATFORM_WIN = 2; - - /** - * @var string Valid local ports. - */ - const REGEX_LOCAL = "/^(LPT\d|COM\d)$/"; - - /** - * @var string Valid printer name. - */ - const REGEX_PRINTERNAME = "/^[\w-]+(\s[\w-]+)*$/"; - - /** - * @var string Valid smb:// URI containing hostname & printer with optional user & optional password only. - */ - const REGEX_SMB = "/^smb:\/\/([\s\w-]+(:[\s\w-]+)?@)?[\w-]+\/([\w-]+\/)?[\w-]+(\s[\w-]+)*$/"; - - /** - * @param string $dest - * @throws BadMethodCallException - */ - public function __construct($dest) { - $this -> platform = $this -> getCurrentPlatform(); - $this -> isLocal = false; - $this -> buffer = null; - $this -> userName = null; - $this -> userPassword = null; - $this -> workgroup = null; - if(preg_match(self::REGEX_LOCAL, $dest) == 1) { - // Straight to LPT1, COM1 or other local port. Allowed only if we are actually on windows. - if($this -> platform !== self::PLATFORM_WIN) { - throw new BadMethodCallException("WindowsPrintConnector can only be used to print to a local printer ('".$dest."') on a Windows computer."); - } - $this -> isLocal = true; - $this -> hostname = null; - $this -> printerName = $dest; - } else if(preg_match(self::REGEX_SMB, $dest) == 1) { - // Connect to samba share, eg smb://host/printer - $part = parse_url($dest); - $this -> hostname = $part['host']; - /* Printer name and optional workgroup */ - $path = ltrim($part['path'], '/'); - if(strpos($path, "/") !== false) { - $pathPart = explode("/", $path); - $this -> workgroup = $pathPart[0]; - $this -> printerName = $pathPart[1]; - } else { - $this -> printerName = $path; - } - /* Username and password if set */ - if(isset($part['user'])) { - $this -> userName = $part['user']; - if(isset($part['pass'])) { - $this -> userPassword = $part['pass']; - } - } - } else if(preg_match(self::REGEX_PRINTERNAME, $dest) == 1) { - // Just got a printer name. Assume it's on the current computer. - $hostname = gethostname(); - if(!$hostname) { - $hostname = "localhost"; - } - $this -> hostname = $hostname; - $this -> printerName = $dest; - } else { - throw new BadMethodCallException("Printer '" . $dest . "' is not a valid printer name. Use local port (LPT1, COM1, etc) or smb://computer/printer notation."); - } - $this -> buffer = array(); - } - - public function __destruct() { - if($this -> buffer !== null) { - trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); - } - } - - public function finalize() { - $data = implode($this -> buffer); - $this -> buffer = null; - if($this -> platform == self::PLATFORM_WIN) { - $this -> finalizeWin($data); - } else if($this -> platform == self::PLATFORM_LINUX) { - $this -> finalizeLinux($data); - } else { - $this -> finalizeMac($data); - } - } - - /** - * Send job to printer -- platform-specific Linux code. - * - * @param string $data Print data - * @throws Exception - */ - protected function finalizeLinux($data) { - /* Non-Windows samba printing */ - $device = "//" . $this -> hostname . "/" . $this -> printerName; - if($this -> userName !== null) { - $user = ($this -> workgroup != null ? ($this -> workgroup . "\\") : "") . $this -> userName; - if($this -> userPassword == null) { - // No password - $command = sprintf("smbclient %s -U %s -c %s -N", - escapeshellarg($device), - escapeshellarg($user), - escapeshellarg("print -")); - $redactedCommand = $command; - } else { - // With password - $command = sprintf("smbclient %s %s -U %s -c %s", - escapeshellarg($device), - escapeshellarg($this -> userPassword), - escapeshellarg($user), - escapeshellarg("print -")); - $redactedCommand = sprintf("smbclient %s %s -U %s -c %s", - escapeshellarg($device), - escapeshellarg("*****"), - escapeshellarg($user), - escapeshellarg("print -")); - } - } else { - // No authentication information at all - $command = sprintf("smbclient %s -c %s -N", - escapeshellarg($device), - escapeshellarg("print -")); - $redactedCommand = $command; - } - $retval = $this -> runCommand($command, $outputStr, $errorStr, $data); - if($retval != 0) { - throw new Exception("Failed to print. Command \"$redactedCommand\" failed with exit code $retval: " . trim($outputStr)); - } - } - - protected function finalizeMac($data) { - throw new Exception("Mac printing not implemented."); - } - - /** - * Send data to printer -- platform-specific Windows code. - * - * @param string $data - */ - protected function finalizeWin($data) { - /* Windows-friendly printing of all sorts */ - if(!$this -> isLocal) { - /* Networked printing */ - $device = "\\\\" . $this -> hostname . "\\" . $this -> printerName; - if($this -> userName !== null) { - /* Log in */ - $user = "/user:" . ($this -> workgroup != null ? ($this -> workgroup . "\\") : "") . $this -> userName; - if($this -> userPassword == null) { - $command = sprintf("net use %s %s", - escapeshellarg($device), - escapeshellarg($user)); - $redactedCommand = $command; - } else { - $command = sprintf("net use %s %s %s", - escapeshellarg($device), - escapeshellarg($user), - escapeshellarg($this -> userPassword)); - $redactedCommand = sprintf("net use %s %s %s", - escapeshellarg($device), - escapeshellarg($user), - escapeshellarg("*****")); - } - $retval = $this -> runCommand($command, $outputStr, $errorStr); - if($retval != 0) { - throw new Exception("Failed to print. Command \"$redactedCommand\" failed with exit code $retval: " . trim($errorStr)); - } - } - /* Final print-out */ - $filename = tempnam(sys_get_temp_dir(), "escpos"); - file_put_contents($filename, $data); - if(!$this -> runCopy($filename, $device)){ - throw new Exception("Failed to copy file to printer"); - } - unlink($filename); - } else { - /* Drop data straight on the printer */ - if(!$this -> runWrite($data, $this -> printerName)) { - throw new Exception("Failed to write file to printer at " . $this -> printerName); - } - } - } - - /** - * @return string Current platform. Separated out for testing purposes. - */ - protected function getCurrentPlatform() { - if(PHP_OS == "WINNT") { - return self::PLATFORM_WIN; - } - if(PHP_OS == "Darwin") { - return self::PLATFORM_MAC; - } - return self::PLATFORM_LINUX; - } - - /* (non-PHPdoc) - * @see PrintConnector::read() - */ - public function read($len) { - /* Two-way communication is not supported */ - return false; - } - - /** - * Run a command, pass it data, and retrieve its return value, standard output, and standard error. - * - * @param string $command the command to run. - * @param string $outputStr variable to fill with standard output. - * @param string $errorStr variable to fill with standard error. - * @param string $inputStr text to pass to the command's standard input (optional). - * @return number - */ - protected function runCommand($command, &$outputStr, &$errorStr, $inputStr = null) { - $descriptors = array( - 0 => array("pipe", "r"), - 1 => array("pipe", "w"), - 2 => array("pipe", "w"), - ); - $process = proc_open($command, $descriptors, $fd); - if (is_resource($process)) { - /* Write to input */ - if($inputStr !== null) { - fwrite($fd[0], $inputStr); - } - fclose($fd[0]); - /* Read stdout */ - $outputStr = stream_get_contents($fd[1]); - fclose($fd[1]); - /* Read stderr */ - $errorStr = stream_get_contents($fd[2]); - fclose($fd[2]); - /* Finish up */ - $retval = proc_close($process); - return $retval; - } else { - /* Method calling this should notice a non-zero exit and print an error */ - return -1; - } - } - - /** - * Copy a file. Separated out so that nothing is actually printed during test runs. - * - * @param string $from Source file - * @param string $to Destination file - * @return boolean True if copy was successful, false otherwise - */ - protected function runCopy($from, $to) { - return copy($from, $to); - } - - /** - * Write data to a file. Separated out so that nothing is actually printed during test runs. - * - * @param string $data Data to print - * @param string $to Destination file - * @return boolean True if write was successful, false otherwise - */ - protected function runWrite($data, $to) { - return file_put_contents($data, $to) !== false; - } - - public function write($data) { - $this -> buffer[] = $data; - } -} diff --git a/htdocs/includes/mike42/escpos-php/src/cache/Characters-DefaultCapabilityProfile.ser.gz b/htdocs/includes/mike42/escpos-php/src/cache/Characters-DefaultCapabilityProfile.ser.gz deleted file mode 100644 index 43ad39d229582af5ad7121088bf2c6287e067e11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12928 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

AN>wkF3^lWB>v&YPaMdeJ# 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 diff --git a/htdocs/includes/mike42/escpos-php/src/cache/Characters-SimpleCapabilityProfile.ser.gz b/htdocs/includes/mike42/escpos-php/src/cache/Characters-SimpleCapabilityProfile.ser.gz deleted file mode 100644 index 288b7d3740782fbcc9d9a28d71a6ecc330683eb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1116 zcmV-i1f%;OiwFP!0000019jGCa}-Aq2H^j4zu=@ppj-W#6S@x+l>LD!S5XvI%G|-( zDBPZM&N)j+LdafhIRGb;P0kqyYz!D2xgGlLa@lWxQt7$b*`As1-br{d@8Etf?nM$G zCHCw~lRM>N;gO`CvM?<}uDCNAj@HmhwhZCfOE_CYw{>ZDVf! zrP{9H4RVQ(<`;%MzXIgRu7}KTVtJ#+Q=|sNQ26~KPXc$d7?qYbz8mBu+;Ah|(?)@0 zjDpP=pY|1FdXkS}l(WWSN%@7tjoDL1*Q(+dr+{3_TvGGPaqvGb_)ag9{9yNo70G}7 zmiW)zet+SINM-m}ZuJhT0Am8xfPR4*z@R`apjV&{FeFe97!f!O7#BzZCIr%eQGp|X z8G)mKX@Lx2Qs84it-vRMI)P(=v_J!3SfCM5FVF;76lex43uFQF0zP0}AO~0#XaQ^r zv;uMhZGcXJc7Xur(g7F{=mg*xy28J>Cp+nuAzMuXJ$Ox@KrdiQpbxMh&<|J>7y!%( z3<4Sjh7cK!e;9x{MgZ85QN*5U5E;V|9QQb2Ltp}cI&S!5oPtrl5OLD?)qd_=RPf-_xKK_0BA_#($uaPX@th1r_p{3XUpJ!MjeWREm7Ag5&!_BEvnp6uUIi7lt%62&P6e58UImqUL8VRPqDrgCB^Bi1w<^fP?^KZB zmsL=ES9G5-^Hr6M$TiLIl*n}zG}jv{cYw-2>5zioy zpY$0_`y7%+U-%i(V~>8(AxM}PDoCndAsHm_OBGD~3VXdG@LH$AIsb-t&kDTJfRUPS zF$A;xu0v3Re?Y3x&;P_j_(=YxseyR^#t^_i5qG&M4BDGK;D#4|jh0lzkjbXRFnB3hb^MN8s^XWjvL>zN7b6aWBu>k}&g diff --git a/htdocs/includes/mike42/escpos-php/src/cache/Characters-StarCapabilityProfile.ser.gz b/htdocs/includes/mike42/escpos-php/src/cache/Characters-StarCapabilityProfile.ser.gz deleted file mode 100644 index e0bb0e5fec5c59a4131ae1f2f4151d392f435b91..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9416 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 $c) { - $code = ord($c); - if($code < 32 || $code > 126) { - $chars[$i] = "\\x" . bin2hex($c); - } - } - return implode($chars); + $chars = str_split($in); + foreach ($chars as $i => $c) { + $code = ord($c); + if ($code < 32 || $code > 126) { + $chars[$i] = "\\x" . bin2hex($c); + } + } + return implode($chars); } diff --git a/htdocs/includes/mike42/escpos-php/test/integration/ExampleTest.php b/htdocs/includes/mike42/escpos-php/test/integration/ExampleTest.php index 689891e2432..6ba8e23e59e 100644 --- a/htdocs/includes/mike42/escpos-php/test/integration/ExampleTest.php +++ b/htdocs/includes/mike42/escpos-php/test/integration/ExampleTest.php @@ -1,126 +1,187 @@ exampleDir = dirname(__FILE__) . "/../../example/"; - } - - public function testBitImage() { - $this -> requireGraphicsLibrary(); - $outp = $this -> runExample("bit-image.php"); - $this -> outpTest($outp, "bit-image.bin"); - } - - public function testCharacterEncodings() { - $outp = $this -> runExample("character-encodings.php"); - $this -> outpTest($outp, "character-encodings.bin"); - } - - public function testCharacterTables() { - $outp = $this -> runExample("character-tables.php"); - $this -> outpTest($outp, "character-tables.bin"); - } - - private function outpTest($outp, $fn) { - $file = dirname(__FILE__) . "/resources/output/".$fn; - if(!file_exists($file)) { - file_put_contents($file, $outp); - } - $this -> assertEquals($outp, file_get_contents($file)); - } - - public function testDemo() { - $this -> requireGraphicsLibrary(); - $outp = $this -> runExample("demo.php"); - $this -> outpTest($outp, "demo.bin"); - } - - public function testGraphics() { - $this -> requireGraphicsLibrary(); - $outp = $this -> runExample("graphics.php"); - $this -> outpTest($outp, "graphics.bin"); - } - - public function testReceiptWithLogo() { - $this -> requireGraphicsLibrary(); - $outp = $this -> runExample("receipt-with-logo.php"); - $this -> outpTest($outp, "receipt-with-logo.bin"); - } - - public function testQrCode() { - $outp = $this -> runExample("qr-code.php"); - $this -> outpTest($outp, "qr-code.bin"); - } +use Mike42\Escpos\EscposImage; - public function testBarcode() { - $outp = $this -> runExample("barcode.php"); - $this -> outpTest($outp, "barcode.bin"); - } - - public function testTextSize() { - $outp = $this -> runExample("text-size.php"); - $this -> outpTest($outp, "text-size.bin"); - } +class ExampleTest extends PHPUnit_Framework_TestCase +{ + /* Verify that the examples don't fizzle out with fatal errors */ + private $exampleDir; + + public function setup() + { + $this -> exampleDir = dirname(__FILE__) . "/../../example/"; + } + + /** + * @medium + */ + public function testBitImage() + { + $this->markTestSkipped('Not repeatable on Travis CI.'); + $this -> requireGraphicsLibrary(); + $outp = $this -> runExample("bit-image.php"); + $this -> outpTest($outp, "bit-image.bin"); + } + + /** + * @medium + */ + public function testCharacterEncodings() + { + $outp = $this -> runExample("character-encodings.php"); + $this -> outpTest($outp, "character-encodings.bin"); + } + + /** + * @medium + */ + public function testCharacterTables() + { + $outp = $this -> runExample("character-tables.php"); + $this -> outpTest($outp, "character-tables.bin"); + } + + private function outpTest($outp, $fn) + { + $file = dirname(__FILE__) . "/resources/output/".$fn; + if (!file_exists($file)) { + file_put_contents($file, $outp); + } + $this -> assertEquals($outp, file_get_contents($file)); + } + + /** + * @medium + */ + public function testDemo() + { + $this->markTestSkipped('Not repeatable on Travis CI.'); + $this -> requireGraphicsLibrary(); + $outp = $this -> runExample("demo.php"); + $this -> outpTest($outp, "demo.bin"); + } + + /** + * @medium + */ + public function testGraphics() + { + $this->markTestSkipped('Not repeatable on Travis CI.'); + $this -> requireGraphicsLibrary(); + $outp = $this -> runExample("graphics.php"); + $this -> outpTest($outp, "graphics.bin"); + } + + /** + * @medium + */ + public function testReceiptWithLogo() + { + $this->markTestSkipped('Not repeatable on Travis CI.'); + $this -> requireGraphicsLibrary(); + $outp = $this -> runExample("receipt-with-logo.php"); + $this -> outpTest($outp, "receipt-with-logo.bin"); + } + + /** + * @medium + */ + public function testQrCode() + { + $outp = $this -> runExample("qr-code.php"); + $this -> outpTest($outp, "qr-code.bin"); + } - /** - * @large - */ - public function testPrintFromPdf() { - if(!EscposImage::isImagickLoaded()) { - $this -> markTestSkipped("imagick plugin required for this test"); - } - $outp = $this -> runExample("print-from-pdf.php"); - $this -> outpTest(gzcompress($outp, 9), "print-from-pdf.bin.z"); // Compressing output because it's ~1MB - } + /** + * @medium + */ + public function testBarcode() + { + $outp = $this -> runExample("barcode.php"); + $this -> outpTest($outp, "barcode.bin"); + } + + /** + * @medium + */ + public function testTextSize() + { + $outp = $this -> runExample("text-size.php"); + $this -> outpTest($outp, "text-size.bin"); + } - public function testInterfaceEthernet() { - // Test attempts DNS lookup on some machine - $outp = $this -> runExample("interface/ethernet.php"); - $this -> outpTest($outp, "interface.bin"); - } - - public function testInterfaceLinuxUSB() { - $outp = $this -> runExample("interface/linux-usb.php"); - $this -> outpTest($outp, "interface.bin"); - } - - public function testInterfaceWindowsUSB() { - // Output varies between platforms, not checking. - $outp = $this -> runExample("interface/windows-usb.php"); - $this -> outpTest($outp, "interface.bin"); - } - - public function testInterfaceSMB() { - // Output varies between platforms, not checking. - $outp = $this -> runExample("interface/smb.php"); - $this -> outpTest($outp, "interface.bin"); - } - - public function testInterfaceWindowsLPT() { - // Output varies between platforms, not checking. - $outp = $this -> runExample("interface/windows-lpt.php"); - $this -> outpTest($outp, "interface.bin"); - } - - private function runExample($fn) { - // Change directory and check script - chdir($this -> exampleDir); - $this -> assertTrue(file_exists($fn), "Script $fn not found."); - // Run command and save output - ob_start(); - passthru("php " . escapeshellarg($fn), $retval); - $outp = ob_get_contents(); - ob_end_clean(); - // Check return value - $this -> assertEquals(0, $retval, "Example $fn exited with status $retval"); - return $outp; - } - - protected function requireGraphicsLibrary() { - if(!EscposImage::isGdLoaded() && !EscposImage::isImagickLoaded()) { - $this -> markTestSkipped("This test requires a graphics library."); - } - } + /** + * @medium + */ + public function testMarginsAndSpacing() + { + $outp = $this -> runExample("margins-and-spacing.php"); + $this -> outpTest($outp, "margins-and-spacing.bin"); + } + + /** + * @medium + */ + public function testPdf417Code() + { + $outp = $this -> runExample("pdf417-code.php"); + $this -> outpTest($outp, "pdf417-code.bin"); + } + + public function testInterfaceCups() + { + $outp = $this -> runSyntaxCheck("interface/cups.php"); + } + + public function testInterfaceEthernet() + { + $outp = $this -> runSyntaxCheck("interface/ethernet.php"); + } + + public function testInterfaceLinuxUSB() + { + $outp = $this -> runSyntaxCheck("interface/linux-usb.php"); + } + + public function testInterfaceWindowsUSB() + { + $outp = $this -> runSyntaxCheck("interface/windows-usb.php"); + } + + public function testInterfaceSMB() + { + $outp = $this -> runSyntaxCheck("interface/smb.php"); + } + + public function testInterfaceWindowsLPT() + { + $outp = $this -> runSyntaxCheck("interface/windows-lpt.php"); + } + + private function runSyntaxCheck($fn) + { + $this -> runExample($fn, true); + } + + private function runExample($fn, $syntaxCheck = false) + { + // Change directory and check script + chdir($this -> exampleDir); + $this -> assertTrue(file_exists($fn), "Script $fn not found."); + // Run command and save output + $php = "php" . ($syntaxCheck ? " -l" : ""); + ob_start(); + passthru($php . " " . escapeshellarg($fn), $retval); + $outp = ob_get_contents(); + ob_end_clean(); + // Check return value + $this -> assertEquals(0, $retval, "Example $fn exited with status $retval"); + return $outp; + } + + protected function requireGraphicsLibrary() + { + if (!EscposImage::isGdLoaded() && !EscposImage::isImagickLoaded()) { + $this -> markTestSkipped("This test requires a graphics library."); + } + } } diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/barcode.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/barcode.bin index 79a2daf803edde452d5e0e47aa7e2545bb108962..ae4070d70a02f0b74946bbc6011ef46379dac870 100644 GIT binary patch delta 341 zcmZ1`^jf4|+Cf^;z#}y?J)=Y+F)u|SDX~bQJTs*vgG*YG!6h{X8gI1BwcusWb)|sQ?oU2RTdu zXmdH-W{40_RXN;Zh>$T*h#6HQ&?)6`r$AKsm;%LEQI!GRQO<@cWDXQ!M->A4p&a4| QpciB_G=L7+$g0Q*07+<8IRF3v delta 15 WcmaDYvP_6o+Cer$W3v~dA}0VPTm$U@ diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/character-encodings.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/character-encodings.bin index 0a762c8c160e39da6be9fc7c587b76a53e73c74e..f93ea377722c34a852f80637b7ba278d7c916b7a 100644 GIT binary patch delta 233 zcmeyu+r>ZOp%P#3oRtgbEPpunfx_x}OBB|xS+{KM{AVj>D9oHaXVIEji=WPz%*+@p zC0)YMn380_oLxAdW)v y$3!5#_EjcCUIW7R&dkfuR4Chusx(9FZeE5$Nyd+4g_5064M5ZNHg~aPF#!PJ?O`JT delta 82 zcmV-Y0ImOu5A+R?;UWvY-t6Sw>YL#DAnxJkAolX~>GR^E>((IG-QMN$*yf+slLG-$ o8i8qUZy;A?ZewM0Y+-L8XlZ(HAZuxC8*~7(Z~+?wvmpg(0urz)YXATM diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/character-tables.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/character-tables.bin index f3fb990cea3c56a9631360b2d12cb0e5b64254c6..9979e46bdd51cec37960ec219a39c22204e2003b 100644 GIT binary patch delta 645 zcmaE7ztC=j1uJK9X+c4LQAujbWIt9}Bwiz{Y&cv_lS|r_LAvC>bP2b#D`QAvQckLZ zp`n$6f<|6`i2@d7JP2h*7|J%UU|YgsfJK)GT$hmnhOWuexbGpkuZu?xiMNkO4x53J z2m?(q4OHWm)4<{iIk+ZcpesV0!~ArObthk7T_-A!kO6ugCL<`iPF4XSgT=q!cs1D& zj@@i3qQQyHwa#!u%*-)eyIdC8!?#g*{Bl^m?+!Q695b>em&+j=xEh6bAG?9x2m`T% ar@K6|fz|Tz2tQBWATKY38rHI5j?4h{>C{>P literal 8174 zcmdT}Rdf?k5N#=TaJL*_3)C%}WF1NkjpY#0?C(h z45ESa7c5+~c*)Xb%U7&iwR+9kb?Y~5+_ZVi)@|E&?A*0`&)$7B&_Vhzhj=gwcace>RFz*0_>*o&=LuZ-FAn_8 zyq&8A!x+ev&DZTp0><9q6%(p+E(QF#JA7%tkPgq6r!s&cU6l`07BHlf@nOmVhIha9fTyV6?T6 zf^0nT0sapA!}aF*0)Nf^L~@ZqRsVh=e6D|S4On}V27_b0_`zt|hz;J&iumXmASyhK&6z-)(UBGZpkRgEKURs0#hI>I2 l1{m%IQ8-|@7erAEqjKxXWEf&yyxX3ve?UC!%Etz|`~{yY7?A(~ diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/interface.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/interface.bin deleted file mode 100644 index 729d4f4481b..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/interface.bin +++ /dev/null @@ -1,2 +0,0 @@ -@Hello World! -VA \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/margins-and-spacing.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/margins-and-spacing.bin new file mode 100644 index 0000000000000000000000000000000000000000..0b3a4676033f93f4b13ba388d573ae18975b5086 GIT binary patch literal 339 zcmY+>qf5_d!m*jAca;gz+ z*GGK~k72wOs)0k-hvyXagj|%Z06Ki{wLy_gEXtC}7G=d`hq7j3Y9!5QLrIQNO;Ix= zV<`+oUdmRK1~RwGP#gg6JBFdtukjo&G*1QjTllfkgS`Kr==9Np$SCFe88S*WyvvEo Hp7x736xCmM literal 0 HcmV?d00001 diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/pdf417-code.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/pdf417-code.bin new file mode 100644 index 0000000000000000000000000000000000000000..ab2d7c54958650ba4b50fa76d5fec1a8a69e3cb1 GIT binary patch literal 2366 zcmb_e&riZI6rO^K*};=Hf_dC#LQJ<|$>m#_`bf^&TXehrlZNgzkw)a92iehx6^aF-bc$J6Kn6Ry>G47N5-}tGWL(~;mjdZ zGUu5V@(uhTTaA%O>{m>b)NJj3yi-mYPf52T7GmKY>aH z5iTgs(2s+8kTHHxxKSw{X_3l9<@OgB6h(L-SHA21$*;6_C%Cb!cBS~&)$vUrHSudi ze_kIws2;mlAANx0LNSXak5P4Bd<)f9a#dx_a#ZlAVEP>bV5!c)ON10jo?KSXX!}Xo za1mM;jK9)6*5xkRSR*`04YC-lT$BcX+8BAbt`A+>`XDC{T)e$&NH80*hy_<$s9ARy zL($F-QvgPO4opqaMF`$bYSvj8iW+1wfKqDK$cCZ@$V05pCN(3fDYnNrPb8XL>I&3U zYX0{dm_Wdzxla2yUP?4=heEv}@XLo^tXZSU@(VO5f?5Lhh%_vM+M~P&=s%J%^9B3E z9-!C7NH6vV4N(nNgD8lUXHvtf&^>H)*ejkEW=v;?lHp9_rGP5-bDpfwn%!vTDwh$} Lc)f7DFL$kP%6Aqq literal 0 HcmV?d00001 diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/print-from-pdf.bin.z b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/print-from-pdf.bin.z deleted file mode 100644 index f89eb5d2115e388de90586ff30d80a47fc0ad083..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17081 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 baI$Cav;BIBA!wfEw|@W6|LqUE=-dSWqat^g diff --git a/htdocs/includes/mike42/escpos-php/test/phpunit.xml b/htdocs/includes/mike42/escpos-php/test/phpunit.xml deleted file mode 100644 index f9a6579cf45..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/phpunit.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - unit - - - integration - - - \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/AbstractCapabilityProfileTest.php b/htdocs/includes/mike42/escpos-php/test/unit/AbstractCapabilityProfileTest.php deleted file mode 100644 index b3e72452a9f..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/AbstractCapabilityProfileTest.php +++ /dev/null @@ -1,69 +0,0 @@ - profiles = array('DefaultCapabilityProfile', 'EposTepCapabilityProfile', 'SimpleCapabilityProfile', 'StarCapabilityProfile', 'P822DCapabilityProfile'); - $this -> checklist = array(); - foreach($this -> profiles as $profile) { - $this-> checklist[] = $profile::getInstance(); - } - } - - function testSupportedCodePages() { - foreach($this -> checklist as $obj) { - $check = $obj -> getSupportedCodePages(); - $this -> assertTrue(is_array($check) && isset($check[0]) && $check[0] == 'CP437'); - $custom = $obj -> getCustomCodePages(); - foreach($check as $num => $page) { - $this -> assertTrue(is_numeric($num) && ($page === false || is_string($page))); - if($page === false || strpos($page, ":") === false) { - continue; - } - $part = explode(":", $page); - if(!array_shift($part) == "custom") { - continue; - } - $this -> assertTrue(isset($custom[implode(":", $part)])); - } - } - } - - function testCustomCodePages() { - foreach($this -> checklist as $obj) { - $check = $obj -> getCustomCodePages(); - $this -> assertTrue(is_array($check)); - foreach($check as $name => $customMap) { - $this -> assertTrue(is_string($name)); - $this -> assertTrue(is_string($customMap) && mb_strlen($customMap, 'UTF-8') == 128); - } - } - } - - function testSupportsBitImage() { - foreach($this -> checklist as $obj) { - $check = $obj -> getSupportsBitImage(); - $this -> assertTrue(is_bool($check)); - } - } - - function testSupportsGraphics() { - foreach($this -> checklist as $obj) { - $check = $obj -> getSupportsGraphics(); - $this -> assertTrue(is_bool($check)); - } - } - - function testSupportsQrCode() { - foreach($this -> checklist as $obj) { - $check = $obj -> getSupportsQrCode(); - $this -> assertTrue(is_bool($check)); - } - } -} -?> \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/AuresCustomerDisplayTest.php b/htdocs/includes/mike42/escpos-php/test/unit/AuresCustomerDisplayTest.php new file mode 100644 index 00000000000..c0f803afa97 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/test/unit/AuresCustomerDisplayTest.php @@ -0,0 +1,76 @@ + outputConnector = new DummyPrintConnector(); + $profile = CapabilityProfile::load('OCD-300'); + $this -> printer = new AuresCustomerDisplay($this -> outputConnector, $profile); + } + + protected function checkOutput($expected = null) + { + /* Check those output strings */ + $outp = $this -> outputConnector -> getData(); + if ($expected === null) { + echo "\nOutput was:\n\"" . friendlyBinary($outp) . "\"\n"; + } + $this -> assertEquals($expected, $outp); + } + + protected function tearDown() + { + $this -> outputConnector -> finalize(); + } + + public function testInitializeOutput() + { + $this -> checkOutput("\x02\x05C1\x03\x1b@\x1bt\x00\x1f\x02"); + } + + public function testselectTextScrollMode() { + $this -> outputConnector -> clear(); + $this -> printer -> selectTextScrollMode(AuresCustomerDisplay::TEXT_OVERWRITE); + $this -> checkOutput("\x1f\x01"); + } + + public function testClear() { + $this -> outputConnector -> clear(); + $this -> printer -> clear(); + $this -> checkOutput("\x0c"); + } + + public function testShowFirmwareVersion() { + $this -> outputConnector -> clear(); + $this -> printer -> showFirmwareVersion(); + $this -> checkOutput("\x02\x05V\x01\x03"); + } + + public function testSelfTest() { + $this -> outputConnector -> clear(); + $this -> printer -> selfTest(); + $this -> checkOutput("\x02\x05D\x08\x03"); + } + + public function testShowLogo() { + $this -> outputConnector -> clear(); + $this -> printer -> showLogo(); + $this -> checkOutput("\x02\xfcU\xaaU\xaa"); + } + + public function testTest() { + $this -> outputConnector -> clear(); + // Handling of line-endings differs to regular printers, need to use \r\n + $this -> printer -> text("Hello\nWorld\n"); + $this -> checkOutput("Hello\x0d\x0aWorld\x0d\x0a"); + } +} \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/CapabilityProfileTest.php b/htdocs/includes/mike42/escpos-php/test/unit/CapabilityProfileTest.php new file mode 100644 index 00000000000..923811e7042 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/test/unit/CapabilityProfileTest.php @@ -0,0 +1,59 @@ +assertFalse(array_search('simple', $names) === false); + $this->assertFalse(array_search('default', $names) === false); + $this->assertTrue(array_search('lalalalala', $names) === false); + } + + public function testLoadDefault() + { + // Just load the default profile and check it out + $profile = CapabilityProfile::load('default'); + $this->assertEquals("default", $profile->getId()); + $this->assertEquals("Default", $profile->getName()); + $this->assertTrue($profile->getSupportsBarcodeB()); + $this->assertTrue($profile->getSupportsBitImageRaster()); + $this->assertTrue($profile->getSupportsGraphics()); + $this->assertTrue($profile->getSupportsQrCode()); + $this->assertTrue($profile->getSupportsPdf417Code()); + $this->assertFalse($profile->getSupportsStarCommands()); + $this->assertArrayHasKey('0', $profile->getCodePages()); + } + + public function testCodePageCacheKey() + { + $default = CapabilityProfile::load('default'); + $simple = CapabilityProfile::load('simple'); + $this->assertNotEquals($default->getCodePageCacheKey(), $simple->getCodePageCacheKey()); + } + + public function testBadProfileNameSuggestion() + { + $this->setExpectedException('\InvalidArgumentException', 'simple'); + $profile = CapabilityProfile::load('simpel'); + } + + public function testBadFeatureNameSuggestion() + { + $this->setExpectedException('\InvalidArgumentException', 'graphics'); + $profile = CapabilityProfile::load('default'); + $profile->getFeature('graphicx'); + } + + public function testSuggestions() + { + $input = "orangee"; + $choices = array("apple", "orange", "pear"); + $suggestions = CapabilityProfile::suggestNearest($input, $choices, 1); + $this->assertEquals(1, count($suggestions)); + $this->assertEquals("orange", $suggestions[0]); + } +} \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/CodePageTest.php b/htdocs/includes/mike42/escpos-php/test/unit/CodePageTest.php new file mode 100644 index 00000000000..0e7b661f94d --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/test/unit/CodePageTest.php @@ -0,0 +1,63 @@ +markTestSkipped("Requires iconv"); + } + } + + public function testDataIconv() + { + // Set up CP437 + $this->requiresIconv(); + $cp = new CodePage("CP437", array( + "name" => "CP437", + "iconv" => "CP437" + )); + $this->assertTrue($cp->isEncodable()); + $this->assertEquals($cp->getIconv(), "CP437"); + $this->assertEquals($cp->getName(), "CP437"); + $this->assertEquals($cp->getId(), "CP437"); + $this->assertEquals($cp->getNotes(), null); + // Get data and see if it's right + $data = $cp->getData(); + $expected = "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "; + $this->assertEquals($expected, $data); + } + + public function testDataIconvBogus() + { + // No errors raised, you just get an empty list of supported characters if you try to compute a fake code page + $this->requiresIconv(); + $cp = new CodePage("foo", array( + "name" => "foo", + "iconv" => "foo" + )); + $this->assertTrue($cp->isEncodable()); + $this->assertEquals($cp->getIconv(), "foo"); + $this->assertEquals($cp->getName(), "foo"); + $this->assertEquals($cp->getId(), "foo"); + $this->assertEquals($cp->getNotes(), null); + $data = $cp->getData(); + $expected = str_repeat(" ", 128); + $this->assertEquals($expected, $data); + // Do this twice (caching behaviour) + $data = $cp->getData(); + $this->assertEquals($expected, $data); + } + + public function testDataCannotEncode() + { + $this->setExpectedException('\InvalidArgumentException'); + $cp = new CodePage("foo", array( + "name" => "foo" + )); + $this->assertFalse($cp->isEncodable()); + $cp->getData(); + } +} \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/CupsPrintConnectorTest.php b/htdocs/includes/mike42/escpos-php/test/unit/CupsPrintConnectorTest.php new file mode 100644 index 00000000000..41499ee4b27 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/test/unit/CupsPrintConnectorTest.php @@ -0,0 +1,36 @@ +getMockConnector("FooPrinter", array("FooPrinter")); + $connector->expects($this->once())->method('getCmdOutput')->with($this->stringContains("lp -d 'FooPrinter' ")); + $connector->finalize(); + } + public function testPrinterDoesntExist() + { + $this -> setExpectedException('BadMethodCallException'); + $connector = $this->getMockConnector("FooPrinter", array("OtherPrinter")); + $connector->expects($this->once())->method('getCmdOutput')->with($this->stringContains("lp -d 'FooPrinter' ")); + $connector->finalize(); + } + public function testNoPrinter() + { + $this -> setExpectedException('BadMethodCallException'); + $connector = $this->getMockConnector("FooPrinter", array("")); + } + private function getMockConnector($path, array $printers) + { + $stub = $this->getMockBuilder('Mike42\Escpos\PrintConnectors\CupsPrintConnector')->setMethods(array ( + 'getCmdOutput', + 'getLocalPrinters' + ))->disableOriginalConstructor()->getMock(); + $stub->method('getCmdOutput')->willReturn(""); + $stub->method('getLocalPrinters')->willReturn($printers); + $stub->__construct($path); + return $stub; + } +} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/EscposImageTest.php b/htdocs/includes/mike42/escpos-php/test/unit/EscposImageTest.php index f152f400a2f..08e1be91c50 100644 --- a/htdocs/includes/mike42/escpos-php/test/unit/EscposImageTest.php +++ b/htdocs/includes/mike42/escpos-php/test/unit/EscposImageTest.php @@ -1,235 +1,16 @@ loadAndCheckImg(null, false, false, 0, 0, ""); - } +use Mike42\Escpos\EscposImage; - /** - * BMP handling not yet implemented, but these will use - * a native PHP bitmap reader. - * This just tests that they are not being passed on to another library. - */ - public function testBmpBadFilename() { - $this -> setExpectedException('Exception'); - $this -> loadAndCheckImg('not a real file.bmp', false, false, 1, 1, "\x80"); - } - - public function testBmpBlack() { - $this -> setExpectedException('Exception'); - $this -> loadAndCheckImg("canvas_black.bmp", false, false, 0, 0, "\x80"); - } - - public function testBmpBlackWhite() { - $this -> setExpectedException('Exception'); - $this -> loadAndCheckImg("black_white.bmp", false, false, 0, 0, "\xc0\x00"); - } - - public function testBmpWhite() { - $this -> setExpectedException('Exception'); - $this -> loadAndCheckImg("canvas_white.bmp", false, false, 0, 0, "\x00"); - } - - /** - * GD tests - Load tiny images and check how they are printed. - * These are skipped if you don't have gd. - */ - public function testGdBadFilename() { - $this -> setExpectedException('Exception'); - $this -> loadAndCheckImg('not a real file.png', true, false, 1, 1, "\x80"); - } - - public function testGdBlack() { - foreach(array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('canvas_black.' . $format, true, false, 1, 1, "\x80"); - } - } - - public function testGdBlackTransparent() { - foreach(array('png', 'gif') as $format) { - $this -> loadAndCheckImg('black_transparent.' . $format, true, false, 2, 2, "\xc0\x00"); - } - } - - public function testGdBlackWhite() { - foreach(array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('black_white.' . $format, true, false, 2, 2, "\xc0\x00"); - } - } - - public function testGdWhite() { - foreach(array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('canvas_white.' . $format, true, false, 1, 1, "\x00"); - } - } - - /** - * Imagick tests - Load tiny images and check how they are printed - * These are skipped if you don't have imagick - */ - public function testImagickBadFilename() { - $this -> setExpectedException('Exception'); - $this -> loadAndCheckImg('not a real file.png', false, true, 1, 1, "\x80"); - } - - public function testImagickBlack() { - foreach(array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('canvas_black.' . $format, false, true, 1, 1, "\x80"); - } - } - - public function testImagickBlackTransparent() { - foreach(array('png', 'gif') as $format) { - $this -> loadAndCheckImg('black_transparent.' . $format, false, true, 2, 2, "\xc0\x00"); - } - } - - public function testImagickBlackWhite() { - foreach(array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('black_white.' . $format, false, true, 2, 2, "\xc0\x00"); - } - } - - public function testImagickWhite() { - foreach(array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('canvas_white.' . $format, false, true, 1, 1, "\x00"); - } - } - - /** - * Mixed test - Same as above, but confirms that each tiny image can be loaded - * under any supported library configuration with the same results. - * These are skipped if you don't have gd AND imagick - */ - public function testLibraryDifferences() { - if(!EscposImage::isGdLoaded() || !EscposImage::isImagickLoaded()) { - $this -> markTestSkipped("both gd and imagick plugin are required for this test"); - } - $inFile = array('black_white.png', 'canvas_black.png', 'canvas_white.png'); - foreach($inFile as $fn) { - // Default check - $im = new EscposImage(dirname(__FILE__) . "/resources/$fn"); - $width = $im -> getWidth(); - $height = $im -> getHeight(); - $data = $im -> toRasterFormat(); - // Gd check - $this -> loadAndCheckImg($fn, true, false, $width, $height, $data); - // Imagick check - $this -> loadAndCheckImg($fn, false, true, $width, $height, $data); - } - } - - /** - * PDF tests - load tiny PDF and check for well-formedness - * These are also skipped if you don't have imagick - * @medium - */ - public function testPdfAllPages() { - $this -> loadAndCheckPdf('doc.pdf', null, 1, 1, array("\x00", "\x80")); - } - - public function testPdfBadFilename() { - $this -> setExpectedException('Exception'); - $this -> loadAndCheckPdf('not a real file', null, 1, 1, array()); - } - - /** - * @medium - */ - public function testPdfBadRange() { - // Start page is after end page. - $this -> setExpectedException('Exception'); - $this -> loadAndCheckPdf('doc.pdf', array(1, 0), 1, 1, array("\x00", "\x80")); - } - - /** - * @medium - */ - public function testPdfFirstPage() { - $this -> loadAndCheckPdf('doc.pdf', array(0, 0), 1, 1, array("\x00")); - } - - /** - * @medium - */ - public function testPdfMorePages() { - $this -> loadAndCheckPdf('doc.pdf', array(1, 20), 1, 1, array("\x80")); - } - - /** - * @medium - */ - public function testPdfSecondPage() { - $this -> loadAndCheckPdf('doc.pdf', array(1, 1), 1, 1, array("\x80")); - } - - /** - * @medium - */ - public function testPdfStartPastEndOfDoc() { - // Doc only has pages 0 and 1, can't start reading from 2. - $this -> markTestIncomplete("Test needs revising- produces output due to apparent imagick bug."); - $this -> setExpectedException('ImagickException'); - $this -> loadAndCheckPdf('doc.pdf', array(2, 3), 1, 1, array()); - } - - /** - * Load an EscposImage with (optionally) certain libraries disabled and run a check. - */ - private function loadAndCheckImg($fn, $gd, $imagick, $width, $height, $rasterFormat = null) { - $img = $this -> getMockImage($fn === null ? null : dirname(__FILE__) . "/resources/$fn", $gd, $imagick); - $this -> checkImg($img, $width, $height, $rasterFormat); - } - - /** - * Same as above, loading document and checking pages against some expected values. - */ - private function loadAndCheckPdf($fn, array $range = null, $width, $height, array $rasterFormat = null) { - if(!EscposImage::isImagickLoaded()) { - $this -> markTestSkipped("imagick plugin required for this test"); - } - $pdfPages = EscposImage::loadPdf(dirname(__FILE__) . "/resources/$fn", $width, $range); - $this -> assertTrue(count($pdfPages) == count($rasterFormat), "Got back wrong number of pages"); - foreach($pdfPages as $id => $img) { - $this -> checkImg($img, $width, $height, $rasterFormat[$id]); - } - } - - /** - * Check image against known width, height, output. - */ - private function checkImg(EscposImage $img, $width, $height, $rasterFormat = null) { - if($rasterFormat === null) { - echo "\nImage was: " . $img -> getWidth() . "x" . $img -> getHeight() . ", data \"" . friendlyBinary($img -> toRasterFormat()) . "\""; - } - $this -> assertTrue($img -> getHeight() == $height); - $this -> assertTrue($img -> getWidth() == $width); - $this -> assertTrue($img -> toRasterFormat() == $rasterFormat); - } - - /** - * Load up an EsposImage with given libraries disabled or enabled. Marks the test - * as skipped if you ask for a library which is not loaded. - */ - private function getMockImage($path, $gd, $imagick) { - /* Sanity checks */ - if($gd && !EscposImage::isGdLoaded()) { - $this -> markTestSkipped("gd plugin required for this test"); - } - if($imagick && !EscposImage::isImagickLoaded()) { - $this -> markTestSkipped("imagick plugin required for this test"); - } - $stub = $this -> getMockBuilder('EscposImage') - -> setMethods(array('isGdSupported', 'isImagickSupported')) - -> disableOriginalConstructor() - -> getMock(); - $stub -> method('isGdSupported') - -> willReturn($gd); - $stub -> method('isImagickSupported') - -> willReturn($imagick); - $stub -> __construct($path); - return $stub; - } +class EscposImageTest extends PHPUnit_Framework_TestCase +{ + public function testImageMissingException() + { + $this -> setExpectedException('Exception'); + $img = EscposImage::load('not-a-real-file.png'); + } + public function testImageNotSupportedException() + { + $this -> setExpectedException('InvalidArgumentException'); + $img = EscposImage::load('/dev/null', false, array()); + } } \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/EscposPrintBufferTest.php b/htdocs/includes/mike42/escpos-php/test/unit/EscposPrintBufferTest.php index 2bbdb34c20c..af0ee2b9b73 100644 --- a/htdocs/includes/mike42/escpos-php/test/unit/EscposPrintBufferTest.php +++ b/htdocs/includes/mike42/escpos-php/test/unit/EscposPrintBufferTest.php @@ -2,149 +2,191 @@ /** * Example strings are pangrams using different character sets, and are * testing correct code-table switching. - * + * * When printed, they should appear the same as in this source file. - * + * * Many of these test strings are from: * - http://www.cl.cam.ac.uk/~mgk25/ucs/examples/quickbrown.txt * - http://clagnut.com/blog/2380/ (mirrored from the English Wikipedia) */ -class EscposPrintBufferTest extends PHPUnit_Framework_TestCase { - protected $buffer; - protected $outputConnector; - - protected function setup() { - $this -> outputConnector = new DummyPrintConnector(); - $printer = new Escpos($this -> outputConnector); - $this -> buffer = $printer -> getPrintBuffer(); - } - - protected function checkOutput($expected = null) { - /* Check those output strings */ - $outp = $this -> outputConnector -> getData(); - if($expected === null) { - echo "\nOutput was:\n\"" . friendlyBinary($outp) . "\"\n"; - } - $this -> assertEquals($expected, $outp); - } +use Mike42\Escpos\Printer; +use Mike42\Escpos\PrintConnectors\DummyPrintConnector; - protected function tearDown() { - $this -> outputConnector -> finalize(); - } +class EscposPrintBufferTest extends PHPUnit_Framework_TestCase +{ + protected $buffer; + protected $outputConnector; + + protected function setup() + { + $this -> outputConnector = new DummyPrintConnector(); + $printer = new Printer($this -> outputConnector); + $this -> buffer = $printer -> getPrintBuffer(); + } + + protected function checkOutput($expected = null) + { + /* Check those output strings */ + $outp = $this -> outputConnector -> getData(); + if ($expected === null) { + echo "\nOutput was:\n\"" . friendlyBinary($outp) . "\"\n"; + } + $this -> assertEquals($expected, $outp); + } - public function testRawTextNonprintable() { - $this -> buffer -> writeTextRaw("Test" . Escpos::ESC . "v1\n"); - $this -> checkOutput("\x1b@Test?v1\x0a"); // ASCII ESC character is substituted for '?' - } + protected function tearDown() + { + $this -> outputConnector -> finalize(); + } - public function testDanish() { - $this -> buffer -> writeText("Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther spillede på xylofon.\n"); - $this -> checkOutput("\x1b@Quizdeltagerne spiste jordb\x91r med fl\x1bt\x02\x9bde, mens cirkusklovnen Wolther spillede p\x86 xylofon.\x0a"); - } + public function testRawTextNonprintable() + { + $this -> buffer -> writeTextRaw("Test" . Printer::ESC . "v1\n"); + $this -> checkOutput("\x1b@Test?v1\x0a"); // ASCII ESC character is substituted for '?' + } - public function testGerman() { - $this -> buffer -> writeText("Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.\n"); - $this -> checkOutput("\x1b@Falsches \x9aben von Xylophonmusik qu\x84lt jeden gr\x94\xe1eren Zwerg.\x0a"); - } + public function testDanish() + { + $this -> buffer -> writeText("Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther spillede på xylofon.\n"); + $this -> checkOutput("\x1b@Quizdeltagerne spiste jordb\x91r med fl\x1bt\x02\x9bde, mens cirkusklovnen Wolther spillede p\x86 xylofon.\x0a"); + } - public function testGreek() { - $this -> buffer -> writeText("Ξεσκεπάζω την ψυχοφθόρα βδελυγμία"); - $this -> checkOutput("\x1b@\x1bt\x0b\xbd\xde\xec\xe4\xde\xea\x9b\xe0\xfa \xee\xe1\xe7 \xf6\xf2\xf4\xe9\xf3\xe2\xa2\xeb\xd6 \xd7\xdd\xde\xe5\xf2\xd8\xe6\x9f\xd6"); - } - - public function testGreekWithDiacritics() { - // This is a string which is known to be un-printable in ESC/POS (the grave-accented letters are not in any code page), - // so we are checking the substitution '?' for unknown characters. - $this -> buffer -> writeText("Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ στὸ χρυσαφὶ ξέφωτο.\n"); - $this -> checkOutput("\x1b@\xe2\xe0\x1bt\x0b\xe0\x9d\xde\xed \xe4\xd6? \xe6\xf2\xeb\xee\xe3?\xed \xdd?\xe7 \xe2? \xd7\xeb? \xea\xe3? \xec\xee? \xf4\xeb\xf2\xec\xd6\xf3? \xe8\x9d\xf3\xfa\xee\xe9.\x0a"); - } + public function testGerman() + { + $this -> buffer -> writeText("Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.\n"); + $this -> checkOutput("\x1b@Falsches \x9aben von Xylophonmusik qu\x84lt jeden gr\x94\xe1eren Zwerg.\x0a"); + } - public function testEnglish() { - $this -> buffer -> writeText("The quick brown fox jumps over the lazy dog.\n"); - $this -> checkOutput("\x1b@The quick brown fox jumps over the lazy dog.\n"); - } + public function testGreek() + { + $this -> buffer -> writeText("Ξεσκεπάζω την ψυχοφθόρα βδελυγμία"); + $this -> checkOutput("\x1b@\x1bt\x0e\x8d\x9c\xa9\xa1\x9c\xa7\xe1\x9d\xe0 \xab\x9e\xa4 \xaf\xac\xae\xa6\xad\x9f\xe6\xa8\x98 \x99\x9b\x9c\xa2\xac\x9a\xa3\xe5\x98"); + } - public function testSpanish() { - // This one does not require changing code-pages at all, so characters are just converted from Unicode to CP437. - $this -> buffer -> writeText("El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.\n"); - $this -> checkOutput("\x1b@El ping\x81ino Wenceslao hizo kil\xa2metros bajo exhaustiva lluvia y fr\xa1o, a\xa4oraba a su querido cachorro.\x0a"); - } + public function testGreekWithDiacritics() + { + // This is a string which is known to be un-printable in ESC/POS (the grave-accented letters are not in any code page), + // so we are checking the substitution '?' for unknown characters. + $this -> buffer -> writeText("Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ στὸ χρυσαφὶ ξέφωτο.\n"); + $this -> checkOutput("\x1b@\xe2\xe0\x1bt\x0e\x9d\xe2\x9c\xaa \xa1\x98? \xa3\xac\xa8\xab\xa0?\xaa \x9b?\xa4 \x9f? \x99\xa8? \xa7\xa0? \xa9\xab? \xae\xa8\xac\xa9\x98\xad? \xa5\xe2\xad\xe0\xab\xa6.\x0a"); + } - public function testFrench() { - $this -> buffer -> writeText("Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en canoë au delà des îles, près du mälström où brûlent les novæ.\n"); - $this -> checkOutput("\x1b@Le c\x1bt\x10\x9cur d\xe9\xe7u mais l'\xe2me plut\xf4t na\xefve, Lou\xffs r\xeava de crapa\xfcter en cano\xeb au del\xe0 des \xeeles, pr\xe8s du m\xe4lstr\xf6m o\xf9 br\xfblent les nov\xe6.\x0a"); - } + public function testEnglish() + { + $this -> buffer -> writeText("The quick brown fox jumps over the lazy dog.\n"); + $this -> checkOutput("\x1b@The quick brown fox jumps over the lazy dog.\n"); + } - public function testIrishGaelic() { - // Note that some letters with diacritics cannot be printed for Irish Gaelic text, so text may need to be simplified. - $this -> buffer -> writeText("D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh.\n"); - $this -> checkOutput("\x1b@D'fhuascail \x1bt\x02\xd6osa, \xe9rmhac na h\xe0ighe Beannaithe, p\xa2r \x90ava agus \xb5dhaimh.\x0a"); - } + public function testSpanish() + { + // This one does not require changing code-pages at all, so characters are just converted from Unicode to CP437. + $this -> buffer -> writeText("El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.\n"); + $this -> checkOutput("\x1b@El ping\x81ino Wenceslao hizo kil\xa2metros bajo exhaustiva lluvia y fr\xa1o, a\xa4oraba a su querido cachorro.\x0a"); + } - public function testHungarian() { - $this -> buffer -> writeText("Árvíztűrő tükörfúrógép.\n"); - $this -> checkOutput("\x1b@\x1bt\x02\xb5rv\xa1zt\x1bt\x12\xfbr\x8b t\x81k\x94rf\xa3r\xa2g\x82p.\x0a"); - } - - public function testIcelandic() { - $this -> buffer -> writeText("Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa."); - $this -> checkOutput("\x1b@K\x91mi n\x1bt\x02\xec \x94xi h\x82r ykist \xe7j\xa2fum n\xa3 b\x91\xd0i v\xa1l og \xa0drepa."); - } + public function testFrench() + { + $this -> buffer -> writeText("Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en canoë au delà des îles, près du mälström où brûlent les novæ.\n"); + $this -> checkOutput("\x1b@Le c\x1bt\x10\x9cur d\xe9\xe7u mais l'\xe2me plut\xf4t na\xefve, Lou\xffs r\xeava de crapa\xfcter en cano\xeb au del\xe0 des \xeeles, pr\xe8s du m\xe4lstr\xf6m o\xf9 br\xfblent les nov\xe6.\x0a"); + } - public function testJapaneseHiragana() { - $this -> markTestIncomplete("Non-ASCII character sets not yet supported."); - $this -> buffer -> writeText(implode("\n", array("いろはにほへとちりぬるを", " わかよたれそつねならむ", "うゐのおくやまけふこえて", "あさきゆめみしゑひもせす")) . "\n"); - $this -> checkOutput(); - } + public function testIrishGaelic() + { + // Note that some letters with diacritics cannot be printed for Irish Gaelic text, so text may need to be simplified. + $this -> buffer -> writeText("D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh.\n"); + $this -> checkOutput("\x1b@D'fhuascail \x1bt\x02\xd6osa, \xe9rmhac na h\xe0ighe Beannaithe, p\xa2r \x90ava agus \xb5dhaimh.\x0a"); + } - public function testJapaneseKatakana() { - $this -> markTestIncomplete("Non-ASCII character sets not yet supported."); - $this -> buffer -> writeText(implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン")) . "\n"); - $this -> checkOutput("\x1b@\x1bt\x01\xb2\xdb\xca\xc6\xce\xcd\xc4 \xc1\xd8\xc7\xd9\xa6 \xdc\xb6\xd6\xc0\xda\xbf \xc2\xc8\xc5\xd7\xd1\x0a\xb3\xb2\xc9\xb5\xb8\xd4\xcf \xb9\xcc\xba\xb4\xc3 \xb1\xbb\xb7\xd5\xd2\xd0\xbc \xb4\xcb\xd3\xbe\xbd\xdd\x0a"); - } + public function testHungarian() + { + $this -> buffer -> writeText("Árvíztűrő tükörfúrógép.\n"); + $this -> checkOutput("\x1b@\x1bt\x02\xb5rv\xa1zt\x1bt\x12\xfbr\x8b t\x81k\x94rf\xa3r\xa2g\x82p.\x0a"); + } + + public function testIcelandic() + { + $this -> buffer -> writeText("Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa."); + $this -> checkOutput("\x1b@K\x91mi n\x1bt\x02\xec \x94xi h\x82r ykist \xe7j\xa2fum n\xa3 b\x91\xd0i v\xa1l og \xa0drepa."); + } - public function testJapaneseKataKanaHalfWidth() { - $this -> buffer -> writeText(implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウイノオクヤマ ケフコエテ アサキユメミシ エヒモセスン")) . "\n"); - $this -> checkOutput("\x1b@\x1bt\x01\xb2\xdb\xca\xc6\xce\xcd\xc4 \xc1\xd8\xc7\xd9\xa6 \xdc\xb6\xd6\xc0\xda\xbf \xc2\xc8\xc5\xd7\xd1\x0a\xb3\xb2\xc9\xb5\xb8\xd4\xcf \xb9\xcc\xba\xb4\xc3 \xb1\xbb\xb7\xd5\xd2\xd0\xbc \xb4\xcb\xd3\xbe\xbd\xdd\x0a"); - } - - public function testLatvian() { - $this -> buffer -> writeText("Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus.\n"); - $this -> checkOutput("\x1b@Gl\x1bt!\x83\xd8\xd5\xe9\xd7\xeca r\xd7\xe9\x8c\xd5i dz\x89rum\x83 \xd1iepj Baha koncertfl\x8c\x85e\xebu v\x83kus.\x0a"); - } + public function testJapaneseHiragana() + { + $this -> markTestIncomplete("Non-ASCII character sets not yet supported."); + $this -> buffer -> writeText(implode("\n", array("いろはにほへとちりぬるを", " わかよたれそつねならむ", "うゐのおくやまけふこえて", "あさきゆめみしゑひもせす")) . "\n"); + $this -> checkOutput(); + } - public function testPolish() { - $this -> buffer -> writeText("Pchnąć w tę łódź jeża lub ośm skrzyń fig.\n"); - $this -> checkOutput("\x1b@Pchn\x1bt\x12\xa5\x86 w t\xa9 \x88\xa2d\xab je\xbea lub o\x98m skrzy\xe4 fig.\x0a"); - } + public function testJapaneseKatakana() + { + $this -> markTestIncomplete("Non-ASCII character sets not yet supported."); + $this -> buffer -> writeText(implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン")) . "\n"); + $this -> checkOutput("\x1b@\x1bt\x01\xb2\xdb\xca\xc6\xce\xcd\xc4 \xc1\xd8\xc7\xd9\xa6 \xdc\xb6\xd6\xc0\xda\xbf \xc2\xc8\xc5\xd7\xd1\x0a\xb3\xb2\xc9\xb5\xb8\xd4\xcf \xb9\xcc\xba\xb4\xc3 \xb1\xbb\xb7\xd5\xd2\xd0\xbc \xb4\xcb\xd3\xbe\xbd\xdd\x0a"); + } - public function testRussian() { - $this -> buffer -> writeText("В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!\n"); - $this -> checkOutput("\x1b@\x1bt\x11\x82 \xe7\xa0\xe9\xa0\xe5 \xee\xa3\xa0 \xa6\xa8\xab \xa1\xeb \xe6\xa8\xe2\xe0\xe3\xe1? \x84\xa0, \xad\xae \xe4\xa0\xab\xec\xe8\xa8\xa2\xeb\xa9 \xed\xaa\xa7\xa5\xac\xaf\xab\xef\xe0!\x0a"); - } + public function testJapaneseKataKanaHalfWidth() + { + $this -> buffer -> writeText(implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウイノオクヤマ ケフコエテ アサキユメミシ エヒモセスン")) . "\n"); + $this -> checkOutput("\x1b@\x1bt\x01\xb2\xdb\xca\xc6\xce\xcd\xc4 \xc1\xd8\xc7\xd9\xa6 \xdc\xb6\xd6\xc0\xda\xbf \xc2\xc8\xc5\xd7\xd1\x0a\xb3\xb2\xc9\xb5\xb8\xd4\xcf \xb9\xcc\xba\xb4\xc3 \xb1\xbb\xb7\xd5\xd2\xd0\xbc \xb4\xcb\xd3\xbe\xbd\xdd\x0a"); + } + + public function testLatvian() + { + $this -> buffer -> writeText("Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus.\n"); + $this -> checkOutput("\x1b@Gl\x1bt!\x83\xd8\xd5\xe9\xd7\xeca r\xd7\xe9\x8c\xd5i dz\x89rum\x83 \xd1iepj Baha koncertfl\x8c\x85e\xebu v\x83kus.\x0a"); + } - public function testThai() { - $this -> markTestIncomplete("Non-ASCII character sets not yet supported."); - $this -> buffer -> writeText("นายสังฆภัณฑ์ เฮงพิทักษ์ฝั่ง ผู้เฒ่าซึ่งมีอาชีพเป็นฅนขายฃวด ถูกตำรวจปฏิบัติการจับฟ้องศาล ฐานลักนาฬิกาคุณหญิงฉัตรชฎา ฌานสมาธิ\n"); // Quotation from Wikipedia - $this -> checkOutput(); - } + public function testPolish() + { + $this -> buffer -> writeText("Pchnąć w tę łódź jeża lub ośm skrzyń fig.\n"); + $this -> checkOutput("\x1b@Pchn\x1bt\x12\xa5\x86 w t\xa9 \x88\xa2d\xab je\xbea lub o\x98m skrzy\xe4 fig.\x0a"); + } - public function testTurkish() { - $this -> buffer -> writeText("Pijamalı hasta, yağız şoföre çabucak güvendi.\n"); - $this -> checkOutput("\x1b@Pijamal\x1bt\x02\xd5 hasta, ya\x1bt\x0d\xa7\x8dz \x9fof\x94re \x87abucak g\x81vendi.\x0a"); - } - - public function testArabic() { - $this -> markTestIncomplete("Right-to-left text not yet supported."); - $this -> buffer -> writeText("صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ" . "\n"); // Quotation from Wikipedia - $this -> checkOutput(); - } - - public function testHebrew() { - // RTL text is more complex than the above. - $this -> markTestIncomplete("Right-to-left text not yet supported."); - $this -> buffer -> writeText("דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה" . "\n"); - $this -> checkOutput(); - } + public function testRussian() + { + $this -> buffer -> writeText("В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!\n"); + $this -> checkOutput("\x1b@\x1bt\x11\x82 \xe7\xa0\xe9\xa0\xe5 \xee\xa3\xa0 \xa6\xa8\xab \xa1\xeb \xe6\xa8\xe2\xe0\xe3\xe1? \x84\xa0, \xad\xae \xe4\xa0\xab\xec\xe8\xa8\xa2\xeb\xa9 \xed\xaa\xa7\xa5\xac\xaf\xab\xef\xe0!\x0a"); + } + + public function testThai() + { + $this -> markTestIncomplete("Non-ASCII character sets not yet supported."); + $this -> buffer -> writeText("นายสังฆภัณฑ์ เฮงพิทักษ์ฝั่ง ผู้เฒ่าซึ่งมีอาชีพเป็นฅนขายฃวด ถูกตำรวจปฏิบัติการจับฟ้องศาล ฐานลักนาฬิกาคุณหญิงฉัตรชฎา ฌานสมาธิ\n"); // Quotation from Wikipedia + $this -> checkOutput(); + } + + public function testTurkish() + { + $this -> buffer -> writeText("Pijamalı hasta, yağız şoföre çabucak güvendi.\n"); + $this -> checkOutput("\x1b@Pijamal\x1bt\x02\xd5 hasta, ya\x1bt\x0d\xa7\x8dz \x9fof\x94re \x87abucak g\x81vendi.\x0a"); + } + + public function testArabic() + { + $this -> markTestIncomplete("Right-to-left text not yet supported."); + $this -> buffer -> writeText("صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ" . "\n"); // Quotation from Wikipedia + $this -> checkOutput(); + } + + public function testHebrew() + { + // RTL text is more complex than the above. + $this -> markTestIncomplete("Right-to-left text not yet supported."); + $this -> buffer -> writeText("דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה" . "\n"); + $this -> checkOutput(); + } + + public function testVietnamese() { + $this -> buffer -> writeText("Tiếng Việt, còn gọi tiếng Việt Nam hay Việt ngữ, là ngôn ngữ của người Việt (người Kinh) và là ngôn ngữ chính thức tại Việt Nam.\n"); + $this -> checkOutput("\x1b@Ti\x1bt\x1e\xd5ng Vi\xd6t, c\xdfn g\xe4i ti\xd5ng Vi\xd6t Nam hay Vi\xd6t ng\xf7, l\xb5 ng\xabn ng\xf7 c\xf1a ng\xad\xeai Vi\xd6t (ng\xad\xeai Kinh) v\xb5 l\xb5 ng\xabn ng\xf7 ch\xddnh th\xf8c t\xb9i Vi\xd6t Nam.\x0a"); + } + + public function testWindowsLineEndings() { + $this -> buffer -> writeText("Hello World!\r\n"); + $this -> checkOutput("\x1b@Hello World!\x0a"); + } + + public function testWindowsLineEndingsRaw() { + $this -> buffer -> writeTextRaw("Hello World!\r\n"); + $this -> checkOutput("\x1b@Hello World!\x0a"); + } } - diff --git a/htdocs/includes/mike42/escpos-php/test/unit/EscposTest.php b/htdocs/includes/mike42/escpos-php/test/unit/EscposTest.php index 6fd0bd7d204..0b70e96b370 100644 --- a/htdocs/includes/mike42/escpos-php/test/unit/EscposTest.php +++ b/htdocs/includes/mike42/escpos-php/test/unit/EscposTest.php @@ -1,765 +1,1127 @@ outputConnector = new DummyPrintConnector(); - $this -> printer = new Escpos($this -> outputConnector); - } +class EscposTest extends PHPUnit_Framework_TestCase +{ + protected $printer; + protected $outputConnector; - protected function checkOutput($expected = null) { - /* Check those output strings */ - $outp = $this -> outputConnector -> getData(); - if($expected === null) { - echo "\nOutput was:\n\"" . friendlyBinary($outp) . "\"\n"; - } - $this -> assertEquals($expected, $outp); - } - - protected function tearDown() { - $this -> outputConnector -> finalize(); - } - - protected function requireGraphicsLibrary() { - if(!EscposImage::isGdLoaded() && !EscposImage::isImagickLoaded()) { - // If the test is about to do something which requires a library, - // something must throw an exception. - $this -> setExpectedException('Exception'); - } - } - - public function testInitializeOutput() { - $this -> checkOutput("\x1b\x40"); + protected function setup() + { + /* Print to nowhere- for testing which inputs are accepted */ + $this -> outputConnector = new DummyPrintConnector(); + $this -> printer = new Printer($this -> outputConnector); } - public function testTextStringOutput() { - $this -> printer -> text("The quick brown fox jumps over the lazy dog\n"); - $this -> checkOutput("\x1b@The quick brown fox jumps over the lazy dog\n"); + protected function checkOutput($expected = null) + { + /* Check those output strings */ + $outp = $this -> outputConnector -> getData(); + if ($expected === null) { + echo "\nOutput was:\n\"" . friendlyBinary($outp) . "\"\n"; + } + $this -> assertEquals($expected, $outp); } - public function testTextDefault() { - $this -> printer -> text(); - $this -> checkOutput("\x1b@"); + protected function tearDown() + { + $this -> outputConnector -> finalize(); } - public function testTextString() { - $this -> printer -> text("String"); - $this -> printer -> text(123); - $this -> printer -> text(); - $this -> printer -> text(null); - $this -> printer -> text(1.2); - $this -> printer -> text(new FooBar("FooBar")); - $this -> checkOutput("\x1b@String1231.2FooBar"); + protected function requireGraphicsLibrary() + { + if (!EscposImage::isGdLoaded() && !EscposImage::isImagickLoaded()) { + // If the test is about to do something which requires a library, + // something must throw an exception. + $this -> setExpectedException('Exception'); + } } - public function testTextObject() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> text(new DateTime()); - } - - public function testFeedDefault() { - $this -> printer -> feed(); - $this -> checkOutput("\x1b@\x0a"); + public function testInitializeOutput() + { + $this -> checkOutput("\x1b\x40"); } - public function testFeed3Lines() { - $this -> printer -> feed(3); - $this -> checkOutput("\x1b@\x1bd\x03"); + public function testTextStringOutput() + { + $this -> printer -> text("The quick brown fox jumps over the lazy dog\n"); + $this -> checkOutput("\x1b@The quick brown fox jumps over the lazy dog\n"); } - public function testFeedZero() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feed(0); + public function testTextDefault() + { + $this -> printer -> text(); + $this -> checkOutput("\x1b@"); + } + + public function testTextChinese() + { + // Switch to chinese print mode, GBK output, switch back to alphanumeric. + $this -> printer -> textChinese("示例文本打印机!\n"); + $this -> checkOutput("\x1b@\x1c&\xca\xbe\xc0\xfd\xce\xc4\xb1\xbe\xb4\xf2\xd3\xa1\xbb\xfa!\x0a\x1c."); + } + + public function testTextRaw() + { + // Under raw output, the raw bytes are sent to the printer, so typing a UTF-8 euro literally causes \xE2 \x82 \xAC to be sent. + // Under text(), this would cause a code-page change (to a page that contains a Euro symbol), and single byte. + $this -> printer -> textRaw("€\n"); + $this -> checkOutput("\x1b@\xe2\x82\xac\x0a"); } - public function testFeedNonInteger() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feed("ab"); + public function testTextString() + { + $this -> printer -> text("String"); + $this -> printer -> text(123); + $this -> printer -> text(); + $this -> printer -> text(null); + $this -> printer -> text(1.2); + $this -> printer -> text(new FooBar("FooBar")); + $this -> checkOutput("\x1b@String1231.2FooBar"); } - public function testFeedTooLarge() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feed(256); - } - - /* Print mode */ - public function testSelectPrintModeDefault() { - $this -> printer -> selectPrintMode(); - $this -> checkOutput("\x1b@\x1b!\x00"); + public function testTextObject() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> text(new DateTime()); } - public function testSelectPrintModeAcceptedValues() { - /* This iterates over a bunch of numbers, figures out which + public function testFeedDefault() + { + $this -> printer -> feed(); + $this -> checkOutput("\x1b@\x0a"); + } + + public function testFeed3Lines() + { + $this -> printer -> feed(3); + $this -> checkOutput("\x1b@\x1bd\x03"); + } + + public function testFeedZero() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> feed(0); + } + + public function testFeedNonInteger() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> feed("ab"); + } + + public function testFeedTooLarge() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> feed(256); + } + + /* Print mode */ + public function testSelectPrintModeDefault() + { + $this -> printer -> selectPrintMode(); + $this -> checkOutput("\x1b@\x1b!\x00"); + } + + public function testSelectPrintModeAcceptedValues() + { + /* This iterates over a bunch of numbers, figures out which ones contain invalid flags, and checks that the driver rejects those, but accepts the good inputs */ - - for($i = -1; $i <= 256; $i++) { - $invalid = ($i < 0) || ($i > 255) || (($i & 2) == 2) || (($i & 4) == 4) || (($i & 64) == 64); - $failed = false; - try { - $this -> printer -> selectPrintMode($i); - } catch(Exception $e) { - $failed = true; - } - $this -> assertEquals($failed, $invalid); - } + + for ($i = -1; $i <= 256; $i++) { + $invalid = ($i < 0) || ($i > 255) || (($i & 2) == 2) || (($i & 4) == 4) || (($i & 64) == 64); + $failed = false; + try { + $this -> printer -> selectPrintMode($i); + } catch (Exception $e) { + $failed = true; + } + $this -> assertEquals($failed, $invalid); + } } - /* Underline */ - public function testSetUnderlineDefault() { - $this -> printer -> setUnderline(); - $this -> checkOutput("\x1b@\x1b-\x01"); + /* Underline */ + public function testSetUnderlineDefault() + { + $this -> printer -> setUnderline(); + $this -> checkOutput("\x1b@\x1b-\x01"); } - public function testSetUnderlineOff() { - $this -> printer -> setUnderline(Escpos::UNDERLINE_NONE); - $this -> checkOutput("\x1b@\x1b-\x00"); + public function testSetUnderlineOff() + { + $this -> printer -> setUnderline(Printer::UNDERLINE_NONE); + $this -> checkOutput("\x1b@\x1b-\x00"); } - public function testSetUnderlineOn() { - $this -> printer -> setUnderline(Escpos::UNDERLINE_SINGLE); - $this -> checkOutput("\x1b@\x1b-\x01"); + public function testSetUnderlineOn() + { + $this -> printer -> setUnderline(Printer::UNDERLINE_SINGLE); + $this -> checkOutput("\x1b@\x1b-\x01"); } - public function testSetUnderlineDbl() { - $this -> printer -> setUnderline(Escpos::UNDERLINE_DOUBLE); - $this -> checkOutput("\x1b@\x1b-\x02"); + public function testSetUnderlineDbl() + { + $this -> printer -> setUnderline(Printer::UNDERLINE_DOUBLE); + $this -> checkOutput("\x1b@\x1b-\x02"); } - public function testSetUnderlineAcceptedValues() { - $this -> printer -> setUnderline(0); - $this -> printer -> setUnderline(1); - $this -> printer -> setUnderline(2); - /* These map to 0 & 1 for interchangeability with setEmphasis */ - $this -> printer -> setUnderline(true); - $this -> printer -> setUnderline(false); - $this -> checkOutput("\x1b@\x1b-\x00\x1b-\x01\x1b-\x02\x1b-\x01\x1b-\x00"); - } - - public function testSetUnderlineTooLarge() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setUnderline(3); - } - - public function testSetUnderlineNegative() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setUnderline(-1); - } - - public function testSetUnderlineNonInteger() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setUnderline("Hello"); - } - - /* Emphasis */ - public function testSetEmphasisDefault() { - $this -> printer -> setEmphasis(); - $this -> checkOutput("\x1b@\x1bE\x01"); + public function testSetUnderlineAcceptedValues() + { + $this -> printer -> setUnderline(0); + $this -> printer -> setUnderline(1); + $this -> printer -> setUnderline(2); + /* These map to 0 & 1 for interchangeability with setEmphasis */ + $this -> printer -> setUnderline(true); + $this -> printer -> setUnderline(false); + $this -> checkOutput("\x1b@\x1b-\x00\x1b-\x01\x1b-\x02\x1b-\x01\x1b-\x00"); } - public function testSetEmphasisOn() { - $this -> printer -> setEmphasis(true); - $this -> checkOutput("\x1b@\x1bE\x01"); + public function testSetUnderlineTooLarge() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setUnderline(3); } - public function testSetEmphasisOff() { - $this -> printer -> setEmphasis(false); - $this -> checkOutput("\x1b@\x1bE\x00"); + public function testSetUnderlineNegative() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setUnderline(-1); } - public function testSetEmphasisNonBoolean() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setEmphasis(7); - } - - /* Double strike */ - public function testSetDoubleStrikeDefault() { - $this -> printer -> setDoubleStrike(); - $this -> checkOutput("\x1b@\x1bG\x01"); + public function testSetUnderlineNonInteger() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setUnderline("Hello"); } - public function testSetDoubleStrikeOn() { - $this -> printer -> setDoubleStrike(true); - $this -> checkOutput("\x1b@\x1bG\x01"); + /* Emphasis */ + public function testSetEmphasisDefault() + { + $this -> printer -> setEmphasis(); + $this -> checkOutput("\x1b@\x1bE\x01"); } - public function testSetDoubleStrikeOff() { - $this -> printer -> setDoubleStrike(false); - $this -> checkOutput("\x1b@\x1bG\x00"); + public function testSetEmphasisOn() + { + $this -> printer -> setEmphasis(true); + $this -> checkOutput("\x1b@\x1bE\x01"); } - public function testSetDoubleStrikeNonBoolean() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setDoubleStrike(4); - } - - /* Font */ - public function testSetFontDefault() { - $this -> printer -> setFont(); - $this -> checkOutput("\x1b@\x1bM\x00"); - } - - public function testSetFontAcceptedValues() { - $this -> printer -> setFont(Escpos::FONT_A); - $this -> printer -> setFont(Escpos::FONT_B); - $this -> printer -> setFont(Escpos::FONT_C); - $this -> checkOutput("\x1b@\x1bM\x00\x1bM\x01\x1bM\x02"); - } - - public function testSetFontNegative() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setFont(-1); - } - - - public function testSetFontTooLarge() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setFont(3); - } - - public function testSetFontNonInteger() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setFont('hello'); - } - - /* Justification */ - public function testSetJustificationDefault() { - $this -> printer -> setJustification(); - $this -> checkOutput("\x1b@\x1ba\x00"); - } - - public function testSetJustificationLeft() { - $this -> printer -> setJustification(Escpos::JUSTIFY_LEFT); - $this -> checkOutput("\x1b@\x1ba\x00"); - } - - public function testSetJustificationRight() { - $this -> printer -> setJustification(Escpos::JUSTIFY_RIGHT); - $this -> checkOutput("\x1b@\x1ba\x02"); - } - - public function testSetJustificationCenter() { - $this -> printer -> setJustification(Escpos::JUSTIFY_CENTER); - $this -> checkOutput("\x1b@\x1ba\x01"); - } - - public function testSetJustificationNegative() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setJustification(-1); - } - - - public function testSetJustificationTooLarge() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setFont(3); - } - - public function testSetJustificationNonInteger() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setJustification('hello'); - } - - /* Reverse feed */ - public function testFeedReverseDefault() { - $this -> printer -> feedReverse(); - $this -> checkOutput("\x1b@\x1be\x01"); - } - - public function testFeedReverse3() { - $this -> printer -> feedReverse(3); - $this -> checkOutput("\x1b@\x1be\x03"); - } - - public function testFeedReverseNegative() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feedReverse(-1); - } - - public function testFeedReverseTooLarge() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feedReverse(256); - } - - public function testFeedReverseNonInteger() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feedReverse('hello'); - } - - /* Cut */ - public function testCutDefault() { - // TODO check what the accepted range of values should be for $line - // cut($mode = self::CUT_FULL, $lines = 3) - $this -> printer -> cut(); - $this -> checkOutput("\x1b@\x1dVA\x03"); - } - - /* Set barcode height */ - public function testSetBarcodeHeightDefault() { - $this -> printer -> setBarcodeHeight(); - $this -> checkOutput("\x1b@\x1dh\x08"); - } - - public function testBarcodeHeight10() { - $this -> printer -> setBarcodeHeight(10); - $this -> checkOutput("\x1b@\x1dh\x0a"); - } - - public function testSetBarcodeHeightNegative() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeHeight(-1); - } - - public function testSetBarcodeHeightTooLarge() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeHeight(256); - } - - public function tesSetBarcodeHeightNonInteger() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeHeight('hello'); - } - - /* Barcode text position */ - public function testSetBarcodeTextPositionDefault() { - $this -> printer -> setBarcodeTextPosition(); - $this -> checkOutput("\x1b@\x1dH\x00"); - } - - public function testSetBarcodeTextPositionBelow() { - $this -> printer -> setBarcodeTextPosition(Escpos::BARCODE_TEXT_BELOW); - $this -> checkOutput("\x1b@\x1dH\x02"); - } - - public function testSetBarcodeTextPositionBoth() { - $this -> printer -> setBarcodeTextPosition(Escpos::BARCODE_TEXT_BELOW | Escpos::BARCODE_TEXT_ABOVE); - $this -> checkOutput("\x1b@\x1dH\x03"); - } - - public function testSetBarcodeTextPositionNegative() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeTextPosition(-1); - } - - public function testSetBarcodeTextPositionTooLarge() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeTextPosition(4); - } - - public function tesSetBarcodeTextPositionNonInteger() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeTextPosition('hello'); - } - - /* Barcode - UPC-A */ - public function testBarcodeUpcaNumeric11Char() { - $this -> printer -> barcode("01234567890", Escpos::BARCODE_UPCA); - $this -> checkOutput("\x1b@\x1dkA\x0b01234567890"); - } - - public function testBarcodeUpcaNumeric12Char() { - $this -> printer -> barcode("012345678901", Escpos::BARCODE_UPCA); - $this -> checkOutput("\x1b@\x1dkA\x0c012345678901"); - } - - public function testBarcodeUpcaNumeric13Char() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("0123456789012", Escpos::BARCODE_UPCA); - } - - public function testBarcodeUpcaNonNumeric12Char() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A12345678901", Escpos::BARCODE_UPCA); - } - - /* Barcode - UPC-E */ - public function testBarcodeUpceNumeric6Char() { - $this -> printer -> barcode("123456", Escpos::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x06123456"); - } - - public function testBarcodeUpceNumeric7Char() { - $this -> printer -> barcode("0123456", Escpos::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x070123456"); - } - - public function testBarcodeUpceNumeric8Char() { - $this -> printer -> barcode("01234567", Escpos::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x0801234567"); - } - - public function testBarcodeUpceNumeric11Char() { - $this -> printer -> barcode("01234567890", Escpos::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x0b01234567890"); - } - - public function testBarcodeUpceNumeric12Char() { - $this -> printer -> barcode("012345678901", Escpos::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x0c012345678901"); - } - - public function testBarcodeUpceNumeric9Char() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("012345678", Escpos::BARCODE_UPCE); - } - - public function testBarcodeUpceNonNumeric12Char() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A12345678901", Escpos::BARCODE_UPCE); - } - - /* Barcode - JAN13 */ - public function testBarcodeJan13Numeric12Char() { - $this -> printer -> barcode("012345678901", Escpos::BARCODE_JAN13); - $this -> checkOutput("\x1b@\x1dkC\x0c012345678901"); - } - - public function testBarcodeJan13Numeric13Char() { - $this -> printer -> barcode("0123456789012", Escpos::BARCODE_JAN13); - $this -> checkOutput("\x1b@\x1dkC\x0d0123456789012"); - } - - public function testBarcodeJan13Numeric11Char() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("01234567890", Escpos::BARCODE_JAN13); - } - - public function testBarcodeJan13NonNumeric13Char() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A123456789012", Escpos::BARCODE_JAN13); - } - - /* Barcode - JAN8 */ - public function testBarcodeJan8Numeric7Char() { - $this -> printer -> barcode("0123456", Escpos::BARCODE_JAN8); - $this -> checkOutput("\x1b@\x1dkD\x070123456"); - } - - public function testBarcodeJan8Numeric8Char() { - $this -> printer -> barcode("01234567", Escpos::BARCODE_JAN8); - $this -> checkOutput("\x1b@\x1dkD\x0801234567"); - } - - public function testBarcodeJan8Numeric9Char() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("012345678", Escpos::BARCODE_JAN8); - } - - public function testBarcodeJan8NonNumeric8Char() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A1234567", Escpos::BARCODE_JAN8); - } - - /* Barcode - Code39 */ - public function testBarcodeCode39AsDefault() { - $this -> printer -> barcode("1234"); - $this -> checkOutput("\x1b@\x1dkE\x041234"); - } - - public function testBarcodeCode39Text() { - $this -> printer -> barcode("ABC 012", Escpos::BARCODE_CODE39); - $this -> checkOutput("\x1b@\x1dkE\x07ABC 012"); - } - - public function testBarcodeCode39SpecialChars() { - $this -> printer -> barcode("$%+-./", Escpos::BARCODE_CODE39); - $this -> checkOutput("\x1b@\x1dkE\x06$%+-./"); - } - - public function testBarcodeCode39Asterisks() { - $this -> printer -> barcode("*TEXT*", Escpos::BARCODE_CODE39); - $this -> checkOutput("\x1b@\x1dkE\x06*TEXT*"); - } - - public function testBarcodeCode39AsterisksUnmatched() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("*TEXT", Escpos::BARCODE_CODE39); - } - - public function testBarcodeCode39AsteriskInText() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("12*34", Escpos::BARCODE_CODE39); - } - - public function testBarcodeCode39Lowercase() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("abcd", Escpos::BARCODE_CODE39); - } - - public function testBarcodeCode39Empty() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("**", Escpos::BARCODE_CODE39); - } - - /* Barcode - ITF */ - public function testBarcodeItfNumericEven() { - $this -> printer -> barcode("1234", Escpos::BARCODE_ITF); - $this -> checkOutput("\x1b@\x1dkF\x041234"); - } - - public function testBarcodeItfNumericOdd() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("123", Escpos::BARCODE_ITF); - } - - public function testBarcodeItfNonNumericEven() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A234", Escpos::BARCODE_ITF); - } - - /* Barcode - Codabar */ - public function testBarcodeCodabarNumeric() { - $this -> printer -> barcode("A012345A", Escpos::BARCODE_CODABAR); - $this -> checkOutput("\x1b@\x1dkG\x08A012345A"); - } - - public function testBarcodeCodabarSpecialChars() { - $this -> printer -> barcode("A012$+-./:A", Escpos::BARCODE_CODABAR); - $this -> checkOutput("\x1b@\x1dkG\x0bA012$+-./:A"); - } - - public function testBarcodeCodabarNotWrapped() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("012345", Escpos::BARCODE_CODABAR); - } - - public function testBarcodeCodabarStartStopWrongPlace() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("012A45", Escpos::BARCODE_CODABAR); - } - - /* Barcode - Code93 */ - public function testBarcodeCode93Valid() { - $this -> printer -> barcode("012abcd", Escpos::BARCODE_CODE93); - $this -> checkOutput("\x1b@\x1dkH\x07012abcd"); - } - - public function testBarcodeCode93Empty() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("", Escpos::BARCODE_CODE93); - } - - /* Barcode - Code128 */ - public function testBarcodeCode128ValidA() { - $this -> printer -> barcode("{A" . "012ABCD", Escpos::BARCODE_CODE128); - $this -> checkOutput("\x1b@\x1dkI\x09{A012ABCD"); - } - - public function testBarcodeCode128ValidB() { - $this -> printer -> barcode("{B" . "012ABCDabcd", Escpos::BARCODE_CODE128); - $this -> checkOutput("\x1b@\x1dkI\x0d{B012ABCDabcd"); - } - - public function testBarcodeCode128ValidC() { - $this -> printer -> barcode("{C" . chr ( 21 ) . chr ( 32 ) . chr ( 43 ), Escpos::BARCODE_CODE128); - $this -> checkOutput("\x1b@\x1dkI\x05{C\x15 +"); - } - - public function testBarcodeCode128NoCodeSet() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("ABCD", Escpos::BARCODE_CODE128); - } - - /* Pulse */ - function testPulseDefault() { - $this -> printer -> pulse(); - $this -> checkOutput("\x1b@\x1bp0 printer -> pulse(1); - $this -> checkOutput("\x1b@\x1bp1 printer -> pulse(0, 2, 2); - $this -> checkOutput("\x1b@\x1bp0\x01\x01"); - } - - function testPulseOddMs() { - $this -> printer -> pulse(0, 3, 3); // Should be rounded down and give same output - $this -> checkOutput("\x1b@\x1bp0\x01\x01"); - } - - function testPulseTooHigh() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> pulse(0, 512, 2); - } - - function testPulseTooLow() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> pulse(0, 0, 2); - } - - function testPulseNotANumber() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> pulse("fish"); - } - - /* Set reverse */ - public function testSetReverseColorsDefault() { - $this -> printer -> setReverseColors(); - $this -> checkOutput("\x1b@\x1dB\x01"); + public function testSetEmphasisOff() + { + $this -> printer -> setEmphasis(false); + $this -> checkOutput("\x1b@\x1bE\x00"); } - public function testSetReverseColorsOn() { - $this -> printer -> setReverseColors(true); - $this -> checkOutput("\x1b@\x1dB\x01"); + public function testSetEmphasisNonBoolean() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setEmphasis(7); } - public function testSetReverseColorsOff() { - $this -> printer -> setReverseColors(false); - $this -> checkOutput("\x1b@\x1dB\x00"); + /* Double strike */ + public function testSetDoubleStrikeDefault() + { + $this -> printer -> setDoubleStrike(); + $this -> checkOutput("\x1b@\x1bG\x01"); } - public function testSetReverseColorsNonBoolean() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setReverseColors(7); - } + public function testSetDoubleStrikeOn() + { + $this -> printer -> setDoubleStrike(true); + $this -> checkOutput("\x1b@\x1bG\x01"); + } - /* Bit image print */ - public function testBitImageBlack() { - $this -> requireGraphicsLibrary(); - $img = new EscposImage(dirname(__FILE__)."/resources/canvas_black.png"); - $this -> printer -> bitImage($img); - $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x01\x00\x80"); - } + public function testSetDoubleStrikeOff() + { + $this -> printer -> setDoubleStrike(false); + $this -> checkOutput("\x1b@\x1bG\x00"); + } - public function testBitImageWhite() { - $this -> requireGraphicsLibrary(); - $img = new EscposImage(dirname(__FILE__)."/resources/canvas_white.png"); - $this -> printer -> bitImage($img); - $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x01\x00\x00"); - } - - public function testBitImageBoth() { - $this -> requireGraphicsLibrary(); - $img = new EscposImage(dirname(__FILE__)."/resources/black_white.png"); - $this -> printer -> bitImage($img); - $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x02\x00\xc0\x00"); - } - - public function testBitImageTransparent() { - $this -> requireGraphicsLibrary(); - $img = new EscposImage(dirname(__FILE__)."/resources/black_transparent.png"); - $this -> printer -> bitImage($img); - $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x02\x00\xc0\x00"); - } - - /* Graphics print */ - public function testGraphicsWhite() { - $this -> requireGraphicsLibrary(); - $img = new EscposImage(dirname(__FILE__)."/resources/canvas_white.png"); - $this -> printer -> graphics($img); - $this -> checkOutput("\x1b@\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x00\x1d(L\x02\x0002"); - } - - public function testGraphicsBlack() { - $this -> requireGraphicsLibrary(); - $img = new EscposImage(dirname(__FILE__)."/resources/canvas_black.png"); - $this -> printer -> graphics($img); - $this -> checkOutput("\x1b@\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x80\x1d(L\x02\x0002"); - } - - public function testGraphicsBoth() { - $this -> requireGraphicsLibrary(); - $img = new EscposImage(dirname(__FILE__)."/resources/black_white.png"); - $this -> printer -> graphics($img); - $this -> checkOutput("\x1b@\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002"); - } - - public function testGraphicsTransparent() { - $this -> requireGraphicsLibrary(); - $img = new EscposImage(dirname(__FILE__)."/resources/black_transparent.png"); - $this -> printer -> graphics($img); - $this -> checkOutput("\x1b@\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002"); - } + public function testSetDoubleStrikeNonBoolean() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setDoubleStrike(4); + } - /* QR code */ - public function testQRCodeDefaults() { - // Test will fail if default values change - $this -> printer -> qrCode("1234"); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } - - public function testQRCodeDefaultsAreCorrect() { - // Below tests assume that defaults are as written here (output string should be same as above) - $this -> printer -> qrCode("1234", Escpos::QR_ECLEVEL_L, 3, Escpos::QR_MODEL_2); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } - - public function testQRCodeEmpty() { - $this -> printer -> qrCode(''); - $this -> checkOutput("\x1b@"); // No commands actually sent - } - - public function testQRCodeChangeEC() { - $this -> printer -> qrCode("1234", Escpos::QR_ECLEVEL_H); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E3\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } - - public function testQRCodeChangeSize() { - $this -> printer -> qrCode("1234", Escpos::QR_ECLEVEL_L, 7); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x07\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } - - public function testQRCodeChangeModel() { - $this -> printer -> qrCode("1234", Escpos::QR_ECLEVEL_L, 3, Escpos::QR_MODEL_1); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A1\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } + /* Font */ + public function testSetFontDefault() + { + $this -> printer -> setFont(); + $this -> checkOutput("\x1b@\x1bM\x00"); + } - /* Feed form - Required on page-mode only printers */ - public function testFeedForm() { - $this -> printer -> feedForm(); - $this -> checkOutput("\x1b@\x0c"); - } - - /* Get status */ - public function testGetStatus() { - $this -> markTestIncomplete("Status check test code not implemented."); - // TODO some unit testing here on statuses - // $a = $this -> printer -> getPrinterStatus(Escpos::STATUS_PRINTER); - } + public function testSetFontAcceptedValues() + { + $this -> printer -> setFont(Printer::FONT_A); + $this -> printer -> setFont(Printer::FONT_B); + $this -> printer -> setFont(Printer::FONT_C); + $this -> checkOutput("\x1b@\x1bM\x00\x1bM\x01\x1bM\x02"); + } - /* Set text size */ - public function testSetTextSizeNormal() { - $this -> printer -> setTextSize(1, 1); - $this -> checkOutput("\x1b@\x1d!\x00"); - } + public function testSetFontNegative() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setFont(-1); + } - public function testSetTextSizeWide() { - $this -> printer -> setTextSize(4, 1); - $this -> checkOutput("\x1b@\x1d!0"); - } - public function testSetTextSizeNarrow() { - $this -> printer -> setTextSize(1, 4); - $this -> checkOutput("\x1b@\x1d!\x03"); - } + public function testSetFontTooLarge() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setFont(3); + } - public function testSetTextSizeLarge() { - $this -> printer -> setTextSize(4, 4); - $this -> checkOutput("\x1b@\x1d!3"); - } + public function testSetFontNonInteger() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setFont('hello'); + } - public function testSetTextSizeInvalid() { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setTextSize(0, 9); - } + /* Justification */ + public function testSetJustificationDefault() + { + $this -> printer -> setJustification(); + $this -> checkOutput("\x1b@\x1ba\x00"); + } + + public function testSetJustificationLeft() + { + $this -> printer -> setJustification(Printer::JUSTIFY_LEFT); + $this -> checkOutput("\x1b@\x1ba\x00"); + } + + public function testSetJustificationRight() + { + $this -> printer -> setJustification(Printer::JUSTIFY_RIGHT); + $this -> checkOutput("\x1b@\x1ba\x02"); + } + + public function testSetJustificationCenter() + { + $this -> printer -> setJustification(Printer::JUSTIFY_CENTER); + $this -> checkOutput("\x1b@\x1ba\x01"); + } + + public function testSetJustificationNegative() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setJustification(-1); + } + + + public function testSetJustificationTooLarge() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setFont(3); + } + + public function testSetJustificationNonInteger() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setJustification('hello'); + } + + /* Reverse feed */ + public function testFeedReverseDefault() + { + $this -> printer -> feedReverse(); + $this -> checkOutput("\x1b@\x1be\x01"); + } + + public function testFeedReverse3() + { + $this -> printer -> feedReverse(3); + $this -> checkOutput("\x1b@\x1be\x03"); + } + + public function testFeedReverseNegative() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> feedReverse(-1); + } + + public function testFeedReverseTooLarge() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> feedReverse(256); + } + + public function testFeedReverseNonInteger() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> feedReverse('hello'); + } + + /* Cut */ + public function testCutDefault() + { + // TODO check what the accepted range of values should be for $line + // cut($mode = self::CUT_FULL, $lines = 3) + $this -> printer -> cut(); + $this -> checkOutput("\x1b@\x1dVA\x03"); + } + + /* Set barcode height */ + public function testSetBarcodeHeightDefault() + { + $this -> printer -> setBarcodeHeight(); + $this -> checkOutput("\x1b@\x1dh\x08"); + } + + public function testBarcodeHeight10() + { + $this -> printer -> setBarcodeHeight(10); + $this -> checkOutput("\x1b@\x1dh\x0a"); + } + + public function testSetBarcodeHeightNegative() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setBarcodeHeight(-1); + } + + public function testSetBarcodeHeightTooLarge() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setBarcodeHeight(256); + } + + public function testSetBarcodeHeightNonInteger() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setBarcodeHeight('hello'); + } + + /* Set barcode width */ + public function testSetBarcodeWidthDefault() + { + $this -> printer -> setBarcodeWidth(); + $this -> checkOutput("\x1b@\x1dw\x03"); + } + + public function testBarcodeWidth1() + { + $this -> printer -> setBarcodeWidth(1); + $this -> checkOutput("\x1b@\x1dw\x01"); + } + + public function testSetBarcodeWidthNegative() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setBarcodeWidth(-1); + } + + public function testSetBarcodeWidthTooLarge() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setBarcodeWidth(256); + } + + public function testSetBarcodeWidthNonInteger() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setBarcodeWidth('hello'); + } + + /* Barcode text position */ + public function testSetBarcodeTextPositionDefault() + { + $this -> printer -> setBarcodeTextPosition(); + $this -> checkOutput("\x1b@\x1dH\x00"); + } + + public function testSetBarcodeTextPositionBelow() + { + $this -> printer -> setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW); + $this -> checkOutput("\x1b@\x1dH\x02"); + } + + public function testSetBarcodeTextPositionBoth() + { + $this -> printer -> setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW | Printer::BARCODE_TEXT_ABOVE); + $this -> checkOutput("\x1b@\x1dH\x03"); + } + + public function testSetBarcodeTextPositionNegative() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setBarcodeTextPosition(-1); + } + + public function testSetBarcodeTextPositionTooLarge() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setBarcodeTextPosition(4); + } + + public function tesSetBarcodeTextPositionNonInteger() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setBarcodeTextPosition('hello'); + } + + /* Barcode - UPC-A */ + public function testBarcodeUpcaNumeric11Char() + { + $this -> printer -> barcode("01234567890", Printer::BARCODE_UPCA); + $this -> checkOutput("\x1b@\x1dkA\x0b01234567890"); + } + + public function testBarcodeUpcaNumeric12Char() + { + $this -> printer -> barcode("012345678901", Printer::BARCODE_UPCA); + $this -> checkOutput("\x1b@\x1dkA\x0c012345678901"); + } + + public function testBarcodeUpcaNumeric13Char() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("0123456789012", Printer::BARCODE_UPCA); + } + + public function testBarcodeUpcaNonNumeric12Char() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("A12345678901", Printer::BARCODE_UPCA); + } + + /* Barcode - UPC-E */ + public function testBarcodeUpceNumeric6Char() + { + $this -> printer -> barcode("123456", Printer::BARCODE_UPCE); + $this -> checkOutput("\x1b@\x1dkB\x06123456"); + } + + public function testBarcodeUpceNumeric7Char() + { + $this -> printer -> barcode("0123456", Printer::BARCODE_UPCE); + $this -> checkOutput("\x1b@\x1dkB\x070123456"); + } + + public function testBarcodeUpceNumeric8Char() + { + $this -> printer -> barcode("01234567", Printer::BARCODE_UPCE); + $this -> checkOutput("\x1b@\x1dkB\x0801234567"); + } + + public function testBarcodeUpceNumeric11Char() + { + $this -> printer -> barcode("01234567890", Printer::BARCODE_UPCE); + $this -> checkOutput("\x1b@\x1dkB\x0b01234567890"); + } + + public function testBarcodeUpceNumeric12Char() + { + $this -> printer -> barcode("012345678901", Printer::BARCODE_UPCE); + $this -> checkOutput("\x1b@\x1dkB\x0c012345678901"); + } + + public function testBarcodeUpceNumeric9Char() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("012345678", Printer::BARCODE_UPCE); + } + + public function testBarcodeUpceNonNumeric12Char() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("A12345678901", Printer::BARCODE_UPCE); + } + + /* Barcode - JAN13 */ + public function testBarcodeJan13Numeric12Char() + { + $this -> printer -> barcode("012345678901", Printer::BARCODE_JAN13); + $this -> checkOutput("\x1b@\x1dkC\x0c012345678901"); + } + + public function testBarcodeJan13Numeric13Char() + { + $this -> printer -> barcode("0123456789012", Printer::BARCODE_JAN13); + $this -> checkOutput("\x1b@\x1dkC\x0d0123456789012"); + } + + public function testBarcodeJan13Numeric11Char() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("01234567890", Printer::BARCODE_JAN13); + } + + public function testBarcodeJan13NonNumeric13Char() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("A123456789012", Printer::BARCODE_JAN13); + } + + /* Barcode - JAN8 */ + public function testBarcodeJan8Numeric7Char() + { + $this -> printer -> barcode("0123456", Printer::BARCODE_JAN8); + $this -> checkOutput("\x1b@\x1dkD\x070123456"); + } + + public function testBarcodeJan8Numeric8Char() + { + $this -> printer -> barcode("01234567", Printer::BARCODE_JAN8); + $this -> checkOutput("\x1b@\x1dkD\x0801234567"); + } + + public function testBarcodeJan8Numeric9Char() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("012345678", Printer::BARCODE_JAN8); + } + + public function testBarcodeJan8NonNumeric8Char() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("A1234567", Printer::BARCODE_JAN8); + } + + /* Barcode - Code39 */ + public function testBarcodeCode39AsDefault() + { + $this -> printer -> barcode("1234"); + $this -> checkOutput("\x1b@\x1dkE\x041234"); + } + + public function testBarcodeCode39Text() + { + $this -> printer -> barcode("ABC 012", Printer::BARCODE_CODE39); + $this -> checkOutput("\x1b@\x1dkE\x07ABC 012"); + } + + public function testBarcodeCode39SpecialChars() + { + $this -> printer -> barcode("$%+-./", Printer::BARCODE_CODE39); + $this -> checkOutput("\x1b@\x1dkE\x06$%+-./"); + } + + public function testBarcodeCode39Asterisks() + { + $this -> printer -> barcode("*TEXT*", Printer::BARCODE_CODE39); + $this -> checkOutput("\x1b@\x1dkE\x06*TEXT*"); + } + + public function testBarcodeCode39AsterisksUnmatched() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("*TEXT", Printer::BARCODE_CODE39); + } + + public function testBarcodeCode39AsteriskInText() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("12*34", Printer::BARCODE_CODE39); + } + + public function testBarcodeCode39Lowercase() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("abcd", Printer::BARCODE_CODE39); + } + + public function testBarcodeCode39Empty() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("**", Printer::BARCODE_CODE39); + } + + /* Barcode - ITF */ + public function testBarcodeItfNumericEven() + { + $this -> printer -> barcode("1234", Printer::BARCODE_ITF); + $this -> checkOutput("\x1b@\x1dkF\x041234"); + } + + public function testBarcodeItfNumericOdd() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("123", Printer::BARCODE_ITF); + } + + public function testBarcodeItfNonNumericEven() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("A234", Printer::BARCODE_ITF); + } + + /* Barcode - Codabar */ + public function testBarcodeCodabarNumeric() + { + $this -> printer -> barcode("A012345A", Printer::BARCODE_CODABAR); + $this -> checkOutput("\x1b@\x1dkG\x08A012345A"); + } + + public function testBarcodeCodabarSpecialChars() + { + $this -> printer -> barcode("A012$+-./:A", Printer::BARCODE_CODABAR); + $this -> checkOutput("\x1b@\x1dkG\x0bA012$+-./:A"); + } + + public function testBarcodeCodabarNotWrapped() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("012345", Printer::BARCODE_CODABAR); + } + + public function testBarcodeCodabarStartStopWrongPlace() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("012A45", Printer::BARCODE_CODABAR); + } + + /* Barcode - Code93 */ + public function testBarcodeCode93Valid() + { + $this -> printer -> barcode("012abcd", Printer::BARCODE_CODE93); + $this -> checkOutput("\x1b@\x1dkH\x07012abcd"); + } + + public function testBarcodeCode93Empty() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("", Printer::BARCODE_CODE93); + } + + /* Barcode - Code128 */ + public function testBarcodeCode128ValidA() + { + $this -> printer -> barcode("{A" . "012ABCD", Printer::BARCODE_CODE128); + $this -> checkOutput("\x1b@\x1dkI\x09{A012ABCD"); + } + + public function testBarcodeCode128ValidB() + { + $this -> printer -> barcode("{B" . "012ABCDabcd", Printer::BARCODE_CODE128); + $this -> checkOutput("\x1b@\x1dkI\x0d{B012ABCDabcd"); + } + + public function testBarcodeCode128ValidC() + { + $this -> printer -> barcode("{C" . chr(21) . chr(32) . chr(43), Printer::BARCODE_CODE128); + $this -> checkOutput("\x1b@\x1dkI\x05{C\x15 +"); + } + + public function testBarcodeCode128NoCodeSet() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> barcode("ABCD", Printer::BARCODE_CODE128); + } + + /* Pulse */ + function testPulseDefault() + { + $this -> printer -> pulse(); + $this -> checkOutput("\x1b@\x1bp0 printer -> pulse(1); + $this -> checkOutput("\x1b@\x1bp1 printer -> pulse(0, 2, 2); + $this -> checkOutput("\x1b@\x1bp0\x01\x01"); + } + + function testPulseOddMs() + { + $this -> printer -> pulse(0, 3, 3); // Should be rounded down and give same output + $this -> checkOutput("\x1b@\x1bp0\x01\x01"); + } + + function testPulseTooHigh() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> pulse(0, 512, 2); + } + + function testPulseTooLow() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> pulse(0, 0, 2); + } + + function testPulseNotANumber() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> pulse("fish"); + } + + /* Set reverse */ + public function testSetReverseColorsDefault() + { + $this -> printer -> setReverseColors(); + $this -> checkOutput("\x1b@\x1dB\x01"); + } + + public function testSetReverseColorsOn() + { + $this -> printer -> setReverseColors(true); + $this -> checkOutput("\x1b@\x1dB\x01"); + } + + public function testSetReverseColorsOff() + { + $this -> printer -> setReverseColors(false); + $this -> checkOutput("\x1b@\x1dB\x00"); + } + + public function testSetReverseColorsNonBoolean() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setReverseColors(7); + } + + /* Bit image print */ + public function testBitImageBlack() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_black.png"); + $this -> printer -> bitImage($img); + $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x01\x00\x80"); + } + + public function testBitImageWhite() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_white.png"); + $this -> printer -> bitImage($img); + $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x01\x00\x00"); + } + + public function testBitImageBoth() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/black_white.png"); + $this -> printer -> bitImage($img); + $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x02\x00\xc0\x00"); + } + + public function testBitImageTransparent() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/black_transparent.png"); + $this -> printer -> bitImage($img); + $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x02\x00\xc0\x00"); + } + + /* Bit image column format */ + public function testBitImageColumnFormatBlack() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_black.png"); + $this -> printer -> bitImageColumnFormat($img); + $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x01\x00\x80\x00\x00\x0a\x1b2"); + } + + public function testBitImageColumnFormatWhite() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_white.png"); + $this -> printer -> bitImageColumnFormat($img); + $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x01\x00\x00\x00\x00\x0a\x1b2"); + } + + public function testBitImageColumnFormatBoth() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/black_white.png"); + $this -> printer -> bitImageColumnFormat($img); + $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x02\x00\x80\x00\x00\x80\x00\x00\x0a\x1b2"); + } + + public function testBitImageColumnFormatTransparent() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/black_transparent.png"); + $this -> printer -> bitImageColumnFormat($img); + $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x02\x00\x80\x00\x00\x80\x00\x00\x0a\x1b2"); + } + + /* Graphics print */ + public function testGraphicsWhite() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_white.png"); + $this -> printer -> graphics($img); + $this -> checkOutput("\x1b@\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x00\x1d(L\x02\x0002"); + } + + public function testGraphicsBlack() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_black.png"); + $this -> printer -> graphics($img); + $this -> checkOutput("\x1b@\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x80\x1d(L\x02\x0002"); + } + + public function testGraphicsBoth() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/black_white.png"); + $this -> printer -> graphics($img); + $this -> checkOutput("\x1b@\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002"); + } + + public function testGraphicsTransparent() + { + $this -> requireGraphicsLibrary(); + $img = EscposImage::load(dirname(__FILE__)."/resources/black_transparent.png"); + $this -> printer -> graphics($img); + $this -> checkOutput("\x1b@\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002"); + } + + /* PDF417 code */ + public function testPdf417CodeDefaults() + { + $this -> printer -> pdf417Code("1234"); + $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x00\x1d(k\x03\x000A\x00\x1d(k\x03\x000C\x03\x1d(k\x03\x000D\x03\x1d(k\x04\x000E1\x01\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0"); + } + + public function testPdf417CodeEmpty() + { + $this -> printer -> pdf417Code(''); + $this -> checkOutput("\x1b@"); // No commands actually sent + } + + public function testPdf417CodeNotSupported() + { + $this -> setExpectedException('Exception'); + $profile = SimpleCapabilityProfile::getInstance(); + $this -> printer = new Printer($this -> outputConnector, $profile); + $this -> printer -> pdf417Code("1234"); + } + + public function testPdf417CodeChangeGeometry() + { + // 7-dot wide, 4-times height, 4 data columns + $this -> printer -> pdf417Code("1234", 7, 4, 4); + $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x00\x1d(k\x03\x000A\x04\x1d(k\x03\x000C\x07\x1d(k\x03\x000D\x04\x1d(k\x04\x000E1\x01\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0"); + } + + public function testPdf417CodeChangeErrorCorrection() + { + $this -> printer -> pdf417Code("1234", 3, 3, 0, 0.5); + $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x00\x1d(k\x03\x000A\x00\x1d(k\x03\x000C\x03\x1d(k\x03\x000D\x03\x1d(k\x04\x000E1\x05\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0"); + } + + public function testPdf417CodeChangeErrorCorrectionOutOfRange() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> pdf417Code("1234", 3, 3, 0, 5.0); + } + + public function testPdf417CodeChangeErrorCorrectionInvalid() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> pdf417Code("1234", 3, 3, 0, "Foobar"); + } + + public function testPdf417CodeChangeOption() + { + // Use the alternate truncated format + $this -> printer -> pdf417Code("1234", 3, 3, 0, 0.1, Printer::PDF417_TRUNCATED); + $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x01\x1d(k\x03\x000A\x00\x1d(k\x03\x000C\x03\x1d(k\x03\x000D\x03\x1d(k\x04\x000E1\x01\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0"); + } + + /* QR code */ + public function testQRCodeDefaults() + { + // Test will fail if default values change + $this -> printer -> qrCode("1234"); + $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); + } + + public function testQRCodeDefaultsAreCorrect() + { + // Below tests assume that defaults are as written here (output string should be same as above) + $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_L, 3, Printer::QR_MODEL_2); + $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); + } + + public function testQRCodeEmpty() + { + $this -> printer -> qrCode(''); + $this -> checkOutput("\x1b@"); // No commands actually sent + } + + public function testQRCodeChangeEC() + { + $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_H); + $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E3\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); + } + + public function testQRCodeChangeSize() + { + $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_L, 7); + $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x07\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); + } + + public function testQRCodeChangeModel() + { + $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_L, 3, Printer::QR_MODEL_1); + $this -> checkOutput("\x1b@\x1d(k\x04\x001A1\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); + } + + /* Feed form - Required on page-mode only printers */ + public function testFeedForm() + { + $this -> printer -> feedForm(); + $this -> checkOutput("\x1b@\x0c"); + } + + /* Release */ + public function testRelease() + { + $this -> printer -> release(); + $this -> checkOutput("\x1b@\x1b\x71"); + } + + /* Set text size */ + public function testSetTextSizeNormal() + { + $this -> printer -> setTextSize(1, 1); + $this -> checkOutput("\x1b@\x1d!\x00"); + } + + public function testSetTextSizeWide() + { + $this -> printer -> setTextSize(4, 1); + $this -> checkOutput("\x1b@\x1d!0"); + } + + public function testSetTextSizeNarrow() + { + $this -> printer -> setTextSize(1, 4); + $this -> checkOutput("\x1b@\x1d!\x03"); + } + + public function testSetTextSizeLarge() + { + $this -> printer -> setTextSize(4, 4); + $this -> checkOutput("\x1b@\x1d!3"); + } + + public function testSetTextSizeInvalid() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setTextSize(0, 9); + } + + /* Set color */ + public function testSetColorDefault() + { + $this -> printer -> setColor(Printer::COLOR_1); + $this -> checkOutput("\x1b@\x1br\x00"); + } + + public function testSetColorAlternative() + { + $this -> printer -> setColor(Printer::COLOR_2); + $this -> checkOutput("\x1b@\x1br\x01"); + } + + public function testSetColorInvalid() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setColor(3); + } + + /* Set line spacing */ + public function testSetLineSpacingDefault() + { + $this -> printer -> setLineSpacing(); + $this -> checkOutput("\x1b@\x1b2"); + } + + public function testSetLineSpacingInvalid() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setLineSpacing(300); + } + + public function testSetLineSpacingSmaller() + { + $this -> printer -> setLineSpacing(16); + $this -> checkOutput("\x1b@\x1b3\x10"); + } + + public function testSetLineSpacingLarger() + { + $this -> printer -> setLineSpacing(32); + $this -> checkOutput("\x1b@\x1b3\x20"); + } + + /* Set print width */ + public function testSetPrintWidthDefault() + { + $this -> printer -> setPrintWidth(); + $this -> checkOutput("\x1b@\x1dW\x00\x02"); + } + + public function testSetPrintWidthNarrow() + { + $this -> printer -> setPrintWidth(400); + $this -> checkOutput("\x1b@\x1dW\x90\x01"); + } + + public function testSetPrintWidthInvalid() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setPrintWidth(0); + } + + /* Set print left margin */ + public function testSetPrintLeftMarginDefault() + { + $this -> printer -> setPrintLeftMargin(); + $this -> checkOutput("\x1b@\x1dL\x00\x00"); + } + + public function testSetPrintLeftMarginWide() + { + $this -> printer -> setPrintLeftMargin(32); + $this -> checkOutput("\x1b@\x1dL\x20\x00"); + } + + public function testPrintLeftMarginInvalid() + { + $this -> setExpectedException('InvalidArgumentException'); + $this -> printer -> setPrintLeftMargin(70000); + $this -> checkOutput(); + } + + /* Upside-down print */ + public function testSetUpsideDown() + { + $this -> printer -> setUpsideDown(true); + $this -> checkOutput("\x1b@\x1b{\x01"); + } } /* * For testing that string-castable objects are handled */ -class FooBar { - private $foo; - public function __construct($foo) { - $this -> foo = $foo; - } - - public function __toString() { - return $this -> foo; - } +class FooBar +{ + private $foo; + public function __construct($foo) + { + $this -> foo = $foo; + } + + public function __toString() + { + return $this -> foo; + } } -?> diff --git a/htdocs/includes/mike42/escpos-php/test/unit/FilePrintConnectorTest.php b/htdocs/includes/mike42/escpos-php/test/unit/FilePrintConnectorTest.php new file mode 100644 index 00000000000..63728717017 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/test/unit/FilePrintConnectorTest.php @@ -0,0 +1,26 @@ + finalize(); + $connector -> finalize(); // Silently do nothing if printer already closed + unlink($tmpfname); + } + + public function testReadAfterClose() + { + // Should attempt to send data to the local printer by writing to it + $this -> setExpectedException('Exception'); + $tmpfname = tempnam("/tmp", "php"); + $connector = new FilePrintConnector($tmpfname); + $connector -> finalize(); + $connector -> write("Test"); + unlink($tmpfname); + } +} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/GdEscposImageTest.php b/htdocs/includes/mike42/escpos-php/test/unit/GdEscposImageTest.php new file mode 100644 index 00000000000..da755f7b9ee --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/test/unit/GdEscposImageTest.php @@ -0,0 +1,101 @@ + setExpectedException('Exception'); + $this -> loadAndCheckImg('not a real file.png', 1, 1, null, null); + } + + /** + * @medium + */ + public function testGdEmpty() + { + $this -> loadAndCheckImg(null, 0, 0, "", array()); + } + + /** + * @medium + */ + public function testGdBlack() + { + foreach (array('png', 'jpg', 'gif') as $format) { + $this -> loadAndCheckImg('canvas_black.' . $format, 1, 1, "\x80", array("\x80")); + } + } + + /** + * @medium + */ + public function testGdBlackTransparent() + { + foreach (array('png', 'gif') as $format) { + $this -> loadAndCheckImg('black_transparent.' . $format, 2, 2, "\xc0\x00", array("\x80\x80")); + } + } + + /** + * @medium + */ + public function testGdBlackWhite() + { + foreach (array('png', 'jpg', 'gif') as $format) { + $this -> loadAndCheckImg('black_white.' . $format, 2, 2, "\xc0\x00", array("\x80\x80")); + } + } + + /** + * @medium + */ + public function testGdWhite() + { + foreach (array('png', 'jpg', 'gif') as $format) { + $this -> loadAndCheckImg('canvas_white.' . $format, 1, 1, "\x00", array("\x00")); + } + } + + /** + * Load an EscposImage with (optionally) certain libraries disabled and run a check. + */ + private function loadAndCheckImg($fn, $width, $height, $rasterFormat = null, $columnFormat = null) + { + if (!EscposImage::isGdLoaded()) { + $this -> markTestSkipped("imagick plugin is required for this test"); + } + $onDisk = ($fn === null ? null : (dirname(__FILE__) . "/resources/$fn")); + // With optimisations + $imgOptimised = new GdEscposImage($onDisk, true); + $this -> checkImg($imgOptimised, $width, $height, $rasterFormat, $columnFormat); + // ... and without + $imgUnoptimised = new GdEscposImage($onDisk, false); + $this -> checkImg($imgUnoptimised, $width, $height, $rasterFormat, $columnFormat); + } + + /** + * Check image against known width, height, output. + */ + private function checkImg(EscposImage $img, $width, $height, $rasterFormatExpected = null, $columnFormatExpected = null) + { + $rasterFormatActual = $img -> toRasterFormat(); + $columnFormatActual = $img -> toColumnFormat(); + if ($rasterFormatExpected === null) { + echo "\nImage was: " . $img -> getWidth() . "x" . $img -> getHeight() . ", raster data \"" . friendlyBinary($rasterFormatActual) . "\""; + } + if ($columnFormatExpected === null) { + echo "\nImage was: " . $img -> getWidth() . "x" . $img -> getHeight() . ", column data \"" . friendlyBinary($columnFormatActual) . "\""; + } + $this -> assertTrue($img -> getHeight() == $height); + $this -> assertTrue($img -> getWidth() == $width); + $this -> assertTrue($rasterFormatExpected === $rasterFormatActual); + $this -> assertTrue($columnFormatExpected === $columnFormatActual); + } +} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/ImagickEscposImageTest.php b/htdocs/includes/mike42/escpos-php/test/unit/ImagickEscposImageTest.php new file mode 100644 index 00000000000..76831f761c6 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/test/unit/ImagickEscposImageTest.php @@ -0,0 +1,142 @@ + setExpectedException('Exception'); + $this -> loadAndCheckImg('not a real file.png', 1, 1, null, null); + } + + /** + * @medium + */ + public function testImagickEmpty() + { + $this -> loadAndCheckImg(null, 0, 0, "", array()); + } + + /** + * @medium + */ + public function testImagickBlack() + { + foreach (array('png', 'jpg', 'gif') as $format) { + $this -> loadAndCheckImg('canvas_black.' . $format, 1, 1, "\x80", array("\x80")); + } + } + + /** + * @medium + */ + public function testImagickBlackTransparent() + { + foreach (array('png', 'gif') as $format) { + $this -> loadAndCheckImg('black_transparent.' . $format, 2, 2, "\xc0\x00", array("\x80\x80")); + } + } + + /** + * @medium + */ + public function testImagickBlackWhite() + { + foreach (array('png', 'jpg', 'gif') as $format) { + $this -> loadAndCheckImg('black_white.' . $format, 2, 2, "\xc0\x00", array("\x80\x80")); + } + } + + /** + * @medium + */ + public function testImagickBlackWhiteTall() + { + // We're very interested in correct column format chopping here at 8 pixels + $this -> loadAndCheckImg('black_white_tall.png', 2, 16, + "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x00\x00\x00\x00\x00\x00\x00\x00", array("\xff\xff", "\x00\x00")); + } + + /** + * @medium + */ + public function testImagickWhite() + { + foreach (array('png', 'jpg', 'gif') as $format) { + $this -> loadAndCheckImg('canvas_white.' . $format, 1, 1, "\x00", array("\x00")); + } + } + + /** + * PDF test - load tiny PDF and check for well-formedness + * These are also skipped if you don't have imagick + * @medium + */ + public function testPdfAllPages() + { + $this -> loadAndCheckPdf('doc.pdf', 1, 1, array("\x00", "\x80"), array(array("\x00"), array("\x80"))); + } + + public function testPdfBadFilename() + { + $this -> setExpectedException('Exception'); + $this -> loadAndCheckPdf('not a real file', 1, 1, array(), array()); + } + + /** + * Load an EscposImage and run a check. + */ + private function loadAndCheckImg($fn, $width, $height, $rasterFormat = null, $columnFormat = null) + { + if (!EscposImage::isImagickLoaded()) { + $this -> markTestSkipped("imagick plugin is required for this test"); + } + $onDisk = ($fn === null ? null : (dirname(__FILE__) . "/resources/$fn")); + // With optimisations + $imgOptimised = new ImagickEscposImage($onDisk, true); + $this -> checkImg($imgOptimised, $width, $height, $rasterFormat, $columnFormat); + // ... and without + $imgUnoptimised = new ImagickEscposImage($onDisk, false); + $this -> checkImg($imgUnoptimised, $width, $height, $rasterFormat, $columnFormat); + } + + /** + * Same as above, loading document and checking pages against some expected values. + */ + private function loadAndCheckPdf($fn, $width, $height, array $rasterFormat = null, array $columnFormat = null) + { + if (!EscposImage::isImagickLoaded()) { + $this -> markTestSkipped("imagick plugin required for this test"); + } + $pdfPages = ImagickEscposImage::loadPdf(dirname(__FILE__) . "/resources/$fn", $width); + $this -> assertTrue(count($pdfPages) == count($rasterFormat), "Got back wrong number of pages"); + foreach ($pdfPages as $id => $img) { + $this -> checkImg($img, $width, $height, $rasterFormat[$id], $columnFormat[$id]); + } + } + + /** + * Check image against known width, height, output. + */ + private function checkImg(EscposImage $img, $width, $height, $rasterFormatExpected = null, $columnFormatExpected = null) + { + $rasterFormatActual = $img -> toRasterFormat(); + $columnFormatActual = $img -> toColumnFormat(); + if ($rasterFormatExpected === null) { + echo "\nImage was: " . $img -> getWidth() . "x" . $img -> getHeight() . ", raster data \"" . friendlyBinary($rasterFormatActual) . "\""; + } + if ($columnFormatExpected === null) { + echo "\nImage was: " . $img -> getWidth() . "x" . $img -> getHeight() . ", column data \"" . friendlyBinary($columnFormatActual) . "\""; + } + $this -> assertEquals($height , $img -> getHeight()); + $this -> assertEquals($width, $img -> getWidth()); + $this -> assertEquals($rasterFormatExpected, $rasterFormatActual, "Raster format did not match expected"); + $this -> assertEquals($columnFormatExpected, $columnFormatActual, "Column format did not match expected"); + } +} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/LegacyCapabilityProfileTest.php b/htdocs/includes/mike42/escpos-php/test/unit/LegacyCapabilityProfileTest.php new file mode 100644 index 00000000000..360dee90fe7 --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/test/unit/LegacyCapabilityProfileTest.php @@ -0,0 +1,79 @@ + profiles = array( + 'Mike42\Escpos\CapabilityProfiles\DefaultCapabilityProfile', + 'Mike42\Escpos\CapabilityProfiles\EposTepCapabilityProfile', + 'Mike42\Escpos\CapabilityProfiles\SimpleCapabilityProfile', + 'Mike42\Escpos\CapabilityProfiles\StarCapabilityProfile', + 'Mike42\Escpos\CapabilityProfiles\P822DCapabilityProfile'); + $this -> checklist = array(); + foreach ($this -> profiles as $profile) { + $this-> checklist[] = $profile::getInstance(); + } + } + + function testSupportedCodePages() + { + foreach ($this -> checklist as $obj) { + $check = $obj -> getCodePages(); + $this -> assertTrue(is_array($check) && isset($check[0])); + foreach ($check as $num => $page) { + $this -> assertTrue(is_numeric($num)); + } + } + } + + function testText() { + /* Smoke test over text rendering with each profile. + * Just makes sure we can attempt to print 'hello world' and a non-ASCII + * char without anything blowing up */ + foreach ($this -> checklist as $obj) { + $connector = new DummyPrintConnector(); + $printer = new Printer($connector, $obj); + $printer -> text("Hello world €\n"); + $printer -> close(); + // Check for character cache + $profileName = $obj -> getId(); + $expected = "Characters-$profileName.ser.z"; + $filename = __DIR__ . "/../../src/Mike42/Escpos/PrintBuffers/cache/$expected"; + $this -> assertFileExists($filename); + } + } + + function testSupportsBitImageRaster() + { + foreach ($this -> checklist as $obj) { + $check = $obj -> getSupportsBitImageRaster(); + $this -> assertTrue(is_bool($check)); + } + } + + function testSupportsGraphics() + { + foreach ($this -> checklist as $obj) { + $check = $obj -> getSupportsGraphics(); + $this -> assertTrue(is_bool($check)); + } + } + + function testSupportsQrCode() + { + foreach ($this -> checklist as $obj) { + $check = $obj -> getSupportsQrCode(); + $this -> assertTrue(is_bool($check)); + } + } +} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/UriPrintConnectorTest.php b/htdocs/includes/mike42/escpos-php/test/unit/UriPrintConnectorTest.php new file mode 100644 index 00000000000..715dd8d77de --- /dev/null +++ b/htdocs/includes/mike42/escpos-php/test/unit/UriPrintConnectorTest.php @@ -0,0 +1,59 @@ + write("AAA"); + $connector -> finalize(); + $this -> assertEquals("AAA", file_get_contents($filename)); + $this -> assertEquals('Mike42\Escpos\PrintConnectors\FilePrintConnector', get_class($connector)); + unlink($filename); + } + + /** + * @expectedException PHPUnit_Framework_Error + * @expectedExceptionMessage not finalized + */ + public function testSmb() + { + $connector = UriPrintConnector::get("smb://windows/printer"); + $this -> assertEquals('Mike42\Escpos\PrintConnectors\WindowsPrintConnector', get_class($connector)); + // We expect that this will throw an exception, we can't + // realistically print to a real printer in this test though... :) + $connector -> __destruct(); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Malformed connector URI + */ + public function testBadUri() + { + $connector = UriPrintConnector::get("foooooo"); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Connection refused + */ + public function testNetwork() + { + // Port should be closed so we can catch an error and move on + $connector = UriPrintConnector::get("tcp://localhost:45987/"); + } + + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage URI sheme is not supported: ldap:// + */ + public function testUnsupportedUri() + { + // Try to print to something silly + $connector = UriPrintConnector::get("ldap://host:1234/"); + } +} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/WindowsPrintConnectorTest.php b/htdocs/includes/mike42/escpos-php/test/unit/WindowsPrintConnectorTest.php index 392775d3277..f6e10fae5f5 100644 --- a/htdocs/includes/mike42/escpos-php/test/unit/WindowsPrintConnectorTest.php +++ b/htdocs/includes/mike42/escpos-php/test/unit/WindowsPrintConnectorTest.php @@ -1,278 +1,304 @@ getMockConnector("LPT1", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runWrite') - -> with($this -> equalTo(''), $this -> equalTo("LPT1")); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } +class WindowsPrintConnectorTest extends PHPUnit_Framework_TestCase +{ + private $connector; - public function testLptMac() { - // Cannot print to local printer on Mac with this connector - $this -> setExpectedException('BadMethodCallException'); - $connector = $this -> getMockConnector("LPT1", WindowsPrintConnector::PLATFORM_MAC); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } + public function testLptWindows() + { + // Should attempt to send data to the local printer by writing to it + $connector = $this -> getMockConnector("LPT1", WindowsPrintConnector::PLATFORM_WIN); + $connector -> expects($this -> once()) + -> method('runWrite') + -> with($this -> equalTo(''), $this -> equalTo("LPT1")); + $connector -> expects($this -> exactly(0)) + -> method('runCommand'); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> finalize(); + } - public function testLptLinux() { - // Cannot print to local printer on Linux with this connector - $this -> setExpectedException('BadMethodCallException'); - $connector = $this -> getMockConnector("LPT1", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } + public function testLptMac() + { + // Cannot print to local printer on Mac with this connector + $this -> setExpectedException('BadMethodCallException'); + $connector = $this -> getMockConnector("LPT1", WindowsPrintConnector::PLATFORM_MAC); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> exactly(0)) + -> method('runCommand'); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> finalize(); + } - public function testComWindows() { - // Simple file write - $connector = $this -> getMockConnector("COM1", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runWrite') - -> with($this -> equalTo(''), $this -> equalTo("COM1")); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } + public function testLptLinux() + { + // Cannot print to local printer on Linux with this connector + $this -> setExpectedException('BadMethodCallException'); + $connector = $this -> getMockConnector("LPT1", WindowsPrintConnector::PLATFORM_LINUX); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> exactly(0)) + -> method('runCommand'); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> finalize(); + } - public function testComMac() { - // Cannot print to local printer on Mac with this connector - $this -> setExpectedException('BadMethodCallException'); - $connector = $this -> getMockConnector("COM1", WindowsPrintConnector::PLATFORM_MAC); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } + public function testComWindows() + { + // Simple file write + $connector = $this -> getMockConnector("COM1", WindowsPrintConnector::PLATFORM_WIN); + $connector -> expects($this -> once()) + -> method('runWrite') + -> with($this -> equalTo(''), $this -> equalTo("COM1")); + $connector -> expects($this -> exactly(0)) + -> method('runCommand'); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> finalize(); + } - public function testComLinux() { - // Cannot print to local printer on Linux with this connector - $this -> setExpectedException('BadMethodCallException'); - $connector = $this -> getMockConnector("COM1", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } + public function testComMac() + { + // Cannot print to local printer on Mac with this connector + $this -> setExpectedException('BadMethodCallException'); + $connector = $this -> getMockConnector("COM1", WindowsPrintConnector::PLATFORM_MAC); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> exactly(0)) + -> method('runCommand'); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> finalize(); + } - public function testLocalShareWindows() { - $connector = $this -> getMockConnector("Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> stringContains('\\Printer')); - $connector -> finalize(); - } + public function testComLinux() + { + // Cannot print to local printer on Linux with this connector + $this -> setExpectedException('BadMethodCallException'); + $connector = $this -> getMockConnector("COM1", WindowsPrintConnector::PLATFORM_LINUX); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> exactly(0)) + -> method('runCommand'); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> finalize(); + } - public function testSharedPrinterWindows() { - $connector = $this -> getMockConnector("smb://example-pc/Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); - $connector -> finalize(); - } + public function testLocalShareWindows() + { + $connector = $this -> getMockConnector("Printer", WindowsPrintConnector::PLATFORM_WIN); + $connector -> expects($this -> exactly(0)) + -> method('runCommand'); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> once()) + -> method('runCopy') + -> with($this -> anything(), $this -> stringContains('\\Printer')); + $connector -> finalize(); + } - public function testSharedPrinterWindowsUsername() { - $connector = $this -> getMockConnector("smb://bob@example-pc/Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('net use \'\\\\example-pc\\Printer\' \'/user:bob\'')); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); - $connector -> finalize(); - } + public function testSharedPrinterWindows() + { + $connector = $this -> getMockConnector("smb://example-pc/Printer", WindowsPrintConnector::PLATFORM_WIN); + $connector -> expects($this -> exactly(0)) + -> method('runCommand'); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> once()) + -> method('runCopy') + -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); + $connector -> finalize(); + } - public function testSharedPrinterWindowsUsernameDomain() { - $connector = $this -> getMockConnector("smb://bob@example-pc/home/Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('net use \'\\\\example-pc\\Printer\' \'/user:home\\bob\'')); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); - $connector -> finalize(); - } + public function testSharedPrinterWindowsUsername() + { + $connector = $this -> getMockConnector("smb://bob@example-pc/Printer", WindowsPrintConnector::PLATFORM_WIN); + $connector -> expects($this -> once()) + -> method('runCommand') + -> with($this -> equalTo('net use \'\\\\example-pc\\Printer\' \'/user:bob\'')); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> once()) + -> method('runCopy') + -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); + $connector -> finalize(); + } - public function testSharedPrinterWindowsUsernamePassword() { - $connector = $this -> getMockConnector("smb://bob:secret@example-pc/Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('net use \'\\\\example-pc\\Printer\' \'/user:bob\' \'secret\'')); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); - $connector -> finalize(); - } + public function testSharedPrinterWindowsUsernameDomain() + { + $connector = $this -> getMockConnector("smb://bob@example-pc/home/Printer", WindowsPrintConnector::PLATFORM_WIN); + $connector -> expects($this -> once()) + -> method('runCommand') + -> with($this -> equalTo('net use \'\\\\example-pc\\Printer\' \'/user:home\\bob\'')); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> once()) + -> method('runCopy') + -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); + $connector -> finalize(); + } - public function testSharedPrinterMac() { - // Not implemented - $this -> setExpectedException('Exception'); - $connector = $this -> getMockConnector("smb://Guest@example-pc/Printer", WindowsPrintConnector::PLATFORM_MAC); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } + public function testSharedPrinterWindowsUsernamePassword() + { + $connector = $this -> getMockConnector("smb://bob:secret@example-pc/Printer", WindowsPrintConnector::PLATFORM_WIN); + $connector -> expects($this -> once()) + -> method('runCommand') + -> with($this -> equalTo('net use \'\\\\example-pc\\Printer\' \'/user:bob\' \'secret\'')); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> once()) + -> method('runCopy') + -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); + $connector -> finalize(); + } - public function testSharedPrinterLinux() { - $connector = $this -> getMockConnector("smb://example-pc/Printer", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('smbclient \'//example-pc/Printer\' -c \'print -\' -N')); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> finalize(); - } + public function testSharedPrinterMac() + { + // Not implemented + $this -> setExpectedException('Exception'); + $connector = $this -> getMockConnector("smb://Guest@example-pc/Printer", WindowsPrintConnector::PLATFORM_MAC); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> expects($this -> exactly(0)) + -> method('runCommand'); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> finalize(); + } - public function testSharedPrinterLinuxUsername() { - $connector = $this -> getMockConnector("smb://bob@example-pc/Printer", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('smbclient \'//example-pc/Printer\' -U \'bob\' -c \'print -\' -N')); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> finalize(); - } + public function testSharedPrinterLinux() + { + $connector = $this -> getMockConnector("smb://example-pc/Printer", WindowsPrintConnector::PLATFORM_LINUX); + $connector -> expects($this -> once()) + -> method('runCommand') + -> with($this -> equalTo('smbclient \'//example-pc/Printer\' -c \'print -\' -N -m SMB2')); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> finalize(); + } - public function testSharedPrinterLinuxUsernameDomain() { - $connector = $this -> getMockConnector("smb://bob@example-pc/home/Printer", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('smbclient \'//example-pc/Printer\' -U \'home\\bob\' -c \'print -\' -N')); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> finalize(); - } + public function testSharedPrinterLinuxUsername() + { + $connector = $this -> getMockConnector("smb://bob@example-pc/Printer", WindowsPrintConnector::PLATFORM_LINUX); + $connector -> expects($this -> once()) + -> method('runCommand') + -> with($this -> equalTo('smbclient \'//example-pc/Printer\' -U \'bob\' -c \'print -\' -N -m SMB2')); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> finalize(); + } - public function testSharedPrinterLinuxUsernamePassword() { - $connector = $this -> getMockConnector("smb://bob:secret@example-pc/Printer", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('smbclient \'//example-pc/Printer\' \'secret\' -U \'bob\' -c \'print -\'')); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> finalize(); - } + public function testSharedPrinterLinuxUsernameDomain() + { + $connector = $this -> getMockConnector("smb://bob@example-pc/home/Printer", WindowsPrintConnector::PLATFORM_LINUX); + $connector -> expects($this -> once()) + -> method('runCommand') + -> with($this -> equalTo('smbclient \'//example-pc/Printer\' -U \'home\\bob\' -c \'print -\' -N -m SMB2')); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> finalize(); + } - private function getMockConnector($path, $platform) { - $stub = $this -> getMockBuilder('WindowsPrintConnector') - -> setMethods(array('runCopy', 'runCommand', 'getCurrentPlatform', 'runWrite')) - -> disableOriginalConstructor() - -> getMock(); - $stub -> method('runCommand') - -> willReturn(0); - $stub -> method('runCopy') - -> willReturn(true); - $stub -> method('runWrite') - -> willReturn(true); - $stub -> method('getCurrentPlatform') - -> willReturn($platform); - $stub -> __construct($path); - return $stub; - } + public function testSharedPrinterLinuxUsernamePassword() + { + $connector = $this -> getMockConnector("smb://bob:secret@example-pc/Printer", WindowsPrintConnector::PLATFORM_LINUX); + $connector -> expects($this -> once()) + -> method('runCommand') + -> with($this -> equalTo('smbclient \'//example-pc/Printer\' \'secret\' -U \'bob\' -c \'print -\' -m SMB2')); + $connector -> expects($this -> exactly(0)) + -> method('runCopy'); + $connector -> expects($this -> exactly(0)) + -> method('runWrite'); + $connector -> finalize(); + } - /** - * Test for correct identification of bogus or non-supported Samba strings. - */ - public function testSambaRegex() { - $good = array("smb://foo/bar", - "smb://foo/bar baz", - "smb://bob@foo/bar", - "smb://bob:secret@foo/bar", - "smb://foo-computer/FooPrinter", - "smb://foo-computer/workgroup/FooPrinter", - "smb://foo-computer/Foo-Printer", - "smb://foo-computer/workgroup/Foo-Printer", - "smb://foo-computer/Foo Printer"); - $bad = array("", - "http://google.com", - "smb:/foo/bar", - "smb://", - "smb:///bar", - "smb://@foo/bar", - "smb://bob:@foo/bar", - "smb://:secret@foo/bar", - "smb://foo/bar/baz/quux", - "smb://foo-computer//FooPrinter"); - foreach($good as $item) { - $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_SMB, $item) == 1, "Windows samba regex should pass '$item'."); - } - foreach($bad as $item) { - $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_SMB, $item) != 1, "Windows samba regex should fail '$item'."); - } - } - - public function testPrinterNameRegex() { - $good = array("a", - "ab", - "a b", - "a-b", - "Abcd Efg-", - "-a" - ); - $bad = array("", - " ", - "a ", - " a", - " a ", - "a/B", - "A:b" - ); - foreach($good as $item) { - $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_PRINTERNAME, $item) == 1, "Windows printer name regex should pass '$item'."); - } - foreach($bad as $item) { - $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_PRINTERNAME, $item) != 1, "Windows printer name regex should fail '$item'."); - } - } + private function getMockConnector($path, $platform) + { + $stub = $this -> getMockBuilder('Mike42\Escpos\PrintConnectors\WindowsPrintConnector') + -> setMethods(array('runCopy', 'runCommand', 'getCurrentPlatform', 'runWrite')) + -> disableOriginalConstructor() + -> getMock(); + $stub -> method('runCommand') + -> willReturn(0); + $stub -> method('runCopy') + -> willReturn(true); + $stub -> method('runWrite') + -> willReturn(true); + $stub -> method('getCurrentPlatform') + -> willReturn($platform); + $stub -> __construct($path); + return $stub; + } + + /** + * Test for correct identification of bogus or non-supported Samba strings. + */ + public function testSambaRegex() + { + $good = array("smb://foo/bar", + "smb://foo/bar baz", + "smb://bob@foo/bar", + "smb://bob:secret@foo/bar", + "smb://foo-computer/FooPrinter", + "smb://foo-computer/workgroup/FooPrinter", + "smb://foo-computer/Foo-Printer", + "smb://foo-computer/workgroup/Foo-Printer", + "smb://foo-computer/Foo Printer", + "smb://foo-computer.local/Foo Printer", + "smb://127.0.0.1/abcd" + ); + $bad = array("", + "http://google.com", + "smb:/foo/bar", + "smb://", + "smb:///bar", + "smb://@foo/bar", + "smb://bob:@foo/bar", + "smb://:secret@foo/bar", + "smb://foo/bar/baz/quux", + "smb://foo-computer//FooPrinter"); + foreach ($good as $item) { + $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_SMB, $item) == 1, "Windows samba regex should pass '$item'."); + } + foreach ($bad as $item) { + $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_SMB, $item) != 1, "Windows samba regex should fail '$item'."); + } + } + + public function testPrinterNameRegex() + { + $good = array("a", + "ab", + "a b", + "a-b", + "Abcd Efg-", + "-a", + "OK1" + ); + $bad = array("", + " ", + "a ", + " a", + " a ", + "a/B", + "A:b" + ); + foreach ($good as $item) { + $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_PRINTERNAME, $item) == 1, "Windows printer name regex should pass '$item'."); + } + foreach ($bad as $item) { + $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_PRINTERNAME, $item) != 1, "Windows printer name regex should fail '$item'."); + } + } } diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white_tall.png b/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white_tall.png new file mode 100644 index 0000000000000000000000000000000000000000..7e0869dcbed532acfd38204f6539d22d93b515ef GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ea0U|e_vV07rI14-?iy0WWg+Z8+Vb&Z8pdfpR zr>`sfBW7Mkas6JV#5+JC+02lL66gHf+|;}hAeVu`xhOTUBsE2$JhLQ2!QIn0AVn{g z9Vjm0>Eal|aXmRff#2ZY|NrwF8yh(fDbHhKSlq|V+q`4SH;`seS3j3^P6 readImage("doc.pdf[5]"); - $im -> destroy(); -} catch(ImagickException $e) { - echo "Error: " . $e -> getMessage() . "\n"; + $im -> readImage("doc.pdf[5]"); + $im -> destroy(); +} catch (ImagickException $e) { + echo "Error: " . $e -> getMessage() . "\n"; } $im = new Imagick(); try { - ob_start(); - @$im -> readImage("doc.pdf[5]"); - ob_end_clean(); - $im -> destroy(); -} catch(ImagickException $e) { - echo "Error: " . $e -> getMessage() . "\n"; + ob_start(); + @$im -> readImage("doc.pdf[5]"); + ob_end_clean(); + $im -> destroy(); +} catch (ImagickException $e) { + echo "Error: " . $e -> getMessage() . "\n"; } - From 6cb5f28db19e6ba14eea0559763d48c994c21f5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sat, 2 Nov 2019 21:16:59 +0100 Subject: [PATCH 02/10] wip ticket printer --- .../mike42/escpos-php/example/README.md | 26 - .../mike42/escpos-php/example/barcode.php | 207 --- .../mike42/escpos-php/example/bit-image.php | 36 - .../character-encodings-with-images.php | 63 - .../example/character-encodings.php | 60 - .../escpos-php/example/character-tables.php | 75 -- .../escpos-php/example/customer-display.php | 51 - .../mike42/escpos-php/example/demo.php | 171 --- .../mike42/escpos-php/example/graphics.php | 36 - .../escpos-php/example/interface/README.md | 8 - .../escpos-php/example/interface/cups.php | 19 - .../escpos-php/example/interface/ethernet.php | 22 - .../example/interface/linux-usb.php | 33 - .../escpos-php/example/interface/smb.php | 52 - .../example/interface/windows-lpt.php | 31 - .../example/interface/windows-usb.php | 34 - .../example/margins-and-spacing.php | 48 - .../mike42/escpos-php/example/pdf417-code.php | 95 -- .../escpos-php/example/print-from-html.php | 86 -- .../escpos-php/example/print-from-pdf.php | 78 -- .../mike42/escpos-php/example/qr-code.php | 86 -- .../escpos-php/example/rawbt-receipt.html | 76 -- .../escpos-php/example/rawbt-receipt.php | 145 --- .../escpos-php/example/receipt-with-logo.php | 104 -- .../character-encoding-test-strings.inc | 35 - .../example/resources/document.html | 40 - .../escpos-php/example/resources/document.odt | Bin 39751 -> 0 bytes .../escpos-php/example/resources/document.pdf | Bin 24389 -> 0 bytes .../escpos-php/example/resources/document.z | Bin 18900 -> 0 bytes .../example/resources/escpos-php-small.png | Bin 1941 -> 0 bytes .../example/resources/escpos-php.png | Bin 7871 -> 0 bytes .../example/resources/rawbtlogo.png | Bin 1358 -> 0 bytes .../escpos-php/example/resources/tulips.png | Bin 379443 -> 0 bytes .../escpos-php/example/resources/tux.png | Bin 5198 -> 0 bytes .../example/specific/123-code128-barcode.php | 21 - .../example/specific/141-custom-command.php | 55 - .../example/specific/148-data-uri.php | 35 - .../example/specific/235-get-data.php | 28 - .../specific/29-latvian-star-tup592.php | 25 - .../32-german-tm-t20-ii-custom-command.php | 39 - .../specific/33-spanish-seypos-prp-300.php | 19 - .../example/specific/37-chinese.php | 24 - .../example/specific/39-currency-symbols.php | 77 -- .../specific/44-pound-symbol-star-tsp650.php | 35 - .../example/specific/50-P-822D-greek.php | 19 - .../example/specific/54-gfx-sidebyside.php | 64 - .../specific/6-arabic-epos-tep-220m.php | 74 -- .../example/specific/62-greek-symbol-swap.php | 15 - .../example/specific/68-redblack.php | 21 - .../example/specific/97-dithering.php | 28 - .../escpos-php/example/specific/README.md | 7 - .../mike42/escpos-php/example/text-size.php | 65 - .../mike42/escpos-php/test/bootstrap.php | 40 - .../test/integration/ExampleTest.php | 187 --- .../integration/resources/output/barcode.bin | Bin 2667 -> 0 bytes .../resources/output/bit-image.bin | Bin 9789 -> 0 bytes .../resources/output/character-encodings.bin | Bin 1930 -> 0 bytes .../resources/output/character-tables.bin | Bin 7969 -> 0 bytes .../integration/resources/output/demo.bin | Bin 73643 -> 0 bytes .../integration/resources/output/graphics.bin | Bin 9635 -> 0 bytes .../resources/output/margins-and-spacing.bin | Bin 339 -> 0 bytes .../resources/output/pdf417-code.bin | Bin 2366 -> 0 bytes .../integration/resources/output/qr-code.bin | Bin 1551 -> 0 bytes .../resources/output/receipt-with-logo.bin | Bin 9579 -> 0 bytes .../resources/output/text-size.bin | Bin 368 -> 0 bytes .../test/unit/AuresCustomerDisplayTest.php | 76 -- .../test/unit/CapabilityProfileTest.php | 59 - .../escpos-php/test/unit/CodePageTest.php | 63 - .../test/unit/CupsPrintConnectorTest.php | 36 - .../escpos-php/test/unit/EscposImageTest.php | 16 - .../test/unit/EscposPrintBufferTest.php | 192 --- .../escpos-php/test/unit/EscposTest.php | 1127 ----------------- .../test/unit/FilePrintConnectorTest.php | 26 - .../test/unit/GdEscposImageTest.php | 101 -- .../test/unit/ImagickEscposImageTest.php | 142 --- .../test/unit/LegacyCapabilityProfileTest.php | 79 -- .../test/unit/UriPrintConnectorTest.php | 59 - .../test/unit/WindowsPrintConnectorTest.php | 304 ----- .../test/unit/resources/black_transparent.gif | Bin 65 -> 0 bytes .../test/unit/resources/black_transparent.png | Bin 167 -> 0 bytes .../test/unit/resources/black_white.bmp | Bin 138 -> 0 bytes .../test/unit/resources/black_white.gif | Bin 65 -> 0 bytes .../test/unit/resources/black_white.jpg | Bin 175 -> 0 bytes .../test/unit/resources/black_white.png | Bin 156 -> 0 bytes .../test/unit/resources/black_white_tall.png | Bin 162 -> 0 bytes .../test/unit/resources/canvas_black.bmp | Bin 142 -> 0 bytes .../test/unit/resources/canvas_black.gif | Bin 72 -> 0 bytes .../test/unit/resources/canvas_black.jpg | Bin 160 -> 0 bytes .../test/unit/resources/canvas_black.png | Bin 239 -> 0 bytes .../test/unit/resources/canvas_white.bmp | Bin 142 -> 0 bytes .../test/unit/resources/canvas_white.gif | Bin 72 -> 0 bytes .../test/unit/resources/canvas_white.jpg | Bin 160 -> 0 bytes .../test/unit/resources/canvas_white.png | Bin 239 -> 0 bytes .../escpos-php/test/unit/resources/demo.php | 18 - .../escpos-php/test/unit/resources/doc.pdf | Bin 6681 -> 0 bytes 95 files changed, 4893 deletions(-) delete mode 100644 htdocs/includes/mike42/escpos-php/example/README.md delete mode 100644 htdocs/includes/mike42/escpos-php/example/barcode.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/bit-image.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/character-encodings-with-images.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/character-encodings.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/character-tables.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/customer-display.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/demo.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/graphics.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/interface/README.md delete mode 100644 htdocs/includes/mike42/escpos-php/example/interface/cups.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/interface/ethernet.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/interface/linux-usb.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/interface/smb.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/interface/windows-lpt.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/interface/windows-usb.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/margins-and-spacing.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/pdf417-code.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/print-from-html.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/print-from-pdf.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/qr-code.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/rawbt-receipt.html delete mode 100644 htdocs/includes/mike42/escpos-php/example/rawbt-receipt.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/receipt-with-logo.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/character-encoding-test-strings.inc delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/document.html delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/document.odt delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/document.pdf delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/document.z delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/escpos-php-small.png delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/escpos-php.png delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/rawbtlogo.png delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/tulips.png delete mode 100644 htdocs/includes/mike42/escpos-php/example/resources/tux.png delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/123-code128-barcode.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/141-custom-command.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/148-data-uri.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/235-get-data.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/29-latvian-star-tup592.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/32-german-tm-t20-ii-custom-command.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/33-spanish-seypos-prp-300.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/37-chinese.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/39-currency-symbols.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/44-pound-symbol-star-tsp650.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/50-P-822D-greek.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/54-gfx-sidebyside.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/6-arabic-epos-tep-220m.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/62-greek-symbol-swap.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/68-redblack.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/97-dithering.php delete mode 100644 htdocs/includes/mike42/escpos-php/example/specific/README.md delete mode 100644 htdocs/includes/mike42/escpos-php/example/text-size.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/bootstrap.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/ExampleTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/barcode.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/bit-image.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/character-encodings.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/character-tables.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/demo.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/graphics.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/margins-and-spacing.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/pdf417-code.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/qr-code.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/receipt-with-logo.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/integration/resources/output/text-size.bin delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/AuresCustomerDisplayTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/CapabilityProfileTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/CodePageTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/CupsPrintConnectorTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/EscposImageTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/EscposPrintBufferTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/EscposTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/FilePrintConnectorTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/GdEscposImageTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/ImagickEscposImageTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/LegacyCapabilityProfileTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/UriPrintConnectorTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/WindowsPrintConnectorTest.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/black_transparent.gif delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/black_transparent.png delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.bmp delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.gif delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.jpg delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.png delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/black_white_tall.png delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_black.bmp delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_black.gif delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_black.jpg delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_black.png delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.bmp delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.gif delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.jpg delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.png delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/demo.php delete mode 100644 htdocs/includes/mike42/escpos-php/test/unit/resources/doc.pdf diff --git a/htdocs/includes/mike42/escpos-php/example/README.md b/htdocs/includes/mike42/escpos-php/example/README.md deleted file mode 100644 index e59e6c095e4..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/README.md +++ /dev/null @@ -1,26 +0,0 @@ -Examples --------- - -This folder contains a collectoion of feature examples. -Generally, demo.php is the fastest way to find out which features your -printer supports. - -## Subfolders -- `interface/` - contains examples for output interfaces: eg, parallel, serial, USB, network, file-based. -- `specific/` - examples made in response to issues & questions. These cover specific languages, printers and interfaces, so hit narrower use cases. - -## List of examples - -Each example prints to standard output, so either edit the print connector, or redirect the output to your printer to see it in action. They are designed for developers: open them in a text editor before you run them! - -- `bit-image.php` - Prints a images to the printer using the older "bit image" commands. -- `demo.php` - Demonstrates output using a large subset of availale features. -- `qr-code.php` - Prints QR codes, if your printer supports it. -- `character-encodings.php` - Shows available character encodings. Change from the DefaultCapabilityProfile to get more useful output for your specific printer. -- `graphics.php` - The same output as `bit-image.php`, printed with the newer graphics commands (not supported on many non-Epson printers) -- `receipt-with-logo.php` - A simple receipt containing a logo and basic formating. -- `character-encodings-with-images.php` - The same as `character-encodings.php`, but also prints each string using an `ImagePrintBuffer`, showing compatibility gaps. -- `print-from-html.php` - Runs `wkhtmltoimage` to convert HTML to an image, and then prints the image. (This is very slow) -- `character-tables.php` - Prints a compact character code table for each available character set. Used to debug incorrect output from `character-encodings.php`. -- `print-from-pdf.php` - Loads a PDF and prints each page in a few different ways (very slow as well) -- `rawbt-receipt` (.php & .html) - Demonstration of Back and Front for integration between the site and the Android application “RawBT - Printer Driver for Android” diff --git a/htdocs/includes/mike42/escpos-php/example/barcode.php b/htdocs/includes/mike42/escpos-php/example/barcode.php deleted file mode 100644 index d3ef9f2f44a..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/barcode.php +++ /dev/null @@ -1,207 +0,0 @@ -selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); -$printer->text("Height and bar width\n"); -$printer->selectPrintMode(); -$heights = array(1, 2, 4, 8, 16, 32); -$widths = array(1, 2, 3, 4, 5, 6, 7, 8); -$printer -> text("Default look\n"); -$printer->barcode("ABC", Printer::BARCODE_CODE39); - -foreach($heights as $height) { - $printer -> text("\nHeight $height\n"); - $printer->setBarcodeHeight($height); - $printer->barcode("ABC", Printer::BARCODE_CODE39); -} -foreach($widths as $width) { - $printer -> text("\nWidth $width\n"); - $printer->setBarcodeWidth($width); - $printer->barcode("ABC", Printer::BARCODE_CODE39); -} -$printer->feed(); -// Set to something sensible for the rest of the examples -$printer->setBarcodeHeight(40); -$printer->setBarcodeWidth(2); - -/* Text position */ -$printer->selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); -$printer->text("Text position\n"); -$printer->selectPrintMode(); -$hri = array ( - Printer::BARCODE_TEXT_NONE => "No text", - Printer::BARCODE_TEXT_ABOVE => "Above", - Printer::BARCODE_TEXT_BELOW => "Below", - Printer::BARCODE_TEXT_ABOVE | Printer::BARCODE_TEXT_BELOW => "Both" -); -foreach ($hri as $position => $caption) { - $printer->text($caption . "\n"); - $printer->setBarcodeTextPosition($position); - $printer->barcode("012345678901", Printer::BARCODE_JAN13); - $printer->feed(); -} - -/* Barcode types */ -$standards = array ( - Printer::BARCODE_UPCA => array ( - "title" => "UPC-A", - "caption" => "Fixed-length numeric product barcodes.", - "example" => array ( - array ( - "caption" => "12 char numeric including (wrong) check digit.", - "content" => "012345678901" - ), - array ( - "caption" => "Send 11 chars to add check digit automatically.", - "content" => "01234567890" - ) - ) - ), - Printer::BARCODE_UPCE => array ( - "title" => "UPC-E", - "caption" => "Fixed-length numeric compact product barcodes.", - "example" => array ( - array ( - "caption" => "6 char numeric - auto check digit & NSC", - "content" => "123456" - ), - array ( - "caption" => "7 char numeric - auto check digit", - "content" => "0123456" - ), - array ( - "caption" => "8 char numeric", - "content" => "01234567" - ), - array ( - "caption" => "11 char numeric - auto check digit", - "content" => "01234567890" - ), - array ( - "caption" => "12 char numeric including (wrong) check digit", - "content" => "012345678901" - ) - ) - ), - Printer::BARCODE_JAN13 => array ( - "title" => "JAN13/EAN13", - "caption" => "Fixed-length numeric barcodes.", - "example" => array ( - array ( - "caption" => "12 char numeric - auto check digit", - "content" => "012345678901" - ), - array ( - "caption" => "13 char numeric including (wrong) check digit", - "content" => "0123456789012" - ) - ) - ), - Printer::BARCODE_JAN8 => array ( - "title" => "JAN8/EAN8", - "caption" => "Fixed-length numeric barcodes.", - "example" => array ( - array ( - "caption" => "7 char numeric - auto check digit", - "content" => "0123456" - ), - array ( - "caption" => "8 char numeric including (wrong) check digit", - "content" => "01234567" - ) - ) - ), - Printer::BARCODE_CODE39 => array ( - "title" => "Code39", - "caption" => "Variable length alphanumeric w/ some special chars.", - "example" => array ( - array ( - "caption" => "Text, numbers, spaces", - "content" => "ABC 012" - ), - array ( - "caption" => "Special characters", - "content" => "$%+-./" - ), - array ( - "caption" => "Extra char (*) Used as start/stop", - "content" => "*TEXT*" - ) - ) - ), - Printer::BARCODE_ITF => array ( - "title" => "ITF", - "caption" => "Variable length numeric w/even number of digits,\nas they are encoded in pairs.", - "example" => array ( - array ( - "caption" => "Numeric- even number of digits", - "content" => "0123456789" - ) - ) - ), - Printer::BARCODE_CODABAR => array ( - "title" => "Codabar", - "caption" => "Varaible length numeric with some allowable\nextra characters. ABCD/abcd must be used as\nstart/stop characters (one at the start, one\nat the end) to distinguish between barcode\napplications.", - "example" => array ( - array ( - "caption" => "Numeric w/ A A start/stop. ", - "content" => "A012345A" - ), - array ( - "caption" => "Extra allowable characters", - "content" => "A012$+-./:A" - ) - ) - ), - Printer::BARCODE_CODE93 => array ( - "title" => "Code93", - "caption" => "Variable length- any ASCII is available", - "example" => array ( - array ( - "caption" => "Text", - "content" => "012abcd" - ) - ) - ), - Printer::BARCODE_CODE128 => array ( - "title" => "Code128", - "caption" => "Variable length- any ASCII is available", - "example" => array ( - array ( - "caption" => "Code set A uppercase & symbols", - "content" => "{A" . "012ABCD" - ), - array ( - "caption" => "Code set B general text", - "content" => "{B" . "012ABCDabcd" - ), - array ( - "caption" => "Code set C compact numbers\n Sending chr(21) chr(32) chr(43)", - "content" => "{C" . chr(21) . chr(32) . chr(43) - ) - ) - ) -); -$printer->setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW); -foreach ($standards as $type => $standard) { - $printer->selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); - $printer->text($standard ["title"] . "\n"); - $printer->selectPrintMode(); - $printer->text($standard ["caption"] . "\n\n"); - foreach ($standard ["example"] as $id => $barcode) { - $printer->setEmphasis(true); - $printer->text($barcode ["caption"] . "\n"); - $printer->setEmphasis(false); - $printer->text("Content: " . $barcode ["content"] . "\n"); - $printer->barcode($barcode ["content"], $type); - $printer->feed(); - } -} -$printer->cut(); -$printer->close(); diff --git a/htdocs/includes/mike42/escpos-php/example/bit-image.php b/htdocs/includes/mike42/escpos-php/example/bit-image.php deleted file mode 100644 index befebf80b9f..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/bit-image.php +++ /dev/null @@ -1,36 +0,0 @@ - text("These example images are printed with the older\nbit image print command. You should only use\n\$p -> bitImage() if \$p -> graphics() does not\nwork on your printer.\n\n"); - - $printer -> bitImage($tux); - $printer -> text("Regular Tux (bit image).\n"); - $printer -> feed(); - - $printer -> bitImage($tux, Printer::IMG_DOUBLE_WIDTH); - $printer -> text("Wide Tux (bit image).\n"); - $printer -> feed(); - - $printer -> bitImage($tux, Printer::IMG_DOUBLE_HEIGHT); - $printer -> text("Tall Tux (bit image).\n"); - $printer -> feed(); - - $printer -> bitImage($tux, Printer::IMG_DOUBLE_WIDTH | Printer::IMG_DOUBLE_HEIGHT); - $printer -> text("Large Tux in correct proportion (bit image).\n"); -} catch (Exception $e) { - /* Images not supported on your PHP, or image file not found */ - $printer -> text($e -> getMessage() . "\n"); -} - -$printer -> cut(); -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/character-encodings-with-images.php b/htdocs/includes/mike42/escpos-php/example/character-encodings-with-images.php deleted file mode 100644 index bc99c2f1872..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/character-encodings-with-images.php +++ /dev/null @@ -1,63 +0,0 @@ - selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_EMPHASIZED | Printer::MODE_DOUBLE_WIDTH); - $printer -> text("Implemented languages\n"); - $printer -> selectPrintMode(); - foreach ($inputsOk as $label => $str) { - $printer -> setEmphasis(true); - $printer -> text($label . ":\n"); - $printer -> setEmphasis(false); - foreach ($buffers as $buffer) { - $printer -> setPrintBuffer($buffer); - $printer -> text($str); - } - $printer -> setPrintBuffer($buffers[0]); - } - $printer -> feed(); - - $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_EMPHASIZED | Printer::MODE_DOUBLE_WIDTH); - $printer -> text("Works in progress\n"); - $printer -> selectPrintMode(); - foreach ($inputsNotOk as $label => $str) { - $printer -> setEmphasis(true); - $printer -> text($label . ":\n"); - $printer -> setEmphasis(false); - foreach ($buffers as $buffer) { - $printer -> setPrintBuffer($buffer); - $printer -> text($str); - } - $printer -> setPrintBuffer($buffers[0]); - } - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch (Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; -} diff --git a/htdocs/includes/mike42/escpos-php/example/character-encodings.php b/htdocs/includes/mike42/escpos-php/example/character-encodings.php deleted file mode 100644 index a38e99fb9ea..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/character-encodings.php +++ /dev/null @@ -1,60 +0,0 @@ - selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_EMPHASIZED | Printer::MODE_DOUBLE_WIDTH); - $printer -> text("Implemented languages\n"); - $printer -> selectPrintMode(); - foreach ($inputsOk as $label => $str) { - $printer -> setEmphasis(true); - $printer -> text($label . ":\n"); - $printer -> setEmphasis(false); - $printer -> text($str); - } - $printer -> feed(); - - $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_EMPHASIZED | Printer::MODE_DOUBLE_WIDTH); - $printer -> text("Works in progress\n"); - $printer -> selectPrintMode(); - foreach ($inputsNotOk as $label => $str) { - $printer -> setEmphasis(true); - $printer -> text($label . ":\n"); - $printer -> setEmphasis(false); - $printer -> text($str); - } - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch (Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; -} diff --git a/htdocs/includes/mike42/escpos-php/example/character-tables.php b/htdocs/includes/mike42/escpos-php/example/character-tables.php deleted file mode 100644 index d2ab8bbcfa1..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/character-tables.php +++ /dev/null @@ -1,75 +0,0 @@ - getCodePages(); -$first = true; // Print larger table for first code-page. -foreach ($codePages as $table => $page) { - /* Change printer code page */ - $printer -> selectCharacterTable(255); - $printer -> selectCharacterTable($table); - /* Select & print a label for it */ - $label = $page -> getId(); - if (!$page -> isEncodable()) { - $label= " (not supported)"; - } - $printer -> setEmphasis(true); - $printer -> textRaw("Table $table: $label\n"); - $printer -> setEmphasis(false); - if (!$page -> isEncodable() && !$verbose) { - continue; // Skip non-recognised - } - /* Print a table of available characters (first table is larger than subsequent ones */ - if ($first) { - $first = false; - compactCharTable($printer, 1, true); - } else { - compactCharTable($printer); - } -} -$printer -> cut(); -$printer -> close(); - -function compactCharTable($printer, $start = 4, $header = false) -{ - /* Output a compact character table for the current encoding */ - $chars = str_repeat(' ', 256); - for ($i = 0; $i < 255; $i++) { - $chars[$i] = ($i > 32 && $i != 127) ? chr($i) : ' '; - } - if ($header) { - $printer -> setEmphasis(true); - $printer -> textRaw(" 0123456789ABCDEF0123456789ABCDEF\n"); - $printer -> setEmphasis(false); - } - for ($y = $start; $y < 8; $y++) { - $printer -> setEmphasis(true); - $printer -> textRaw(strtoupper(dechex($y * 2)) . " "); - $printer -> setEmphasis(false); - $printer -> textRaw(substr($chars, $y * 32, 32) . "\n"); - } -} diff --git a/htdocs/includes/mike42/escpos-php/example/customer-display.php b/htdocs/includes/mike42/escpos-php/example/customer-display.php deleted file mode 100644 index 47947789540..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/customer-display.php +++ /dev/null @@ -1,51 +0,0 @@ - feed(); - $display -> text($line); - usleep(500000); -} - -// Finish by showing "Hello World" -$display -> clear(); -$display -> text("Hello World\n"); - -// Dont forget to close the device -$display -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/demo.php b/htdocs/includes/mike42/escpos-php/example/demo.php deleted file mode 100644 index f0e357ed431..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/demo.php +++ /dev/null @@ -1,171 +0,0 @@ - - */ -require __DIR__ . '/../autoload.php'; -use Mike42\Escpos\Printer; -use Mike42\Escpos\PrintConnectors\FilePrintConnector; -use Mike42\Escpos\EscposImage; - -$connector = new FilePrintConnector("php://stdout"); -$printer = new Printer($connector); - -/* Initialize */ -$printer -> initialize(); - -/* Text */ -$printer -> text("Hello world\n"); -$printer -> cut(); - -/* Line feeds */ -$printer -> text("ABC"); -$printer -> feed(7); -$printer -> text("DEF"); -$printer -> feedReverse(3); -$printer -> text("GHI"); -$printer -> feed(); -$printer -> cut(); - -/* Font modes */ -$modes = array( - Printer::MODE_FONT_B, - Printer::MODE_EMPHASIZED, - Printer::MODE_DOUBLE_HEIGHT, - Printer::MODE_DOUBLE_WIDTH, - Printer::MODE_UNDERLINE); -for ($i = 0; $i < pow(2, count($modes)); $i++) { - $bits = str_pad(decbin($i), count($modes), "0", STR_PAD_LEFT); - $mode = 0; - for ($j = 0; $j < strlen($bits); $j++) { - if (substr($bits, $j, 1) == "1") { - $mode |= $modes[$j]; - } - } - $printer -> selectPrintMode($mode); - $printer -> text("ABCDEFGHIJabcdefghijk\n"); -} -$printer -> selectPrintMode(); // Reset -$printer -> cut(); - -/* Underline */ -for ($i = 0; $i < 3; $i++) { - $printer -> setUnderline($i); - $printer -> text("The quick brown fox jumps over the lazy dog\n"); -} -$printer -> setUnderline(0); // Reset -$printer -> cut(); - -/* Cuts */ -$printer -> text("Partial cut\n(not available on all printers)\n"); -$printer -> cut(Printer::CUT_PARTIAL); -$printer -> text("Full cut\n"); -$printer -> cut(Printer::CUT_FULL); - -/* Emphasis */ -for ($i = 0; $i < 2; $i++) { - $printer -> setEmphasis($i == 1); - $printer -> text("The quick brown fox jumps over the lazy dog\n"); -} -$printer -> setEmphasis(false); // Reset -$printer -> cut(); - -/* Double-strike (looks basically the same as emphasis) */ -for ($i = 0; $i < 2; $i++) { - $printer -> setDoubleStrike($i == 1); - $printer -> text("The quick brown fox jumps over the lazy dog\n"); -} -$printer -> setDoubleStrike(false); -$printer -> cut(); - -/* Fonts (many printers do not have a 'Font C') */ -$fonts = array( - Printer::FONT_A, - Printer::FONT_B, - Printer::FONT_C); -for ($i = 0; $i < count($fonts); $i++) { - $printer -> setFont($fonts[$i]); - $printer -> text("The quick brown fox jumps over the lazy dog\n"); -} -$printer -> setFont(); // Reset -$printer -> cut(); - -/* Justification */ -$justification = array( - Printer::JUSTIFY_LEFT, - Printer::JUSTIFY_CENTER, - Printer::JUSTIFY_RIGHT); -for ($i = 0; $i < count($justification); $i++) { - $printer -> setJustification($justification[$i]); - $printer -> text("A man a plan a canal panama\n"); -} -$printer -> setJustification(); // Reset -$printer -> cut(); - -/* Barcodes - see barcode.php for more detail */ -$printer -> setBarcodeHeight(80); -$printer->setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW); -$printer -> barcode("9876"); -$printer -> feed(); -$printer -> cut(); - -/* Graphics - this demo will not work on some non-Epson printers */ -try { - $logo = EscposImage::load("resources/escpos-php.png", false); - $imgModes = array( - Printer::IMG_DEFAULT, - Printer::IMG_DOUBLE_WIDTH, - Printer::IMG_DOUBLE_HEIGHT, - Printer::IMG_DOUBLE_WIDTH | Printer::IMG_DOUBLE_HEIGHT - ); - foreach ($imgModes as $mode) { - $printer -> graphics($logo, $mode); - } -} catch (Exception $e) { - /* Images not supported on your PHP, or image file not found */ - $printer -> text($e -> getMessage() . "\n"); -} -$printer -> cut(); - -/* Bit image */ -try { - $logo = EscposImage::load("resources/escpos-php.png", false); - $imgModes = array( - Printer::IMG_DEFAULT, - Printer::IMG_DOUBLE_WIDTH, - Printer::IMG_DOUBLE_HEIGHT, - Printer::IMG_DOUBLE_WIDTH | Printer::IMG_DOUBLE_HEIGHT - ); - foreach ($imgModes as $mode) { - $printer -> bitImage($logo, $mode); - } -} catch (Exception $e) { - /* Images not supported on your PHP, or image file not found */ - $printer -> text($e -> getMessage() . "\n"); -} -$printer -> cut(); - -/* QR Code - see also the more in-depth demo at qr-code.php */ -$testStr = "Testing 123"; -$models = array( - Printer::QR_MODEL_1 => "QR Model 1", - Printer::QR_MODEL_2 => "QR Model 2 (default)", - Printer::QR_MICRO => "Micro QR code\n(not supported on all printers)"); -foreach ($models as $model => $name) { - $printer -> qrCode($testStr, Printer::QR_ECLEVEL_L, 3, $model); - $printer -> text("$name\n"); - $printer -> feed(); -} -$printer -> cut(); - -/* Pulse */ -$printer -> pulse(); - -/* Always close the printer! On some PrintConnectors, no actual - * data is sent until the printer is closed. */ -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/graphics.php b/htdocs/includes/mike42/escpos-php/example/graphics.php deleted file mode 100644 index 49b02b9b0d9..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/graphics.php +++ /dev/null @@ -1,36 +0,0 @@ - graphics($tux); - $printer -> text("Regular Tux.\n"); - $printer -> feed(); - - $printer -> graphics($tux, Printer::IMG_DOUBLE_WIDTH); - $printer -> text("Wide Tux.\n"); - $printer -> feed(); - - $printer -> graphics($tux, Printer::IMG_DOUBLE_HEIGHT); - $printer -> text("Tall Tux.\n"); - $printer -> feed(); - - $printer -> graphics($tux, Printer::IMG_DOUBLE_WIDTH | Printer::IMG_DOUBLE_HEIGHT); - $printer -> text("Large Tux in correct proportion.\n"); - - $printer -> cut(); -} catch (Exception $e) { - /* Images not supported on your PHP, or image file not found */ - $printer -> text($e -> getMessage() . "\n"); -} - -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/interface/README.md b/htdocs/includes/mike42/escpos-php/example/interface/README.md deleted file mode 100644 index 96fe2eed2fb..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/interface/README.md +++ /dev/null @@ -1,8 +0,0 @@ -Interfaces ----------- -This directory contains boilerpalte code to show you how to open a print connector -to printers which are connected in different ways. - -To get a list of supported interfaces and operating systems, see the main README.md file for the project. - -If you have a printer interface with no example, and you want to help put one together, then please lodge a request on the bug tracker: https://github.com/mike42/escpos-php/issues diff --git a/htdocs/includes/mike42/escpos-php/example/interface/cups.php b/htdocs/includes/mike42/escpos-php/example/interface/cups.php deleted file mode 100644 index 8b65ab3d4d9..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/interface/cups.php +++ /dev/null @@ -1,19 +0,0 @@ - text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch (Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; -} diff --git a/htdocs/includes/mike42/escpos-php/example/interface/ethernet.php b/htdocs/includes/mike42/escpos-php/example/interface/ethernet.php deleted file mode 100644 index 129af5ce3aa..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/interface/ethernet.php +++ /dev/null @@ -1,22 +0,0 @@ - text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch (Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; -} diff --git a/htdocs/includes/mike42/escpos-php/example/interface/linux-usb.php b/htdocs/includes/mike42/escpos-php/example/interface/linux-usb.php deleted file mode 100644 index 2b390f658b2..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/interface/linux-usb.php +++ /dev/null @@ -1,33 +0,0 @@ - text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch (Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; -} diff --git a/htdocs/includes/mike42/escpos-php/example/interface/smb.php b/htdocs/includes/mike42/escpos-php/example/interface/smb.php deleted file mode 100644 index fac54b342d1..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/interface/smb.php +++ /dev/null @@ -1,52 +0,0 @@ - testfile - * ## If you need authentication, use "net use" to hook up the printer: - * # net use "\\computername\Receipt Printer" /user:Guest - * # net use "\\computername\Receipt Printer" /user:Bob secret - * # net use "\\computername\Receipt Printer" /user:workgroup\Bob secret - * copy testfile "\\computername\Receipt Printer" - * del testfile - * - * GNU/Linux: - * # No authentication - * echo "Hello World" | smbclient "//computername/Receipt Printer" -c "print -" -N - * # Guest login - * echo "Hello World" | smbclient "//computername/Receipt Printer" -U Guest -c "print -" -N - * # Basic username/password - * echo "Hello World" | smbclient "//computername/Receipt Printer" secret -U "Bob" -c "print -" - * # Including domain name - * echo "Hello World" | smbclient "//computername/Receipt Printer" secret -U "workgroup\\Bob" -c "print -" - */ -try { - // Enter the share name for your printer here, as a smb:// url format - $connector = new WindowsPrintConnector("smb://computername/Receipt Printer"); - //$connector = new WindowsPrintConnector("smb://Guest@computername/Receipt Printer"); - //$connector = new WindowsPrintConnector("smb://FooUser:secret@computername/workgroup/Receipt Printer"); - //$connector = new WindowsPrintConnector("smb://User:secret@computername/Receipt Printer"); - - /* Print a "Hello world" receipt" */ - $printer = new Printer($connector); - $printer -> text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch (Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; -} diff --git a/htdocs/includes/mike42/escpos-php/example/interface/windows-lpt.php b/htdocs/includes/mike42/escpos-php/example/interface/windows-lpt.php deleted file mode 100644 index e8fef286bd8..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/interface/windows-lpt.php +++ /dev/null @@ -1,31 +0,0 @@ - LPT1 - */ -try { - $connector = new WindowsPrintConnector("LPT1"); - - // A FilePrintConnector will also work, but on non-Windows systems, writes - // to an actual file called 'LPT1' rather than giving a useful error. - // $connector = new FilePrintConnector("LPT1"); - - /* Print a "Hello world" receipt" */ - $printer = new Printer($connector); - $printer -> text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch (Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; -} diff --git a/htdocs/includes/mike42/escpos-php/example/interface/windows-usb.php b/htdocs/includes/mike42/escpos-php/example/interface/windows-usb.php deleted file mode 100644 index 79776994231..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/interface/windows-usb.php +++ /dev/null @@ -1,34 +0,0 @@ - testfile - * copy testfile "\\%COMPUTERNAME%\Receipt Printer" - * del testfile - */ -try { - // Enter the share name for your USB printer here - $connector = null; - //$connector = new WindowsPrintConnector("Receipt Printer"); - - /* Print a "Hello world" receipt" */ - $printer = new Printer($connector); - $printer -> text("Hello World!\n"); - $printer -> cut(); - - /* Close printer */ - $printer -> close(); -} catch (Exception $e) { - echo "Couldn't print to this printer: " . $e -> getMessage() . "\n"; -} diff --git a/htdocs/includes/mike42/escpos-php/example/margins-and-spacing.php b/htdocs/includes/mike42/escpos-php/example/margins-and-spacing.php deleted file mode 100644 index 296a7b0bc73..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/margins-and-spacing.php +++ /dev/null @@ -1,48 +0,0 @@ - setEmphasis(true); -$printer -> text("Line spacing\n"); -$printer -> setEmphasis(false); -foreach(array(16, 32, 64, 128, 255) as $spacing) { - $printer -> setLineSpacing($spacing); - $printer -> text("Spacing $spacing: The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.\n"); -} -$printer -> setLineSpacing(); // Back to default -*/ - -/* Stuff around with left margin */ -$printer -> setEmphasis(true); -$printer -> text("Left margin\n"); -$printer -> setEmphasis(false); -$printer -> text("Default left\n"); -foreach(array(1, 2, 4, 8, 16, 32, 64, 128, 256, 512) as $margin) { - $printer -> setPrintLeftMargin($margin); - $printer -> text("left margin $margin\n"); -} -/* Reset left */ -$printer -> setPrintLeftMargin(0); - -/* Stuff around with page width */ -$printer -> setEmphasis(true); -$printer -> text("Page width\n"); -$printer -> setEmphasis(false); -$printer -> setJustification(Printer::JUSTIFY_RIGHT); -$printer -> text("Default width\n"); -foreach(array(512, 256, 128, 64) as $width) { - $printer -> setPrintWidth($width); - $printer -> text("page width $width\n"); -} - -/* Printer shutdown */ -$printer -> cut(); -$printer -> close(); - diff --git a/htdocs/includes/mike42/escpos-php/example/pdf417-code.php b/htdocs/includes/mike42/escpos-php/example/pdf417-code.php deleted file mode 100644 index 6735ae6ee4d..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/pdf417-code.php +++ /dev/null @@ -1,95 +0,0 @@ - pdf417Code($testStr); -$printer -> text("Most simple example\n"); -$printer -> feed(); - -// Demo that alignment is the same as text -$printer -> setJustification(Printer::JUSTIFY_CENTER); -$printer -> pdf417Code($testStr, 3, 3, 2); -$printer -> text("Same content, narrow and centred\n"); -$printer -> setJustification(); -$printer -> feed(); - -// Demo of error correction -title($printer, "Error correction\n"); -$ec = array(0.1, 0.5, 1.0, 2.0, 4.0); -foreach ($ec as $level) { - $printer -> pdf417Code($testStr, 3, 3, 0, $level); - $printer -> text("Error correction ratio $level\n"); - $printer -> feed(); -} - -// Change size -title($printer, "Pixel size\n"); -$sizes = array( - 2 => "(minimum)", - 3 => "(default)", - 4 => "", - 8 => "(maximum)"); -foreach ($sizes as $size => $label) { - $printer -> pdf417Code($testStr, $size); - $printer -> text("Module width $size dots $label\n"); - $printer -> feed(); -} - -// Change height -title($printer, "Height multiplier\n"); -$sizes = array( - 2 => "(minimum)", - 3 => "(default)", - 4 => "", - 8 => "(maximum)"); -foreach ($sizes as $size => $label) { - $printer -> pdf417Code($testStr, 3, $size); - $printer -> text("Height multiplier $size $label\n"); - $printer -> feed(); -} - -// Chage data column count -title($printer, "Data column count\n"); -$columnCounts = array( - 0 => "(auto, default)", - 1 => "", - 2 => "", - 3 => "", - 4 => "", - 5 => "", - 30 => "(maximum, doesnt fit!)"); -foreach ($columnCounts as $columnCount => $label) { - $printer -> pdf417Code($testStr, 3, 3, $columnCount); - $printer -> text("Column count $columnCount $label\n"); - $printer -> feed(); -} - -// Change options -title($printer, "Options\n"); -$models = array( - Printer::PDF417_STANDARD => "Standard", - Printer::PDF417_TRUNCATED => "Truncated"); -foreach ($models as $model => $name) { - $printer -> pdf417Code($testStr, 3, 3, 0, 0.10, $model); - $printer -> text("$name\n"); - $printer -> feed(); -} - -// Cut & close -$printer -> cut(); -$printer -> close(); - -function title(Printer $printer, $str) -{ - $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); - $printer -> text($str); - $printer -> selectPrintMode(); -} diff --git a/htdocs/includes/mike42/escpos-php/example/print-from-html.php b/htdocs/includes/mike42/escpos-php/example/print-from-html.php deleted file mode 100644 index 640132e11b0..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/print-from-html.php +++ /dev/null @@ -1,86 +0,0 @@ - 225 below) and printing w/ Escpos::IMG_DOUBLE_WIDTH | Escpos::IMG_DOUBLE_HEIGHT - */ -try { - /* Set up command */ - $source = __DIR__ . "/resources/document.html"; - $width = 550; - $dest = tempnam(sys_get_temp_dir(), 'escpos') . ".png"; - $command = sprintf( - "xvfb-run wkhtmltoimage -n -q --width %s %s %s", - escapeshellarg($width), - escapeshellarg($source), - escapeshellarg($dest) - ); - - /* Test for dependencies */ - foreach (array("xvfb-run", "wkhtmltoimage") as $cmd) { - $testCmd = sprintf("which %s", escapeshellarg($cmd)); - exec($testCmd, $testOut, $testStatus); - if ($testStatus != 0) { - throw new Exception("You require $cmd but it could not be found"); - } - } - - - /* Run wkhtmltoimage */ - $descriptors = array( - 1 => array("pipe", "w"), - 2 => array("pipe", "w"), - ); - $process = proc_open($command, $descriptors, $fd); - if (is_resource($process)) { - /* Read stdout */ - $outputStr = stream_get_contents($fd[1]); - fclose($fd[1]); - /* Read stderr */ - $errorStr = stream_get_contents($fd[2]); - fclose($fd[2]); - /* Finish up */ - $retval = proc_close($process); - if ($retval != 0) { - throw new Exception("Command $cmd failed: $outputStr $errorStr"); - } - } else { - throw new Exception("Command '$cmd' failed to start."); - } - - /* Load up the image */ - try { - $img = EscposImage::load($dest); - } catch (Exception $e) { - unlink($dest); - throw $e; - } - unlink($dest); - - /* Print it */ - $printer -> bitImage($img); // bitImage() seems to allow larger images than graphics() on the TM-T20. bitImageColumnFormat() is another option. - $printer -> cut(); -} catch (Exception $e) { - echo $e -> getMessage(); -} finally { - $printer -> close(); -} diff --git a/htdocs/includes/mike42/escpos-php/example/print-from-pdf.php b/htdocs/includes/mike42/escpos-php/example/print-from-pdf.php deleted file mode 100644 index 23469e8a00f..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/print-from-pdf.php +++ /dev/null @@ -1,78 +0,0 @@ - graphics($page); - } - $printer -> cut(); -} catch (Exception $e) { - /* - * loadPdf() throws exceptions if files or not found, or you don't have the - * imagick extension to read PDF's - */ - echo $e -> getMessage() . "\n"; -} finally { - $printer -> close(); -} - - -/* - * 2: Speed up printing by roughly halving the resolution, and printing double-size. - * This gives a 75% speed increase at the expense of some quality. - * - * Reduce the page width further if necessary: if it extends past the printing area, your prints will be very slow. - */ -$connector = new FilePrintConnector("php://stdout"); -$printer = new Printer($connector); -$pdf = 'resources/document.pdf'; -$pages = ImagickEscposImage::loadPdf($pdf, 260); -foreach ($pages as $page) { - $printer -> graphics($page, Printer::IMG_DOUBLE_HEIGHT | Printer::IMG_DOUBLE_WIDTH); -} -$printer -> cut(); -$printer -> close(); - -/* - * 3: PDF printing still too slow? If you regularly print the same files, serialize & compress your - * EscposImage objects (after printing[1]), instead of throwing them away. - * - * (You can also do this to print logos on computers which don't have an - * image processing library, by preparing a serialized version of your logo on your PC) - * - * [1]After printing, the pixels are loaded and formatted for the print command you used, so even a raspberry pi can print complex PDF's quickly. - */ -$connector = new FilePrintConnector("php://stdout"); -$printer = new Printer($connector); -$pdf = 'resources/document.pdf'; -$ser = 'resources/document.z'; -if (!file_exists($ser)) { - $pages = ImagickEscposImage::loadPdf($pdf); -} else { - $pages = unserialize(gzuncompress(file_get_contents($ser))); -} - -foreach ($pages as $page) { - $printer -> graphics($page); -} -$printer -> cut(); -$printer -> close(); - -if (!file_exists($ser)) { - file_put_contents($ser, gzcompress(serialize($pages))); -} diff --git a/htdocs/includes/mike42/escpos-php/example/qr-code.php b/htdocs/includes/mike42/escpos-php/example/qr-code.php deleted file mode 100644 index f57c2b8270d..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/qr-code.php +++ /dev/null @@ -1,86 +0,0 @@ - qrCode($testStr); -$printer -> text("Most simple example\n"); -$printer -> feed(); - -// Demo that alignment is the same as text -$printer -> setJustification(Printer::JUSTIFY_CENTER); -$printer -> qrCode($testStr); -$printer -> text("Same example, centred\n"); -$printer -> setJustification(); -$printer -> feed(); - -// Demo of numeric data being packed more densly -title($printer, "Data encoding\n"); -$test = array( - "Numeric" => "0123456789012345678901234567890123456789", - "Alphanumeric" => "abcdefghijklmnopqrstuvwxyzabcdefghijklmn", - "Binary" => str_repeat("\0", 40)); -foreach ($test as $type => $data) { - $printer -> qrCode($data); - $printer -> text("$type\n"); - $printer -> feed(); -} - -// Demo of error correction -title($printer, "Error correction\n"); -$ec = array( - Printer::QR_ECLEVEL_L => "L", - Printer::QR_ECLEVEL_M => "M", - Printer::QR_ECLEVEL_Q => "Q", - Printer::QR_ECLEVEL_H => "H"); -foreach ($ec as $level => $name) { - $printer -> qrCode($testStr, $level); - $printer -> text("Error correction $name\n"); - $printer -> feed(); -} - -// Change size -title($printer, "Pixel size\n"); -$sizes = array( - 1 => "(minimum)", - 2 => "", - 3 => "(default)", - 4 => "", - 5 => "", - 10 => "", - 16 => "(maximum)"); -foreach ($sizes as $size => $label) { - $printer -> qrCode($testStr, Printer::QR_ECLEVEL_L, $size); - $printer -> text("Pixel size $size $label\n"); - $printer -> feed(); -} - -// Change model -title($printer, "QR model\n"); -$models = array( - Printer::QR_MODEL_1 => "QR Model 1", - Printer::QR_MODEL_2 => "QR Model 2 (default)", - Printer::QR_MICRO => "Micro QR code\n(not supported on all printers)"); -foreach ($models as $model => $name) { - $printer -> qrCode($testStr, Printer::QR_ECLEVEL_L, 3, $model); - $printer -> text("$name\n"); - $printer -> feed(); -} - -// Cut & close -$printer -> cut(); -$printer -> close(); - -function title(Printer $printer, $str) -{ - $printer -> selectPrintMode(Printer::MODE_DOUBLE_HEIGHT | Printer::MODE_DOUBLE_WIDTH); - $printer -> text($str); - $printer -> selectPrintMode(); -} diff --git a/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.html b/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.html deleted file mode 100644 index c3d307a94d1..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - RawBT Integration Demo - - - - - - - -black & white picture -

RawBT Integration Demo

-
-
-    window.location.href = ajax_backend_data;
-
-
-
- - -

Visit RawBT site

- - diff --git a/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.php b/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.php deleted file mode 100644 index 45a4e8fcde2..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/rawbt-receipt.php +++ /dev/null @@ -1,145 +0,0 @@ -getSupportsGraphics()) { - $printer->graphics($logo); - } - if ($profile->getSupportsBitImageRaster() && !$profile->getSupportsGraphics()) { - $printer->bitImage($logo); - } - - /* Name of shop */ - $printer->setJustification(Printer::JUSTIFY_CENTER); - $printer->selectPrintMode(Printer::MODE_DOUBLE_WIDTH); - $printer->text("ExampleMart Ltd.\n"); - $printer->selectPrintMode(); - $printer->text("Shop No. 42.\n"); - $printer->feed(); - - - /* Title of receipt */ - $printer->setEmphasis(true); - $printer->text("SALES INVOICE\n"); - $printer->setEmphasis(false); - - /* Items */ - $printer->setJustification(Printer::JUSTIFY_LEFT); - $printer->setEmphasis(true); - $printer->text(new item('', '$')); - $printer->setEmphasis(false); - foreach ($items as $item) { - $printer->text($item->getAsString(32)); // for 58mm Font A - } - $printer->setEmphasis(true); - $printer->text($subtotal->getAsString(32)); - $printer->setEmphasis(false); - $printer->feed(); - - /* Tax and total */ - $printer->text($tax->getAsString(32)); - $printer->selectPrintMode(Printer::MODE_DOUBLE_WIDTH); - $printer->text($total->getAsString(32)); - $printer->selectPrintMode(); - - /* Footer */ - $printer->feed(2); - $printer->setJustification(Printer::JUSTIFY_CENTER); - $printer->text("Thank you for shopping\n"); - $printer->text("at ExampleMart\n"); - $printer->text("For trading hours,\n"); - $printer->text("please visit example.com\n"); - $printer->feed(2); - $printer->text($date . "\n"); - - /* Barcode Default look */ - - $printer->barcode("ABC", Printer::BARCODE_CODE39); - $printer->feed(); - $printer->feed(); - - -// Demo that alignment QRcode is the same as text - $printer2 = new Printer($connector); // dirty printer profile hack !! - $printer2->setJustification(Printer::JUSTIFY_CENTER); - $printer2->qrCode("https://rawbt.ru/mike42", Printer::QR_ECLEVEL_M, 8); - $printer2->text("rawbt.ru/mike42\n"); - $printer2->setJustification(); - $printer2->feed(); - - - /* Cut the receipt and open the cash drawer */ - $printer->cut(); - $printer->pulse(); - -} catch (Exception $e) { - echo $e->getMessage(); -} finally { - $printer->close(); -} - -/* A wrapper to do organise item names & prices into columns */ - -class item -{ - private $name; - private $price; - private $dollarSign; - - public function __construct($name = '', $price = '', $dollarSign = false) - { - $this->name = $name; - $this->price = $price; - $this->dollarSign = $dollarSign; - } - - public function getAsString($width = 48) - { - $rightCols = 10; - $leftCols = $width - $rightCols; - if ($this->dollarSign) { - $leftCols = $leftCols / 2 - $rightCols / 2; - } - $left = str_pad($this->name, $leftCols); - - $sign = ($this->dollarSign ? '$ ' : ''); - $right = str_pad($sign . $this->price, $rightCols, ' ', STR_PAD_LEFT); - return "$left$right\n"; - } - - public function __toString() - { - return $this->getAsString(); - } - -} diff --git a/htdocs/includes/mike42/escpos-php/example/receipt-with-logo.php b/htdocs/includes/mike42/escpos-php/example/receipt-with-logo.php deleted file mode 100644 index b094e9f2b2a..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/receipt-with-logo.php +++ /dev/null @@ -1,104 +0,0 @@ - setJustification(Printer::JUSTIFY_CENTER); -$printer -> graphics($logo); - -/* Name of shop */ -$printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH); -$printer -> text("ExampleMart Ltd.\n"); -$printer -> selectPrintMode(); -$printer -> text("Shop No. 42.\n"); -$printer -> feed(); - -/* Title of receipt */ -$printer -> setEmphasis(true); -$printer -> text("SALES INVOICE\n"); -$printer -> setEmphasis(false); - -/* Items */ -$printer -> setJustification(Printer::JUSTIFY_LEFT); -$printer -> setEmphasis(true); -$printer -> text(new item('', '$')); -$printer -> setEmphasis(false); -foreach ($items as $item) { - $printer -> text($item); -} -$printer -> setEmphasis(true); -$printer -> text($subtotal); -$printer -> setEmphasis(false); -$printer -> feed(); - -/* Tax and total */ -$printer -> text($tax); -$printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH); -$printer -> text($total); -$printer -> selectPrintMode(); - -/* Footer */ -$printer -> feed(2); -$printer -> setJustification(Printer::JUSTIFY_CENTER); -$printer -> text("Thank you for shopping at ExampleMart\n"); -$printer -> text("For trading hours, please visit example.com\n"); -$printer -> feed(2); -$printer -> text($date . "\n"); - -/* Cut the receipt and open the cash drawer */ -$printer -> cut(); -$printer -> pulse(); - -$printer -> close(); - -/* A wrapper to do organise item names & prices into columns */ -class item -{ - private $name; - private $price; - private $dollarSign; - - public function __construct($name = '', $price = '', $dollarSign = false) - { - $this -> name = $name; - $this -> price = $price; - $this -> dollarSign = $dollarSign; - } - - public function __toString() - { - $rightCols = 10; - $leftCols = 38; - if ($this -> dollarSign) { - $leftCols = $leftCols / 2 - $rightCols / 2; - } - $left = str_pad($this -> name, $leftCols) ; - - $sign = ($this -> dollarSign ? '$ ' : ''); - $right = str_pad($sign . $this -> price, $rightCols, ' ', STR_PAD_LEFT); - return "$left$right\n"; - } -} diff --git a/htdocs/includes/mike42/escpos-php/example/resources/character-encoding-test-strings.inc b/htdocs/includes/mike42/escpos-php/example/resources/character-encoding-test-strings.inc deleted file mode 100644 index 000b3bd59a2..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/resources/character-encoding-test-strings.inc +++ /dev/null @@ -1,35 +0,0 @@ - "Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther spillede på xylofon.\n", - "German" => "Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.\n", - "Greek" => "Ξεσκεπάζω την ψυχοφθόρα βδελυγμία\n", - "English" => "The quick brown fox jumps over the lazy dog.\n", - "Spanish" => "El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.\n", - "French" => "Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en canoë au delà des îles, près du mälström où brûlent les novæ.\n", - "Irish Gaelic" => "D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh.\n", - "Hungarian" => "Árvíztűrő tükörfúrógép.\n", - "Icelandic" => "Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa.\n", - "Latvian" => "Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus.\n", - "Polish" => "Pchnąć w tę łódź jeża lub ośm skrzyń fig.\n", - "Russian" => "В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!\n", - "Turkish" => "Pijamalı hasta, yağız şoföre çabucak güvendi.\n", - "Japanese (Katakana half-width)" => implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウイノオクヤマ ケフコエテ アサキユメミシ エヒモセスン")) . "\n", - "Vietnamese" => "Tiếng Việt, còn gọi tiếng Việt Nam hay Việt ngữ, là ngôn ngữ của người Việt (người Kinh) và là ngôn ngữ chính thức tại Việt Nam.\n" - ); - -/* - * These strings are not expected to print correctly, if at all, even on an Epson printer. This is due to a mix of - * escpos driver, printer, and PHP language support issues. - * - * They are included here as a collection of things not yet implemented. - */ -$inputsNotOk = array( - "Thai (No character encoder available)" => "นายสังฆภัณฑ์ เฮงพิทักษ์ฝั่ง ผู้เฒ่าซึ่งมีอาชีพเป็นฅนขายฃวด ถูกตำรวจปฏิบัติการจับฟ้องศาล ฐานลักนาฬิกาคุณหญิงฉัตรชฎา ฌานสมาธิ\n", - "Japanese (Hiragana)" => implode("\n", array("いろはにほへとちりぬるを", " わかよたれそつねならむ", "うゐのおくやまけふこえて", "あさきゆめみしゑひもせす")) . "\n", - "Japanese (Katakana full-width)" => implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン")) . "\n", - "Arabic (RTL not supported, encoding issues)" => "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ" . "\n", - "Hebrew (RTL not supported, line break issues)" => "דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה" . "\n" - ); diff --git a/htdocs/includes/mike42/escpos-php/example/resources/document.html b/htdocs/includes/mike42/escpos-php/example/resources/document.html deleted file mode 100644 index bb413aa1d3d..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/resources/document.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - -

- - This is a simple document. For receipts involving complex formatting, - non-monospace fonts, advanced character encodings, or vector graphics, - you can always create and render HTML instead. -

-

- The printing will be a lot slower, but you have full access to things like unicode and SVG. -

-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do - eiusmod tempor incididunt ut labore et dolore magna aliqua.

-

Ut enim ad minim veniam, quis nostrud exercitation ullamco - laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor - in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla - pariatur.

-

Excepteur sint occaecat cupidatat non proident, sunt in culpa - qui officia deserunt mollit anim id est laborum.

- - diff --git a/htdocs/includes/mike42/escpos-php/example/resources/document.odt b/htdocs/includes/mike42/escpos-php/example/resources/document.odt deleted file mode 100644 index 4bbd7f98b654dd1f8086589f22bfb9ed7ecb4c9a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39751 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%0DXC4u*ZB5o$LxKAV8c6QUjWTfwW z?LKEk&ks{KUHSrY^YP{6$Zol0uH%^GpI>B&s zgB!I-pTCXf56q5lT5sUsf3D>)IJ?EzDpfLeq-@2KoSp=Kkkg(LIU>bwBsiT;zT*A!nGPS%od zo4U|m34wv+RmlTYrpj^9r=laX|N4?Qrb1U-h$2HvSOP4u>i)rLO$o6`ULsC zBE`Ig$8ElBDVgOzkNeBP(PqG%`Rg!H^XVB`u8{c6GLJqhJ~Ku4l!c^@ayEUR)M3ux zNqE5;1+#)*wn%bL`U9@3PWqj8wQ3I{N_7T81k6(&&=fh2E}T)gar1TG2C4i9Q9+d^ z_?Vg2yLzrIk8H(weY=d$4v&!j-)UeW|FF$j7I0Jy-wQ@p{vx(y%N6>N;=TNMQAuF6 zj;M}~%RaFs>J_uc8y^znA#WW1GaPc*xiU*Avn0#7{7+%BnZitMI^Ii&^i=L4ValD# zDUYo7P?-D+=OLNmRN#t6pb3ZEPW8n!wP+eURg7NCD@%Pcg@iXrC+| z;NK$IlyaM{INdq7F0`oXx%JYYwIb#t=XAoz4?~>%9Of4-B4O^Dex#7p66@lq*oAjm zI0y&5G5Q*G#4-Sm?#&*93EEgF81)KKDq2N76H-cZJUTsC3#cdU~PGy}S$>?8bQ zQzGUCGY=d3zas)s??Gp{9TYGd?k4+H5eZN;vXUDf*}i!hn&0JqonHsG#8)}h2WoCG zFH5qmd25d@(VgHmQTZJ9=n|)zOp`Ntto-g}lM;%FdXt$>+)5g;QJXhJNsBNm=zNo{ zOV1OB>kT6$S6cHIQ?E6XG%t@uX{nY7pGbjMDq&6(9(^l1+ESZ0@F$xYx=#~IVVz&` zuB2?1=tN3;7JnV_9r~tbYf(&y<2BINlS})K1Pr&MDJ%^8V$f^K@(7rhwb8vbq+opv z7%j|q)|(tmIj?&LAQjCh3RogCnPIuH5hZ#1eU^qo*+;a`6kwklQaUKh{`zcj^qme@w@BbfrxLn@~33i{b-$ z+uP9$_`^Z+dlqgb0o>tk{qYY+Mt6&{4re5Olp}{E%)GlHcr{cl>U*^%tZf5BQ`(;P zd;XIV&cn8=KG`&8FnPC_U0^v5->UGsA2Y}Ye@?kP_UfeH2MzzHEb?MYBK0FM zSy_-CdPzZDMib?c{rE5qvBL<6{8?ABU0{s%a6tD*uBsx~dk;u5E@5~?tm4RhW}1cO zpgkJsP=YCuj3c*?Ah!nvYl;O{%fc>i{UNDB%$1xg84`0<(k7yng-^=YgnuDsvrngt zKPX+Jfux;@K?EJ+FCfcs@eZ^=#+U5+AWMBBeEp*2?Q59CL)m+X9q~FuWXwByScpsb zJ#n+!Sc{J!BNtA+porLnMAICU za$aOuZqbhcyh@>|&ry#7luF7lw`PQKVHrZ2hgLiTX%(jav1ImN)`zKpGVFSC9S&6t4)jQ^g5CMY+T2-@$82NIWZi;ctY6Erq9!NdQJ+%Bn*{GB z%-brin8JVo{r~s%kpI16%l8;kEYGV12)7}k8Eh~h2!QBXL_b){-747Fi&vNL%n%6m*C(qP_vn|rP09}wV#hY zH>E4*G+c1qSZe$8!ct^&ei^8RU2VL~JA z&Jyu08DwhG3Gb)a(HXubNLhs2O{|vdhgvIJ3G`A^;CMe9W1Mv>gE@U- zam|uYvmoM>h^hhj-al*F#8MdW<(@C)VaBTwx8ARLO1q0qy_KyjNt;qO89&CPv$0_} zCZeSS{tt7UjY|e%e`3~nKQ+;?RrK%@CEJMSD1Y9VwaF-#9%!=pM(wD?{YAdzrtbf2 zt<8l04Z{a>L0d@+_E2XGr@T3Q`mDg}RWIv19UlwL%mdw)74HGk^o@Php?Lai_NSz6 z9hvBYAu?UI!8c2ZFSZZV+jGGoX8tap;&p{gn97jgU-A50UyghgSjEMJ$rD2_DUDP{ z6KA*Ms7Gdgxn;BRTyt;6iAG1s9D2kovKuKTvVE5O+9|Ot=ZG^lQ&v`57PCoXcO7X& zWhHC(Sq`pKQ*$4^Pj))3Ejit_Q_B`;p*JhbD=lk%saHQj?-TW>B%)xnaBWsUK=0G3 zOIJ)zKXi?=pCb3K(Wf?`V5D>{v!5pKm3^c6Nx?Yenq)sp-mB}FlAoMT#;de^h;Bsw z_p{SyxuV!~4aG+e8xy~sLn&OlUP22wM00z^R-CZ}2VdFY{mqsGS5?2817UNE_=hFe z@KSkqf==oR-P3)6&p8k2u6By8T%$wtlY{MvIc03pFI1hX(el1g`t*9PgHB0yWrKsb zV`)va(!OPz3{wie?43Lnx=XG#EgV-iz+oIj)+c=}jT1Dq8nxvgsnM>}^vL-ls@bX! z{>^oMR;y#DBSKF>Sz$4yOK;J#gdnPWq-+PyrH4`U)jUGQO`Dd}WC>Pq4Fj5^ zEdcZ1R*hk~Moc3LEpv?;S;yr0{SOhVR>uw$XFMI51UBkg|3OE$jX)5&HHZl7TgAW~uyKH#a zHJ^W$=i!g(*6iO7K5)4vEQar{44cgF6E(8@$kqlr zrd${4zDIvhF4N|^gkS}>?W9ZwZ`NY>+74R$>(jT|q`!WV9#Mpt`Z|nu%@*K~;AL2D z#?03AvC7&jT3*h?R!yl^gu(XoQ}Zg!KB;MVyVi7FZo5~?LQVNLgu#erV4*7)SF_v^ zsH^+n&?pvH zdtefNWvIHW`*F#ZEaK8f8QgqU&KPG|V}&;^_t|#H`i@Q9o3CRU(>!WQ6CJ#@k4Ee! zw~4q5i$~CFt$3tN?7rmMylmMikP8+vTdhHpu~Cbi0zP!+ z;Qm&PHL9J{YRVLR^T4`ipfm3pKc&m*>dB+WXpWQ;GE$S$g-Re-J9~=04%Kz#s0@Bj z_aJLhjz=637PTsLQU@=QHOVU?jR;F~7iu{#umQ)$nU)ubkRPRHr;w}p8W=A?tX{)p z2hM2xWzU)SGsu+~q1q!v9q=dVWT;(YxQEqs^VDCC9@8vvAypn`6m4Zni6c{`Z&NnIX)&W=kv$ITULp$6>cLYA{b%yX4ZZD6hcLAEMnVMIQ(;S9_99|G^q$HG-uKpT8-EdSmgKPWBd%CtqUu%Sumj7^BNQ4agH=0KG)F9I zdK7#KF5qig`4np=8N(xWGbVl?OFExqypYF%0{sOL!J;U?|1gsx7{OA@AsN0{BDIj##g7O^!tI^ z>H`Mx!7ka-hWyY~Xx4>DjbM(13wzdN2Wv_+Yeo@by#@bLLvi1o2*w>G5B5$#aZzmPar`T z@u7l2Pd8k_$|(_=pdRlb>t}aGFv#apY)coy-6Wa!wi7smMz^Pm0=VsfW1W7_s=XH7 zm7Fc(^vu5Z&E?dyplP=COY%Z@r#*mO$gg*^h4H{0{O0%~5I;uVi<{7lCz@H{@YM}@ zUR`Tx=47Z#03APyCh8(rjAYBI7%z+l*MK+6;4yN9Y>#bdAxq_Kxa=uFDE(PqyX`+jqY7N)^uWqeRRts?Cs#2lPL`1gPZPMIo^b~ z+8q_4Y5Lww*0V9&x8X^F(|6Q+3nI)+(Y-kF3YzHR|M#bC9sQ;NrPU zYP*X&IXD1}YLK|Ag^9a`IjN_OyEUowX9Z=gAQW6+Bg%gpnFCFHX8+j&1Yppdj4bSo ztQ_jBTzs6|d~B@rtgL)2EGS#17yrWt9GuK;EWQ8h4+Mm)s{$YR-(Z&`09(1ad)r(5 zhemg<_cLLm13lo6k;$>MUkc;e7HZd;AeL6CAZaI#!o{PAT0k}!pA zdiS^^mo;urg#IL+Yk1!yne=2=LA<1pcc~bg;TFsl2Le@#yw~{nxxwYe(cfPVmkX~2 zTUQKb@CFqEYq%}yMd}r~#O1|ygFDUH4Vx_Qttx^EhZUs^`xguHuNqSl*ihMtsk$p8O^F!edFe?m zg7Z|De7N`tQ5Jrfjt_mosn@K@DqlvR<}_->?L3rC!JDE*NNM)MpCNP-#m1{4xqhNc zdo~pxvbK&Sv(ijU*q9@}>L3cFT0>`D=jL$R=#Fvk_QtIeZYQE(JA83_t=Dc>?!X2DQX*@`tp z8A=+J1W)h{XS-`I+05n+BJL%1=?LY$#NT9)xP&uhqm6sleEYA02JrbAm+@;ixQF zx)=_iLe8pKvwVa9uga|hs;O*?h7ynxr6WjFKu}7g2?R1!=}K=ZC4-b`5?VqNMT&qR zNC$zT7eVPDNEHN?UR4z7U}(~dAjnTb(*)bPqvdtxcqN32)3m$J1=4P}@~*c$6UUm(9ixa)O?oXLf#%2T zj>M&`Cln~yXzG;(bwhm&Sup}`l)cWhxffe=Odje9hPd@_NRCILA&RL)b)(VB1t*NE zY*cGHT}omZEcv^0FIQlgc-Koa`*b`=ZF|towE$?6vBrbRjF0opO#XH`PS@va zd0lbVv&Ks&!b1dF!A9M;lT&CBO*j75_6s#hU1$2Rq%3qTXU#xEAn=YSNtmI@Xsol@ zXu=Z6m=gR{XM0>aqV2+IqJV(i1@)o4yfWI=?vy@Nk_gV%>VHIgl8FW%6^k`7-;En; zhqa!*Uk3r1PRD%Rv~?|S=-PbWop6zQvSDcO>ZKb-(YjifhU49J#^bF_u&1Nb-d?1U zqpiM0M8sR%(%ek-@SgT*7F;+JVLVtU+L$F@I5)2atE zbmoNVu9rm6uyg*v*05M$-O=Te7-iSzIj?!eE@n@zLM}_hLNU4WgQTkgAstDHHSrzT z!DeErd*r#m@`=+uX4wOIoaC?D^s1vev^r&)&>t7F@W zV(JOS{baaWBm-N%Guf4m4mth%)xa`M)jKUO&?4!Io&G+5;R zWLa$)+Jp*VLDOfFdw|HV> zrgwm!qp>dt5SbH3Gd_c)9b! zhix_wHk<42XUoEa0m)KnkupyWs07|5qC@dNPuUFTTNlZ7SMy&G+%kz@tfS)TG#y;! znf6-OW8o9ehra|)&^+$mo_Y1@g0H&}^Ykw9F48c$dl2OsHBv>iWA#aCgiPjsOy4Gg z*kv(wPHZ(dT6lo2LjrkfUbay%m8;l1Z77tzFGM@VN%|%lCAa>9wj$mOT?`3#9`u-aI>v zJ&P=|c~q8?>2lw6cNNhUS7eoEx?6X&a+d^eTl9kTd0{9305frdZSiNVfJhh$Ze#6? z7IwO3(;nH5@;yi6w;+4hx}#qn3-O^{9MA{1PES^ryHsbjWp8D$el^<8_!n} z8xAc^_zYuv9bEjV-ay>y3~!5?UD>n%q)PZ%<^beF|5E|Zc=o01zM08qD_v1%r7dFa z3Q1BUI!n^{-QrhdwX09nzmalOqkdT$dW3=_L=nC=;mIo9F-Boytc#va33K1zf(8#l za#D&ZVNdmH0-kb(d&`GVXtnsEec386X*P+)tmsPDr+yxLWm(hfnyvf#tDXo+oPOC!4CEg7zf;K zItKiYkN8({&S)4K3`sGuFW6D!w>cQD73vj;`dQD2z%VW3&I&5wxDqK=^xGz zW@TlKu*L~w?*z8OI63{>6iV`UKPg^HV*Cd#eorv`6dYhEYsCK$j19;7!v%7(x5c@1 z|Buw1halldm@UrUs|ZIUVGhp!4ttmij5zSc3kC{8>X%f&|J`3W(|DOdE9wOoP4$L= zV19Ick-?ebG3C63q?>ATcSg#5NrRiXgLZ5CuX7kipEc4Ko-1x`D-;woBF~F}n(%>Q zuBnJc04Vh}5t_?I?wZ(ZWu7K>p~XblV4S1m*3>1Gx=&Ms1D~1qRbPQ>el2p76SU$f z;94v*cW-kQO<3fllGCRf89w6k$$Jo4t=VkXfc;6n*91$Ms%* zKLxocF7r2x{;5)kBiap^ky~?ouCA7#q+#||GfGZDsq?L4uS*ZWYbkfTVv-NPRh5BrL^`;w%7(K@>u3@YGXNL>giUAuQj{9MB=K*&dH-M_ z;Ye$=yMy)js7hBKvr-cP0RP5sxxK)-uK@;j804QQ7#!gYMiUP4j&1@AVL|Ngl*V_L z?S-W2!3ON_k^4K=@SW6q5syRe>#P1AxW9|x;E-CD2ix1eNA7pI9~8>b1^~dx^moq# z0Y#Aadk6g9i3Z!@F2?Wp;R)0P_4d~<{3C_Ehz{8QfZ==G{=|Jy0>yCLME2D>0+KM9 zy%7Kad}7}V?}$UP$i6gxaLw)EzUO&%2+#hs|8t&$t8nQMp1m^gt1NtxKhA2eEc_~q z*&!@@W#S(e!ZpP!L&){`9k~~ghp_ylZ2bCVn>mDZf6@5)6!B$aFHS}MD3rs2BJy)4 wd>Pq`tA{ZCP*e_Twm-Y!%gSCn#E~6ZWOOuvxOP_nfFAb(;*z3Z4F21H09cWxT>t<8 diff --git a/htdocs/includes/mike42/escpos-php/example/resources/document.pdf b/htdocs/includes/mike42/escpos-php/example/resources/document.pdf deleted file mode 100644 index 93a702337f1b09cfcb96ddce75a0c6421b69251e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24389 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 diff --git a/htdocs/includes/mike42/escpos-php/example/resources/escpos-php-small.png b/htdocs/includes/mike42/escpos-php/example/resources/escpos-php-small.png deleted file mode 100644 index 3c74d2d57a29e0398f706efd0e2f4531c036584a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1941 zcmV;G2Wt3004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 zVoOIv0063uBQgL0010qNS#tmY3ljhU3ljkVnw%H_00wqRL_t(o!|j=SP?Xmh#(&>l zSaz3-7a$0t#I+JdEt*SdVzto;>J%@jY1LGl#3|#nbtcX8MGaPGe0QlGv(= zv6I%pF&Y)r*2Y2{gP101yfEOUTx>vVKtW`e{ht282Q2JjVw)++4A0D-J?Gu$yyw~X zob#Tu-@*XC05Gg~FH?!>Hx;$KgV`-6+t`~hD7s&iG;#GPxm*Q@WpPDCueVP{{UD}* z4bj-3TMP!N`1&O>33SH5)@|&MsPr7y_CI*}%rPKlK+NY@7_45h{Pl*Tx1p6kP(mEb8BZyH>(g5GH_9Bw zu%^NU+EK6J!^BLd7?TQuOkph<WCW9Kb?&t8UeAG6p+8i(*Pj$abX zbl#(xS$qTd7&wTJ*U2EA06}Zv3meCIkz)*E!p+6xa)T0LSjaFIvxjrcV=0MjpcoI& zk&ekks!8SvMzWd_lrn-R$zTyXC?uOD*ezcM6RBhj%NWK(qyawi7>dbQt`Nm<853zU zGcCHgSe-D{jbJZpi|*AEQbb12`oA?n>lBWF=4ffiC~L(#42l?;j&BrcyBSs}XZO1I z*!rlun8Wx8-fi5Er`ITbOw%VJid7NZM1q$!5t%kt_R-^(#oWpX(ihXXMSj0vKulkV zux6U5U@}*!AcJyTjOATiWKu;2XBkZ;6R~lWcJ8DKA17($F3vHE(_G`L#BdxRHKcK# z%iK*Z!%5=rB=axoxRXm%lSLEpr1c>xB+s1Cd|lJq%2A0@HAzKEQl^SDU4PSDl_*y= zs@Hg>sZ{fIM0Y7!NAyj-r70Ssay97z73pCeP_Dcx(sy-0(xWQW5=Ci;@)V_QTB%pU z@=Szj>bR?PByK+eO#JvU30Ss{dq|+G9l(!h$Fyo#ER%Npn6z6bQD-}7m1fw;pRi^O ztNe7CC4AF%_xv;-K35BPK+J%c&qR#6N`;g?84CG<(#=qhPs3TE%06hFBbUaNs2tI|g2>?I8{aZXAFcCxc1GO+2^ZCJs;7$er7N zTJ*j*yfXo4riL+Gra59ogoTO972|5@ZZ@q;j4%?%*QBsOCDExH&@# zmq_9wP29m{5*b7#L%2Z`!)d0GR9cDdNV}}#r)A8fv0GG+Yv=zLH$4ve4+CPpXku(! zU^guQnEaJ8%YKDj)LZrUIBXsLZS3c)Wv%8-S^*FxUHzKa-PP|T2dxJx0g5?eSue7O zmI(2f=4sxj8FDLMEi$!DiMm}yk}m5pxwJral1epBiF!?@+VreqG)-qDozqNt^^~ql zDpZO_>(7!J^+UO}NFPZ$u1OlKO$sWYjf&S-^ns*W&6ivG`bpPr>JsBx>n zo0J%&kb}4DbuE*XPg|3`~WAjZRg`f z8CiH(@A10>Y#@eA-j0`1!#tw-5iOkPDP|O#nF>G@kMkUf0HpIWOR)h4^V!Te0ODB7 zYAc&hW-B=WI9Sea7zRKp1>{*r&1_yF3ji-aV-2wYjAtuz0C2K`U(oA6l%&87Zp#T5?8FWQhbVF}#ZDnqB07G(R zVRU6=Aa`kWXdp*PO;A^X4i^9b03~!qSaf7zbY(hYa%Ew3WdJfTF*PkPGc7SRR5CI; zH8DChGb=GMIxsLILPgX7001R)MObuXVRU6WZEs|0W_bWIFflbPFf%PNG*mJ$Ix;mn bG%zbMF*-0X?$PJj00000NkvXXu0mjfgfCmX diff --git a/htdocs/includes/mike42/escpos-php/example/resources/escpos-php.png b/htdocs/includes/mike42/escpos-php/example/resources/escpos-php.png deleted file mode 100644 index feee2d71cc280655b1765f2689bbed8299ba394e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7871 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 Q9{>OV07*qoM6N<$g5qCe^8f$< diff --git a/htdocs/includes/mike42/escpos-php/example/resources/tulips.png b/htdocs/includes/mike42/escpos-php/example/resources/tulips.png deleted file mode 100644 index a0e681cf0ffa7498bfff6e26d71b15f82a8bc7f6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 379443 zcmV)RK(oJzP)004R=004l4008;_004mL004C`008P>0026e000+nl3&F}00006 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
;pHdyGure7GxRzfSq-{YSt0 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 L(g0N{n1A^n;lIUB diff --git a/htdocs/includes/mike42/escpos-php/example/resources/tux.png b/htdocs/includes/mike42/escpos-php/example/resources/tux.png deleted file mode 100644 index e32f8d945345480f7bdd85354b48bbd84dcb4f0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5198 zcmV-U6tU}xP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00002 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 diff --git a/htdocs/includes/mike42/escpos-php/example/specific/123-code128-barcode.php b/htdocs/includes/mike42/escpos-php/example/specific/123-code128-barcode.php deleted file mode 100644 index b87e44981e0..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/123-code128-barcode.php +++ /dev/null @@ -1,21 +0,0 @@ - setJustification(Printer::JUSTIFY_CENTER); -$printer -> setBarcodeHeight(48); -$printer->setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW); -foreach(array($a, $b, $c) as $item) { - $printer -> barcode($item, Printer::BARCODE_CODE128); - $printer -> feed(1); -} -$printer -> cut(); -$printer -> close(); - diff --git a/htdocs/includes/mike42/escpos-php/example/specific/141-custom-command.php b/htdocs/includes/mike42/escpos-php/example/specific/141-custom-command.php deleted file mode 100644 index 6e3bed70d0b..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/141-custom-command.php +++ /dev/null @@ -1,55 +0,0 @@ -getPrintConnector()->write($barcodeCommand); -$printer->cut(); -$printer->close(); - -/** - * Generate two characters for a number: In lower and higher parts, or more parts as needed. - * - * @param int $input - * Input number - * @param int $length - * The number of bytes to output (1 - 4). - */ -function intLowHigh($input, $length) -{ - $outp = ""; - for ($i = 0; $i < $length; $i ++) { - $outp .= chr($input % 256); - $input = (int) ($input / 256); - } - return $outp; -} -?> \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/example/specific/148-data-uri.php b/htdocs/includes/mike42/escpos-php/example/specific/148-data-uri.php deleted file mode 100644 index 74759146712..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/148-data-uri.php +++ /dev/null @@ -1,35 +0,0 @@ - setResourceLimit(6, 1); // Prevent libgomp1 segfaults, grumble grumble. -$imagick -> readImageBlob($imageBlob, "input.png"); - -// Load Imagick straight into an EscposImage object -$im = new ImagickEscposImage(); -$im -> readImageFromImagick($imagick); - -// Do a test print to make sure that this EscposImage object has the right data -// (should see a tiny bullet point) -$connector = new FilePrintConnector("php://output"); -$printer = new Printer($connector); -$printer -> bitImage($im); -$printer -> cut(); -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/235-get-data.php b/htdocs/includes/mike42/escpos-php/example/specific/235-get-data.php deleted file mode 100644 index c3607c868b3..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/235-get-data.php +++ /dev/null @@ -1,28 +0,0 @@ - text("Hello world!\n"); -$printer -> cut(); - -// Get the data out as a string -$data = $connector -> getData(); - -// Return it, check the manual for specifics. -header('Content-type: application/octet-stream'); -header('Content-Length: '.strlen($data)); -echo $data; - -// Close the printer when done. -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/29-latvian-star-tup592.php b/htdocs/includes/mike42/escpos-php/example/specific/29-latvian-star-tup592.php deleted file mode 100644 index 73613100abb..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/29-latvian-star-tup592.php +++ /dev/null @@ -1,25 +0,0 @@ - text("Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus\n"); -$printer -> cut(); -$printer -> close(); - -/* Option 2: Image-based output (formatting not available using this output) */ -$buffer = new ImagePrintBuffer(); -$connector = new FilePrintConnector("php://stdout"); -$printer = new Printer($connector, $profile); -$printer -> setPrintBuffer($buffer); -$printer -> text("Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus\n"); -$printer -> cut(); -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/32-german-tm-t20-ii-custom-command.php b/htdocs/includes/mike42/escpos-php/example/specific/32-german-tm-t20-ii-custom-command.php deleted file mode 100644 index 29b6b3fc638..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/32-german-tm-t20-ii-custom-command.php +++ /dev/null @@ -1,39 +0,0 @@ - getPrintConnector() -> write($cmd); -$printer -> text("Beispieltext in Deutsch\n"); -$printer -> cut(); -$printer -> close(); -/* - * Hex-dump of output confirms that ESC V 1 being sent: - * - * 0000000 033 @ 033 V 001 B e i s p i e l t e x - * 0000010 t i n D e u t s c h \n 035 V A - * 0000020 003 - */ diff --git a/htdocs/includes/mike42/escpos-php/example/specific/33-spanish-seypos-prp-300.php b/htdocs/includes/mike42/escpos-php/example/specific/33-spanish-seypos-prp-300.php deleted file mode 100644 index 90bdc63fb5c..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/33-spanish-seypos-prp-300.php +++ /dev/null @@ -1,19 +0,0 @@ - text("El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.\n"); -$printer -> cut(); -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/37-chinese.php b/htdocs/includes/mike42/escpos-php/example/specific/37-chinese.php deleted file mode 100644 index d14790f47d5..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/37-chinese.php +++ /dev/null @@ -1,24 +0,0 @@ - textChinese("艾德蒙 AOC E2450SWH 23.6吋 LED液晶寬螢幕特價$ 19900\n\n"); - -// Note that on the printer tested (ZJ5890), the font only contained simplified characters. -$printer -> textChinese("示例文本打印机!\n\n"); -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/39-currency-symbols.php b/htdocs/includes/mike42/escpos-php/example/specific/39-currency-symbols.php deleted file mode 100644 index b960ee681c3..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/39-currency-symbols.php +++ /dev/null @@ -1,77 +0,0 @@ - text("€ 9,95\n"); -$printer -> text("£ 9.95\n"); -$printer -> text("$ 9.95\n"); -$printer -> text("¥ 9.95\n"); -$printer -> cut(); -$printer -> close(); - -/* Option 2: Image-based output (formatting not available using this output). */ -$buffer = new ImagePrintBuffer(); -$connector = new FilePrintConnector("php://stdout"); -$printer = new Printer($connector, $profile); -$printer -> setPrintBuffer($buffer); -$printer -> text("€ 9,95\n"); -$printer -> text("£ 9.95\n"); -$printer -> text("$ 9.95\n"); -$printer -> text("¥ 9.95\n"); -$printer -> cut(); -$printer -> close(); - -/* - Option 3: If the printer is configured to print in a specific code - page, you can set up a CapabilityProfile which either references its - iconv encoding name, or includes all of the available characters. - - Here, we make use of CP858 for its inclusion of currency symbols which - are not available in CP437. CP858 has good printer support, but is not - included in all iconv builds. -*/ -class CustomCapabilityProfile extends CapabilityProfile -{ - function getCustomCodePages() - { - /* - * Example to print in a specific, user-defined character set - * on a printer which has been configured to use i - */ - return array( - 'CP858' => "ÇüéâäàåçêëèïîìÄÅ" . - "ÉæÆôöòûùÿÖÜø£Ø×ƒ" . - "áíóúñѪº¿®¬½¼¡«»" . - "░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐" . - "└┴┬├─┼ãÃ╚╔╩╦╠═╬¤" . - "ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀" . - "ÓßÔÒõÕµþÞÚÛÙýݯ´" . - " ±‗¾¶§÷¸°¨·¹³²■ "); - } - - function getSupportedCodePages() - { - return array( - 0 => 'custom:CP858'); - } -} - -$connector = new FilePrintConnector("php://stdout"); -$profile = CustomCapabilityProfile::getInstance(); -$printer = new Printer($connector, $profile); -$printer -> text("€ 9,95\n"); -$printer -> text("£ 9.95\n"); -$printer -> text("$ 9.95\n"); -$printer -> text("¥ 9.95\n"); - -$printer -> cut(); -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/44-pound-symbol-star-tsp650.php b/htdocs/includes/mike42/escpos-php/example/specific/44-pound-symbol-star-tsp650.php deleted file mode 100644 index 3e7e6a2e48b..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/44-pound-symbol-star-tsp650.php +++ /dev/null @@ -1,35 +0,0 @@ - textRaw("\x9C"); // based on position in CP437 -$printer -> text(" 1.95\n"); - -// B) Manually encoded UTF8 pound symbol. Tests that the driver correctly -// encodes this as CP437. -$printer -> text(base64_decode("wqM=") . " 2.95\n"); - -// C) Pasted in file. Tests that your files are being saved as UTF-8, which -// escpos-php is able to convert automatically to a mix of code pages. -$printer -> text("£ 3.95\n"); - -$printer -> cut(); -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/50-P-822D-greek.php b/htdocs/includes/mike42/escpos-php/example/specific/50-P-822D-greek.php deleted file mode 100644 index 1651f44a7fa..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/50-P-822D-greek.php +++ /dev/null @@ -1,19 +0,0 @@ - text($text . "\n"); -$printer -> cut(); - -// Close the connection -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/54-gfx-sidebyside.php b/htdocs/includes/mike42/escpos-php/example/specific/54-gfx-sidebyside.php deleted file mode 100644 index 2becce742d4..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/54-gfx-sidebyside.php +++ /dev/null @@ -1,64 +0,0 @@ - setJustification(Printer::JUSTIFY_CENTER); - $printer -> graphics($img); - $printer -> cut(); - } finally { - // Always close the connection - $printer -> close(); - } -} catch (Exception $e) { - // Print out any errors: Eg. printer connection, image loading & external image manipulation. - echo $e -> getMessage() . "\n"; - echo $e -> getTraceAsString(); -} finally { - unlink($imgCombined_path); - unlink($tmpf_path); -} diff --git a/htdocs/includes/mike42/escpos-php/example/specific/6-arabic-epos-tep-220m.php b/htdocs/includes/mike42/escpos-php/example/specific/6-arabic-epos-tep-220m.php deleted file mode 100644 index 5994b7a81c7..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/6-arabic-epos-tep-220m.php +++ /dev/null @@ -1,74 +0,0 @@ - utf8Glyphs($textUtf8, $maxChars); -$textLine = explode("\n", $textLtr); - -/* - * Set up and use an image print buffer with a suitable font - */ -$buffer = new ImagePrintBuffer(); -$buffer -> setFont($fontPath); -$buffer -> setFontSize($fontSize); - -$profile = CapabilityProfile::load("TEP-200M"); -$connector = new FilePrintConnector("php://output"); - // = new WindowsPrintConnector("LPT2"); - // Windows LPT2 was used in the bug tracker - -$printer = new Printer($connector, $profile); -$printer -> setPrintBuffer($buffer); - -$printer -> setJustification(Printer::JUSTIFY_RIGHT); -foreach($textLine as $text) { - // Print each line separately. We need to do this since Imagick thinks - // text is left-to-right - $printer -> text($text . "\n"); -} - -$printer -> cut(); -$printer -> close(); diff --git a/htdocs/includes/mike42/escpos-php/example/specific/62-greek-symbol-swap.php b/htdocs/includes/mike42/escpos-php/example/specific/62-greek-symbol-swap.php deleted file mode 100644 index 5ea995e5aed..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/62-greek-symbol-swap.php +++ /dev/null @@ -1,15 +0,0 @@ - text("Μιχάλης Νίκος\n"); -$printer -> cut(); -$printer -> close(); - -?> diff --git a/htdocs/includes/mike42/escpos-php/example/specific/68-redblack.php b/htdocs/includes/mike42/escpos-php/example/specific/68-redblack.php deleted file mode 100644 index 142a83ab3e7..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/68-redblack.php +++ /dev/null @@ -1,21 +0,0 @@ - text("Hello World!\n"); - $printer -> setColor(Printer::COLOR_2); - $printer -> text("Red?!\n"); - $printer -> setColor(Printer::COLOR_1); - $printer -> text("Default color again?!\n"); - $printer -> cut(); -} finally { - /* Always close the printer! */ - $printer -> close(); -} diff --git a/htdocs/includes/mike42/escpos-php/example/specific/97-dithering.php b/htdocs/includes/mike42/escpos-php/example/specific/97-dithering.php deleted file mode 100644 index 312df749eb1..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/97-dithering.php +++ /dev/null @@ -1,28 +0,0 @@ - bitImage($img1); - - /* Load with optimisations disabled, forcing the use of PHP to convert the - pixels, which uses a threshold and is much slower. - */ - $img2 = EscposImage::load(__DIR__ . '/../resources/tulips.png', false); - $printer -> bitImage($img2); - $printer -> cut(); -} finally { - /* Always close the printer! */ - $printer -> close(); -} diff --git a/htdocs/includes/mike42/escpos-php/example/specific/README.md b/htdocs/includes/mike42/escpos-php/example/specific/README.md deleted file mode 100644 index 7433e7aa247..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/specific/README.md +++ /dev/null @@ -1,7 +0,0 @@ -Specific examples ------------------ - -These examples are designed for specific combinations of language, -printer and interface. - -They are documented here because the general examples all set up the printer in a similar way. diff --git a/htdocs/includes/mike42/escpos-php/example/text-size.php b/htdocs/includes/mike42/escpos-php/example/text-size.php deleted file mode 100644 index 01bf33dd699..00000000000 --- a/htdocs/includes/mike42/escpos-php/example/text-size.php +++ /dev/null @@ -1,65 +0,0 @@ - - */ -require __DIR__ . '/../autoload.php'; -use Mike42\Escpos\Printer; -use Mike42\Escpos\PrintConnectors\FilePrintConnector; - -$connector = new FilePrintConnector("php://stdout"); -$printer = new Printer($connector); - -/* Initialize */ -$printer -> initialize(); - -/* Text of various (in-proportion) sizes */ -title($printer, "Change height & width\n"); -for ($i = 1; $i <= 8; $i++) { - $printer -> setTextSize($i, $i); - $printer -> text($i); -} -$printer -> text("\n"); - -/* Width changing only */ -title($printer, "Change width only (height=4):\n"); -for ($i = 1; $i <= 8; $i++) { - $printer -> setTextSize($i, 4); - $printer -> text($i); -} -$printer -> text("\n"); - -/* Height changing only */ -title($printer, "Change height only (width=4):\n"); -for ($i = 1; $i <= 8; $i++) { - $printer -> setTextSize(4, $i); - $printer -> text($i); -} -$printer -> text("\n"); - -/* Very narrow text */ -title($printer, "Very narrow text:\n"); -$printer -> setTextSize(1, 8); -$printer -> text("The quick brown fox jumps over the lazy dog.\n"); - -/* Very flat text */ -title($printer, "Very wide text:\n"); -$printer -> setTextSize(4, 1); -$printer -> text("Hello world!\n"); - -/* Very large text */ -title($printer, "Largest possible text:\n"); -$printer -> setTextSize(8, 8); -$printer -> text("Hello\nworld!\n"); - -$printer -> cut(); -$printer -> close(); - -function title(Printer $printer, $text) -{ - $printer -> selectPrintMode(Printer::MODE_EMPHASIZED); - $printer -> text("\n" . $text); - $printer -> selectPrintMode(); // Reset -} diff --git a/htdocs/includes/mike42/escpos-php/test/bootstrap.php b/htdocs/includes/mike42/escpos-php/test/bootstrap.php deleted file mode 100644 index 749629ac4af..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/bootstrap.php +++ /dev/null @@ -1,40 +0,0 @@ - $c) { - $code = ord($c); - if ($code < 32 || $code > 126) { - $chars[$i] = "\\x" . bin2hex($c); - } - } - return implode($chars); -} diff --git a/htdocs/includes/mike42/escpos-php/test/integration/ExampleTest.php b/htdocs/includes/mike42/escpos-php/test/integration/ExampleTest.php deleted file mode 100644 index 6ba8e23e59e..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/integration/ExampleTest.php +++ /dev/null @@ -1,187 +0,0 @@ - exampleDir = dirname(__FILE__) . "/../../example/"; - } - - /** - * @medium - */ - public function testBitImage() - { - $this->markTestSkipped('Not repeatable on Travis CI.'); - $this -> requireGraphicsLibrary(); - $outp = $this -> runExample("bit-image.php"); - $this -> outpTest($outp, "bit-image.bin"); - } - - /** - * @medium - */ - public function testCharacterEncodings() - { - $outp = $this -> runExample("character-encodings.php"); - $this -> outpTest($outp, "character-encodings.bin"); - } - - /** - * @medium - */ - public function testCharacterTables() - { - $outp = $this -> runExample("character-tables.php"); - $this -> outpTest($outp, "character-tables.bin"); - } - - private function outpTest($outp, $fn) - { - $file = dirname(__FILE__) . "/resources/output/".$fn; - if (!file_exists($file)) { - file_put_contents($file, $outp); - } - $this -> assertEquals($outp, file_get_contents($file)); - } - - /** - * @medium - */ - public function testDemo() - { - $this->markTestSkipped('Not repeatable on Travis CI.'); - $this -> requireGraphicsLibrary(); - $outp = $this -> runExample("demo.php"); - $this -> outpTest($outp, "demo.bin"); - } - - /** - * @medium - */ - public function testGraphics() - { - $this->markTestSkipped('Not repeatable on Travis CI.'); - $this -> requireGraphicsLibrary(); - $outp = $this -> runExample("graphics.php"); - $this -> outpTest($outp, "graphics.bin"); - } - - /** - * @medium - */ - public function testReceiptWithLogo() - { - $this->markTestSkipped('Not repeatable on Travis CI.'); - $this -> requireGraphicsLibrary(); - $outp = $this -> runExample("receipt-with-logo.php"); - $this -> outpTest($outp, "receipt-with-logo.bin"); - } - - /** - * @medium - */ - public function testQrCode() - { - $outp = $this -> runExample("qr-code.php"); - $this -> outpTest($outp, "qr-code.bin"); - } - - /** - * @medium - */ - public function testBarcode() - { - $outp = $this -> runExample("barcode.php"); - $this -> outpTest($outp, "barcode.bin"); - } - - /** - * @medium - */ - public function testTextSize() - { - $outp = $this -> runExample("text-size.php"); - $this -> outpTest($outp, "text-size.bin"); - } - - /** - * @medium - */ - public function testMarginsAndSpacing() - { - $outp = $this -> runExample("margins-and-spacing.php"); - $this -> outpTest($outp, "margins-and-spacing.bin"); - } - - /** - * @medium - */ - public function testPdf417Code() - { - $outp = $this -> runExample("pdf417-code.php"); - $this -> outpTest($outp, "pdf417-code.bin"); - } - - public function testInterfaceCups() - { - $outp = $this -> runSyntaxCheck("interface/cups.php"); - } - - public function testInterfaceEthernet() - { - $outp = $this -> runSyntaxCheck("interface/ethernet.php"); - } - - public function testInterfaceLinuxUSB() - { - $outp = $this -> runSyntaxCheck("interface/linux-usb.php"); - } - - public function testInterfaceWindowsUSB() - { - $outp = $this -> runSyntaxCheck("interface/windows-usb.php"); - } - - public function testInterfaceSMB() - { - $outp = $this -> runSyntaxCheck("interface/smb.php"); - } - - public function testInterfaceWindowsLPT() - { - $outp = $this -> runSyntaxCheck("interface/windows-lpt.php"); - } - - private function runSyntaxCheck($fn) - { - $this -> runExample($fn, true); - } - - private function runExample($fn, $syntaxCheck = false) - { - // Change directory and check script - chdir($this -> exampleDir); - $this -> assertTrue(file_exists($fn), "Script $fn not found."); - // Run command and save output - $php = "php" . ($syntaxCheck ? " -l" : ""); - ob_start(); - passthru($php . " " . escapeshellarg($fn), $retval); - $outp = ob_get_contents(); - ob_end_clean(); - // Check return value - $this -> assertEquals(0, $retval, "Example $fn exited with status $retval"); - return $outp; - } - - protected function requireGraphicsLibrary() - { - if (!EscposImage::isGdLoaded() && !EscposImage::isImagickLoaded()) { - $this -> markTestSkipped("This test requires a graphics library."); - } - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/barcode.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/barcode.bin deleted file mode 100644 index ae4070d70a02f0b74946bbc6011ef46379dac870..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2667 zcmbVOT~FIc6osV))@`MI*(Vg~B6X`k$%hjPp)b3R2}||?Rf2Z+bz)DGQ5=tDPcVo- zzh`X6$+$_sgcQctGw0rO?#KAxuY<$(H5cQFA{P2IVlkz{R}<^taO;wPX7fN%Am!Am zO$R$p-?fU(wpE*KS8N^FeyP|_VS84w^AATJVWhjJ=^Um#(*y=-$)Gl=!#{Mq;}41=nFu9hs0F-{ zq+qjZ*ITuz`?76!x~K2X&U+Va+j2(op5qO;RNnM?AXB^nrRp1r#MG`qtnvbz;s4_Y zx8Z2NSK@*Djev(^2o}y~JQf~BvGnJj(kb?&&y%KQ9SpYZ4tWzKeX&b~UNHAXIHr0U z%W!;z*W8PX?XZ)G_%1`8tg)P1!`f$raqu0qi3X?DHuB=@rgbGf-- zeu5CVT&|SUVcW$x=w4_JpI9u|DBx7g4i-ccwipd*ixN5GltkPUEXZ^%rih+=C%PO* zJWfuqgLynL)Wp@H2L^l(_7-cT=XM1P9gEY(sn>tJZ8Tf@&~CBBnZbjKS)SGU@ezGY zxKAvhM6p=45+x%8;`nax-`#NrQ7nrs zdW`x=07Xp1g%UUUv~AE@1S7I#IU%|$YvmCUA}0);QAEkaN>a)w1*UtJ5sXin>bzOV zL!nKsW|JWHWs8kGpJwv})1T8k7tC4;mWi1kpt=k>F{OFtlAaJOR$;+JKhl%j7m30p zF&D`MkSgVnt7v44MNxo}t}j7T6hZ|#_**(|lA(x`Yv4eSzxT_BGUX-Bm3Y56|5{hf z`wZfRhFCo3n(~Wm5LN0NLneGA=hht#NhHMXnFumDfxfM4+wcNVttW!K)_s|+3v|1a zje;M6*Ud)>SI}i1MLhOc!s!hqkF${s%x-wnd~`nHdid+|2|<=9eH!zS$7s*&%VYJv ze(D#;i|B{1Ov@^aON%?SXlje}ZLYryyh&W|*!sI5u6H~6|I_Y~A<>ijC%x5CK7Vq5 J*Q-y?&i{#g_R0VN diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/bit-image.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/bit-image.bin deleted file mode 100644 index 462eb1a0bf32bbe4bd68b8e9dc8304bc6559549b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9789 zcmeI2F>l*O6o4N~Km-iK^i~;FL=GL2p@BvZhRz)ebP9|X-K1KqB~%s#T524iFxjbN zmdwphF^m3y{)0q7hm2K`Au8;Meed0)cvM`p2s#yahROTx9q-<~dptee>7(P5VRR9N z(PjU9I*!88dH*cB2>VGCPLt7O77fD3quDT=4Wlp~529q}>(NZt(iOtf`24&-89WTX zis#|QFrJSGVLTZ>3FjBl&d1a6lWvHQd`9iwe-Mto33b_7(w`1Trx#c@h_S~>JllC3 zC*R_;;gfitNcYLZot=B%bzmQ!!M{wZs8w`|A~y^CqF9<76veH{X;G|AE-)F4%@svf z6)@)&yCgT*BVJVUZANu!3jGrYRDV^q_g-uan4hon52iuX(*kPjtsyn)cimf11|K=^ z@P1H}uZ~PUoUXnP41*soS63!CSF5$jt!=(}T9@BCb-sjJ`|T;Tl+j;s3|?V!22f)( zwOPN792oUmTYLcEn(~7T_Dnv?p;_Y|^pw$Fx9Q}u;c#lthhI(pdFA?s177u@<(a$> z9nWyU^)BQ!Zn&9eIOH1V%dOrBBpg7+IJ*E&<#58A3H8VoonkWppI!4E-V7k%cdvSb z6mz;!I2B%Cvy{>WUDZZmol&KNPRT2(Mw;hz3rY_y`C1efOZhKFVX>tDyC~?tq{qQ~ zBOF|poN-2Jc5lSu>WYiqw=#fKvs3bw?$=q%0M?>M$!|sPwH~)qaw`0%ELExEitdfD z+GagK@AZQ90ky@!bMDxClWV!KUojiReKDy_2zOSRW%$tRrX>|`~zUU!CCqU&>(9&$6hIJ*4?W<6r* zkBq{zoQqj5|&yb^2Rw+y?1WjC-? z`9_o*R`gYpQpwlCb^}Y>#cp7|AVb&w__dkCx&QG7)=7UnzB{~fZFr^E zMH^n(^Fez)XwL@~f5WQI3w8Wx&j)3dwC95uEKs;$&j;=Kpu7|Cc|SSR+gGCr{;VrW ZqSG1v3@e_-$!vr_%c`9j-uvQH_b;K8L%;w4 diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/character-encodings.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/character-encodings.bin deleted file mode 100644 index f93ea377722c34a852f80637b7ba278d7c916b7a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1930 zcmZuyTWnNC7zTZ7qEQo{Hkyyb1W2k6J{eySBR3%gwE^SX?Ah5p)15Q3&YZKQeWFlq zQZSfCDxh>*U<>7xGf7!7#Es0{w=12bzd(FO&j-4AZj99`ZQ}4hfN6U zb5v>*39mKqXmeDC{3kXwc*uBg$7 z3)$>(-)M_4tJL5NT^3khBpIX(l7gWcQIpc;V4JmJVFm^p5E*VnM8jc@tBujcGft-? zJEgqL;c!C!GaCbg$k0Flj|mGo@h6WYmVy7P55;~?Qc~vV;2#TfkK&R1j$sM*w@*hR z@f@b~eXxKgWFOru9!hS@kuZZ65yHGJt#9%k^q(ZlUy{rMS^%Y!cZ+;x8PX3k7?;8+ zO8?fxs2ecrFd@;cEi1=0X7AHzX98MmNjIfwZsaWd?DB3rShJ^y| zVuR{9Sr-G9&C$SvYC(AI1%YHrLdVb)F+9PFP;;11Nhw)!23dQ;k}JJKmxme5<)Qjs zfk@3t6L?FI5j;_eH<`;2*OYPNM`is|em_8R2^ByQYo2~&uz8NFE-XhC{47>9N4AiW zHr{q+#kpEPA zbqzM@XoKNc&ccDi;)vBIIjLDZ!`oyS#VyCA+018gR>&li(U+@4#CIo;6x{ed*H3?c zuKPQ5Ug^5J6+e7^>FBj1ICk>H#W_e5!aQt5rRQ0`S)T969y^^$Z#|mX`_(Y|&ZQ6c?9Zf54Ij!3 zrt$67p}swX*|tlA>CWEn?DpQneFq0RwsbUSkF|8|!`D|+?H7-CwI1Bvb0E{+lgb`% z%^Wx~)SW(=J%KN?9VarWj_g_bzWK`DGdp|I+cNFPx9`egN4Dd1XZD+(g0%nTZl*9S zM!737oATIIhQ|kwy-z6{GZ+K+$O_Rw%EzrRvZaJMf?RrxqK%oFGP0yVb}BVL;b79c z6?3S=_|yaw32o^2R8GB$1f~`XVQs+esJyTC=5OF!uK&jz-S3{y<7Vzw{!D)!UHv_| zTNm>B8;Y+5WE19B$>WUFpi?3p{4> zu;Eqz%R>tK1=1{)$XF&XEm@4U>l#1CXDd*>PuBd%HV#00?w1J>>t-F3>EHF9=>Gy?uO3`S}L~mM&u~TMpQu@)asps!Ui93k9n1t6sk0-s zOV@7Qd-UwpyN^IYje>pq^&c>B(BL6MhYcSwa@6QCW5^T$+ zrr_Lp^A{{!w0OzVWy@ErT(x@5+I8zUY}~YY%hqk%ckJA?dk+O|6x_RS|AB*t4j(ys z?D&b3r%s{~EYcyiN@nr{>BvJI^3yZeSUX0ssZ=aue4fRWPeb~FkDMk=IRtO#JF5V^&Q0>%rx;tZ3>OvTyaBaM<#L^TT~ zzyeuCE(^G}6}f@9?iCVmA$b9&p8-@A*BPuN=yx80WnB8bLBHz^jBBU(fPOvxH3io; z@df>^^v9JKr9i(k{S_;!O6v#uN&2%hFs?=9&rDcI;xQ8NF?V7xZ~)d1tY0H50-C<8`H~1IFu0 gMF7U@O2sft<7xZNFp?FVCfA>TI5&S=EI!!tFDPdJG5`Po diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/demo.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/demo.bin deleted file mode 100644 index 6b426d91ff0563a2ec43c93217f26a492e8d9396..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73643 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 M5AW>X{`!mPPivkA#sB~S diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/margins-and-spacing.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/margins-and-spacing.bin deleted file mode 100644 index 0b3a4676033f93f4b13ba388d573ae18975b5086..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 339 zcmY+>qf5_d!m*jAca;gz+ z*GGK~k72wOs)0k-hvyXagj|%Z06Ki{wLy_gEXtC}7G=d`hq7j3Y9!5QLrIQNO;Ix= zV<`+oUdmRK1~RwGP#gg6JBFdtukjo&G*1QjTllfkgS`Kr==9Np$SCFe88S*WyvvEo Hp7x736xCmM diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/pdf417-code.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/pdf417-code.bin deleted file mode 100644 index ab2d7c54958650ba4b50fa76d5fec1a8a69e3cb1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2366 zcmb_e&riZI6rO^K*};=Hf_dC#LQJ<|$>m#_`bf^&TXehrlZNgzkw)a92iehx6^aF-bc$J6Kn6Ry>G47N5-}tGWL(~;mjdZ zGUu5V@(uhTTaA%O>{m>b)NJj3yi-mYPf52T7GmKY>aH z5iTgs(2s+8kTHHxxKSw{X_3l9<@OgB6h(L-SHA21$*;6_C%Cb!cBS~&)$vUrHSudi ze_kIws2;mlAANx0LNSXak5P4Bd<)f9a#dx_a#ZlAVEP>bV5!c)ON10jo?KSXX!}Xo za1mM;jK9)6*5xkRSR*`04YC-lT$BcX+8BAbt`A+>`XDC{T)e$&NH80*hy_<$s9ARy zL($F-QvgPO4opqaMF`$bYSvj8iW+1wfKqDK$cCZ@$V05pCN(3fDYnNrPb8XL>I&3U zYX0{dm_Wdzxla2yUP?4=heEv}@XLo^tXZSU@(VO5f?5Lhh%_vM+M~P&=s%J%^9B3E z9-!C7NH6vV4N(nNgD8lUXHvtf&^>H)*ejkEW=v;?lHp9_rGP5-bDpfwn%!vTDwh$} Lc)f7DFL$kP%6Aqq diff --git a/htdocs/includes/mike42/escpos-php/test/integration/resources/output/qr-code.bin b/htdocs/includes/mike42/escpos-php/test/integration/resources/output/qr-code.bin deleted file mode 100644 index a1e687f151c8f8db633da3fa63fcc0d67fbb6671..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1551 zcmbW1%}>HG6u_t8We4M(m^^M6J#6Dcy@^WVK@6zzUbhOBwVhq3gTLN4zC;SLLcwb^4Fs%YZ^axwI=)>$o;5TW;ISE+xyoDb3D~gXf{;_MB%LYbFNZdi7bT z?{sCXA!a-ZDbSQ;r)^ir9>$GXPlPWaXW&zz6%7z(p`3F|Gyy757!7vWo@TZVYBrj! z^NY*vx5ckKB%CVd+x9m1DVeteJ5hw$8y10bHnYCKyln$-3me8OwupM3J#v(WyfXo0TM?&e18G=`?b5 z4$KhE97Hy8CJALw;# k<|_&F8YT^J0>~w5QL=Ip$*1cQ(OqxX~7|PHI^$;+biUCaG-b< zbkNsYg1nc0z4RhHU7dT3|(d)C_d?ac6hZ+6UB)o-dT=fRgd zpFgbk>W0|726xg0-U0->UoL0HJX{(VYKP7ZxnIhPHVA``3=CP%Cj z)(PW)x!Rogn@(h!TjJOMkctJMfLO3m27V5VHXZk-fGi$t`eOX{#ni!!#C|Pk>xBS` z`hakY$!44yirQVwNsRVY#6gS$aOrxBBEZa0ZkBtZ@UUQr4q}q~iKG(5G@xC(jF2bJ zy=0SWmd0-8Cz(eSp*Tu|iz#Z8C8U6fV3@LNMP*DBZW;^<)0b>dK-K;*^{!=<-P9Ag zn+3#_BdT7ABKafXUCZ59QO*qI72ppfbtSwM6QTt5^=AsvL!l^kCEQfHG9)USrCiJ= zRE&2}fcb>-aX7y(2#N{i;pIF^&Q?=u_7LCPK|wrrLVzcf6Em}?zJQD+NmuWnJnIe$ZtAnUuvO3s6 zW`qyyf~HMMi4s&ve+DMMx*chEjGd7H?6XwD8}cEb5r-e6X4 z0!BL8Oh74l(p1V*rzfh`l%GN=0dx$f#ZoZRRFFZb6apikPAW=iDy9PttqfwLAO|B& z$s;?hoQ|7H#dO+NN>TKmGCHzTDjY0DM}1>ys=(ot+yY5Xf$xk88FtL$t0|50m^94e zOCwEX!S7Rgp9Q3=Ecjrgsno}X(v)CylCwaXN<3UBO$}VUQw}w03LIQ0MNzdt=c*Op zmxbC;tpK0R(-#2KlJ47L9k333yaV*Ln0rufR#*A?xaAL znZFHB`9av{CltG$bgC6i$F}kvwMG5bzHI7*r~Q-1oWkBBgWhycx)E>dJgB`6k1Evf uZg{-kddr_i9UdO=tzN%-$eZ=XIv)hMO>9TUc%2ib6th}+ZV#S^)@eM5#$Umje%7B$&R5Dh^tV~#$w#q`7 z2J74y?a_(7i}%morNHl9wfe**k7``&J#KbiTZ{Tf7<4>V`Jur=mv`Y)0pk1OKhu8^ fN@?`ksDeWFnwwHshg)rJwNxjy4|Ni2SUh!)7zJM* diff --git a/htdocs/includes/mike42/escpos-php/test/unit/AuresCustomerDisplayTest.php b/htdocs/includes/mike42/escpos-php/test/unit/AuresCustomerDisplayTest.php deleted file mode 100644 index c0f803afa97..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/AuresCustomerDisplayTest.php +++ /dev/null @@ -1,76 +0,0 @@ - outputConnector = new DummyPrintConnector(); - $profile = CapabilityProfile::load('OCD-300'); - $this -> printer = new AuresCustomerDisplay($this -> outputConnector, $profile); - } - - protected function checkOutput($expected = null) - { - /* Check those output strings */ - $outp = $this -> outputConnector -> getData(); - if ($expected === null) { - echo "\nOutput was:\n\"" . friendlyBinary($outp) . "\"\n"; - } - $this -> assertEquals($expected, $outp); - } - - protected function tearDown() - { - $this -> outputConnector -> finalize(); - } - - public function testInitializeOutput() - { - $this -> checkOutput("\x02\x05C1\x03\x1b@\x1bt\x00\x1f\x02"); - } - - public function testselectTextScrollMode() { - $this -> outputConnector -> clear(); - $this -> printer -> selectTextScrollMode(AuresCustomerDisplay::TEXT_OVERWRITE); - $this -> checkOutput("\x1f\x01"); - } - - public function testClear() { - $this -> outputConnector -> clear(); - $this -> printer -> clear(); - $this -> checkOutput("\x0c"); - } - - public function testShowFirmwareVersion() { - $this -> outputConnector -> clear(); - $this -> printer -> showFirmwareVersion(); - $this -> checkOutput("\x02\x05V\x01\x03"); - } - - public function testSelfTest() { - $this -> outputConnector -> clear(); - $this -> printer -> selfTest(); - $this -> checkOutput("\x02\x05D\x08\x03"); - } - - public function testShowLogo() { - $this -> outputConnector -> clear(); - $this -> printer -> showLogo(); - $this -> checkOutput("\x02\xfcU\xaaU\xaa"); - } - - public function testTest() { - $this -> outputConnector -> clear(); - // Handling of line-endings differs to regular printers, need to use \r\n - $this -> printer -> text("Hello\nWorld\n"); - $this -> checkOutput("Hello\x0d\x0aWorld\x0d\x0a"); - } -} \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/CapabilityProfileTest.php b/htdocs/includes/mike42/escpos-php/test/unit/CapabilityProfileTest.php deleted file mode 100644 index 923811e7042..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/CapabilityProfileTest.php +++ /dev/null @@ -1,59 +0,0 @@ -assertFalse(array_search('simple', $names) === false); - $this->assertFalse(array_search('default', $names) === false); - $this->assertTrue(array_search('lalalalala', $names) === false); - } - - public function testLoadDefault() - { - // Just load the default profile and check it out - $profile = CapabilityProfile::load('default'); - $this->assertEquals("default", $profile->getId()); - $this->assertEquals("Default", $profile->getName()); - $this->assertTrue($profile->getSupportsBarcodeB()); - $this->assertTrue($profile->getSupportsBitImageRaster()); - $this->assertTrue($profile->getSupportsGraphics()); - $this->assertTrue($profile->getSupportsQrCode()); - $this->assertTrue($profile->getSupportsPdf417Code()); - $this->assertFalse($profile->getSupportsStarCommands()); - $this->assertArrayHasKey('0', $profile->getCodePages()); - } - - public function testCodePageCacheKey() - { - $default = CapabilityProfile::load('default'); - $simple = CapabilityProfile::load('simple'); - $this->assertNotEquals($default->getCodePageCacheKey(), $simple->getCodePageCacheKey()); - } - - public function testBadProfileNameSuggestion() - { - $this->setExpectedException('\InvalidArgumentException', 'simple'); - $profile = CapabilityProfile::load('simpel'); - } - - public function testBadFeatureNameSuggestion() - { - $this->setExpectedException('\InvalidArgumentException', 'graphics'); - $profile = CapabilityProfile::load('default'); - $profile->getFeature('graphicx'); - } - - public function testSuggestions() - { - $input = "orangee"; - $choices = array("apple", "orange", "pear"); - $suggestions = CapabilityProfile::suggestNearest($input, $choices, 1); - $this->assertEquals(1, count($suggestions)); - $this->assertEquals("orange", $suggestions[0]); - } -} \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/CodePageTest.php b/htdocs/includes/mike42/escpos-php/test/unit/CodePageTest.php deleted file mode 100644 index 0e7b661f94d..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/CodePageTest.php +++ /dev/null @@ -1,63 +0,0 @@ -markTestSkipped("Requires iconv"); - } - } - - public function testDataIconv() - { - // Set up CP437 - $this->requiresIconv(); - $cp = new CodePage("CP437", array( - "name" => "CP437", - "iconv" => "CP437" - )); - $this->assertTrue($cp->isEncodable()); - $this->assertEquals($cp->getIconv(), "CP437"); - $this->assertEquals($cp->getName(), "CP437"); - $this->assertEquals($cp->getId(), "CP437"); - $this->assertEquals($cp->getNotes(), null); - // Get data and see if it's right - $data = $cp->getData(); - $expected = "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ "; - $this->assertEquals($expected, $data); - } - - public function testDataIconvBogus() - { - // No errors raised, you just get an empty list of supported characters if you try to compute a fake code page - $this->requiresIconv(); - $cp = new CodePage("foo", array( - "name" => "foo", - "iconv" => "foo" - )); - $this->assertTrue($cp->isEncodable()); - $this->assertEquals($cp->getIconv(), "foo"); - $this->assertEquals($cp->getName(), "foo"); - $this->assertEquals($cp->getId(), "foo"); - $this->assertEquals($cp->getNotes(), null); - $data = $cp->getData(); - $expected = str_repeat(" ", 128); - $this->assertEquals($expected, $data); - // Do this twice (caching behaviour) - $data = $cp->getData(); - $this->assertEquals($expected, $data); - } - - public function testDataCannotEncode() - { - $this->setExpectedException('\InvalidArgumentException'); - $cp = new CodePage("foo", array( - "name" => "foo" - )); - $this->assertFalse($cp->isEncodable()); - $cp->getData(); - } -} \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/CupsPrintConnectorTest.php b/htdocs/includes/mike42/escpos-php/test/unit/CupsPrintConnectorTest.php deleted file mode 100644 index 41499ee4b27..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/CupsPrintConnectorTest.php +++ /dev/null @@ -1,36 +0,0 @@ -getMockConnector("FooPrinter", array("FooPrinter")); - $connector->expects($this->once())->method('getCmdOutput')->with($this->stringContains("lp -d 'FooPrinter' ")); - $connector->finalize(); - } - public function testPrinterDoesntExist() - { - $this -> setExpectedException('BadMethodCallException'); - $connector = $this->getMockConnector("FooPrinter", array("OtherPrinter")); - $connector->expects($this->once())->method('getCmdOutput')->with($this->stringContains("lp -d 'FooPrinter' ")); - $connector->finalize(); - } - public function testNoPrinter() - { - $this -> setExpectedException('BadMethodCallException'); - $connector = $this->getMockConnector("FooPrinter", array("")); - } - private function getMockConnector($path, array $printers) - { - $stub = $this->getMockBuilder('Mike42\Escpos\PrintConnectors\CupsPrintConnector')->setMethods(array ( - 'getCmdOutput', - 'getLocalPrinters' - ))->disableOriginalConstructor()->getMock(); - $stub->method('getCmdOutput')->willReturn(""); - $stub->method('getLocalPrinters')->willReturn($printers); - $stub->__construct($path); - return $stub; - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/EscposImageTest.php b/htdocs/includes/mike42/escpos-php/test/unit/EscposImageTest.php deleted file mode 100644 index 08e1be91c50..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/EscposImageTest.php +++ /dev/null @@ -1,16 +0,0 @@ - setExpectedException('Exception'); - $img = EscposImage::load('not-a-real-file.png'); - } - public function testImageNotSupportedException() - { - $this -> setExpectedException('InvalidArgumentException'); - $img = EscposImage::load('/dev/null', false, array()); - } -} \ No newline at end of file diff --git a/htdocs/includes/mike42/escpos-php/test/unit/EscposPrintBufferTest.php b/htdocs/includes/mike42/escpos-php/test/unit/EscposPrintBufferTest.php deleted file mode 100644 index af0ee2b9b73..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/EscposPrintBufferTest.php +++ /dev/null @@ -1,192 +0,0 @@ - outputConnector = new DummyPrintConnector(); - $printer = new Printer($this -> outputConnector); - $this -> buffer = $printer -> getPrintBuffer(); - } - - protected function checkOutput($expected = null) - { - /* Check those output strings */ - $outp = $this -> outputConnector -> getData(); - if ($expected === null) { - echo "\nOutput was:\n\"" . friendlyBinary($outp) . "\"\n"; - } - $this -> assertEquals($expected, $outp); - } - - protected function tearDown() - { - $this -> outputConnector -> finalize(); - } - - public function testRawTextNonprintable() - { - $this -> buffer -> writeTextRaw("Test" . Printer::ESC . "v1\n"); - $this -> checkOutput("\x1b@Test?v1\x0a"); // ASCII ESC character is substituted for '?' - } - - public function testDanish() - { - $this -> buffer -> writeText("Quizdeltagerne spiste jordbær med fløde, mens cirkusklovnen Wolther spillede på xylofon.\n"); - $this -> checkOutput("\x1b@Quizdeltagerne spiste jordb\x91r med fl\x1bt\x02\x9bde, mens cirkusklovnen Wolther spillede p\x86 xylofon.\x0a"); - } - - public function testGerman() - { - $this -> buffer -> writeText("Falsches Üben von Xylophonmusik quält jeden größeren Zwerg.\n"); - $this -> checkOutput("\x1b@Falsches \x9aben von Xylophonmusik qu\x84lt jeden gr\x94\xe1eren Zwerg.\x0a"); - } - - public function testGreek() - { - $this -> buffer -> writeText("Ξεσκεπάζω την ψυχοφθόρα βδελυγμία"); - $this -> checkOutput("\x1b@\x1bt\x0e\x8d\x9c\xa9\xa1\x9c\xa7\xe1\x9d\xe0 \xab\x9e\xa4 \xaf\xac\xae\xa6\xad\x9f\xe6\xa8\x98 \x99\x9b\x9c\xa2\xac\x9a\xa3\xe5\x98"); - } - - public function testGreekWithDiacritics() - { - // This is a string which is known to be un-printable in ESC/POS (the grave-accented letters are not in any code page), - // so we are checking the substitution '?' for unknown characters. - $this -> buffer -> writeText("Γαζέες καὶ μυρτιὲς δὲν θὰ βρῶ πιὰ στὸ χρυσαφὶ ξέφωτο.\n"); - $this -> checkOutput("\x1b@\xe2\xe0\x1bt\x0e\x9d\xe2\x9c\xaa \xa1\x98? \xa3\xac\xa8\xab\xa0?\xaa \x9b?\xa4 \x9f? \x99\xa8? \xa7\xa0? \xa9\xab? \xae\xa8\xac\xa9\x98\xad? \xa5\xe2\xad\xe0\xab\xa6.\x0a"); - } - - public function testEnglish() - { - $this -> buffer -> writeText("The quick brown fox jumps over the lazy dog.\n"); - $this -> checkOutput("\x1b@The quick brown fox jumps over the lazy dog.\n"); - } - - public function testSpanish() - { - // This one does not require changing code-pages at all, so characters are just converted from Unicode to CP437. - $this -> buffer -> writeText("El pingüino Wenceslao hizo kilómetros bajo exhaustiva lluvia y frío, añoraba a su querido cachorro.\n"); - $this -> checkOutput("\x1b@El ping\x81ino Wenceslao hizo kil\xa2metros bajo exhaustiva lluvia y fr\xa1o, a\xa4oraba a su querido cachorro.\x0a"); - } - - public function testFrench() - { - $this -> buffer -> writeText("Le cœur déçu mais l'âme plutôt naïve, Louÿs rêva de crapaüter en canoë au delà des îles, près du mälström où brûlent les novæ.\n"); - $this -> checkOutput("\x1b@Le c\x1bt\x10\x9cur d\xe9\xe7u mais l'\xe2me plut\xf4t na\xefve, Lou\xffs r\xeava de crapa\xfcter en cano\xeb au del\xe0 des \xeeles, pr\xe8s du m\xe4lstr\xf6m o\xf9 br\xfblent les nov\xe6.\x0a"); - } - - public function testIrishGaelic() - { - // Note that some letters with diacritics cannot be printed for Irish Gaelic text, so text may need to be simplified. - $this -> buffer -> writeText("D'fhuascail Íosa, Úrmhac na hÓighe Beannaithe, pór Éava agus Ádhaimh.\n"); - $this -> checkOutput("\x1b@D'fhuascail \x1bt\x02\xd6osa, \xe9rmhac na h\xe0ighe Beannaithe, p\xa2r \x90ava agus \xb5dhaimh.\x0a"); - } - - public function testHungarian() - { - $this -> buffer -> writeText("Árvíztűrő tükörfúrógép.\n"); - $this -> checkOutput("\x1b@\x1bt\x02\xb5rv\xa1zt\x1bt\x12\xfbr\x8b t\x81k\x94rf\xa3r\xa2g\x82p.\x0a"); - } - - public function testIcelandic() - { - $this -> buffer -> writeText("Kæmi ný öxi hér ykist þjófum nú bæði víl og ádrepa."); - $this -> checkOutput("\x1b@K\x91mi n\x1bt\x02\xec \x94xi h\x82r ykist \xe7j\xa2fum n\xa3 b\x91\xd0i v\xa1l og \xa0drepa."); - } - - public function testJapaneseHiragana() - { - $this -> markTestIncomplete("Non-ASCII character sets not yet supported."); - $this -> buffer -> writeText(implode("\n", array("いろはにほへとちりぬるを", " わかよたれそつねならむ", "うゐのおくやまけふこえて", "あさきゆめみしゑひもせす")) . "\n"); - $this -> checkOutput(); - } - - public function testJapaneseKatakana() - { - $this -> markTestIncomplete("Non-ASCII character sets not yet supported."); - $this -> buffer -> writeText(implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウヰノオクヤマ ケフコエテ アサキユメミシ ヱヒモセスン")) . "\n"); - $this -> checkOutput("\x1b@\x1bt\x01\xb2\xdb\xca\xc6\xce\xcd\xc4 \xc1\xd8\xc7\xd9\xa6 \xdc\xb6\xd6\xc0\xda\xbf \xc2\xc8\xc5\xd7\xd1\x0a\xb3\xb2\xc9\xb5\xb8\xd4\xcf \xb9\xcc\xba\xb4\xc3 \xb1\xbb\xb7\xd5\xd2\xd0\xbc \xb4\xcb\xd3\xbe\xbd\xdd\x0a"); - } - - public function testJapaneseKataKanaHalfWidth() - { - $this -> buffer -> writeText(implode("\n", array("イロハニホヘト チリヌルヲ ワカヨタレソ ツネナラム", "ウイノオクヤマ ケフコエテ アサキユメミシ エヒモセスン")) . "\n"); - $this -> checkOutput("\x1b@\x1bt\x01\xb2\xdb\xca\xc6\xce\xcd\xc4 \xc1\xd8\xc7\xd9\xa6 \xdc\xb6\xd6\xc0\xda\xbf \xc2\xc8\xc5\xd7\xd1\x0a\xb3\xb2\xc9\xb5\xb8\xd4\xcf \xb9\xcc\xba\xb4\xc3 \xb1\xbb\xb7\xd5\xd2\xd0\xbc \xb4\xcb\xd3\xbe\xbd\xdd\x0a"); - } - - public function testLatvian() - { - $this -> buffer -> writeText("Glāžšķūņa rūķīši dzērumā čiepj Baha koncertflīģeļu vākus.\n"); - $this -> checkOutput("\x1b@Gl\x1bt!\x83\xd8\xd5\xe9\xd7\xeca r\xd7\xe9\x8c\xd5i dz\x89rum\x83 \xd1iepj Baha koncertfl\x8c\x85e\xebu v\x83kus.\x0a"); - } - - public function testPolish() - { - $this -> buffer -> writeText("Pchnąć w tę łódź jeża lub ośm skrzyń fig.\n"); - $this -> checkOutput("\x1b@Pchn\x1bt\x12\xa5\x86 w t\xa9 \x88\xa2d\xab je\xbea lub o\x98m skrzy\xe4 fig.\x0a"); - } - - public function testRussian() - { - $this -> buffer -> writeText("В чащах юга жил бы цитрус? Да, но фальшивый экземпляр!\n"); - $this -> checkOutput("\x1b@\x1bt\x11\x82 \xe7\xa0\xe9\xa0\xe5 \xee\xa3\xa0 \xa6\xa8\xab \xa1\xeb \xe6\xa8\xe2\xe0\xe3\xe1? \x84\xa0, \xad\xae \xe4\xa0\xab\xec\xe8\xa8\xa2\xeb\xa9 \xed\xaa\xa7\xa5\xac\xaf\xab\xef\xe0!\x0a"); - } - - public function testThai() - { - $this -> markTestIncomplete("Non-ASCII character sets not yet supported."); - $this -> buffer -> writeText("นายสังฆภัณฑ์ เฮงพิทักษ์ฝั่ง ผู้เฒ่าซึ่งมีอาชีพเป็นฅนขายฃวด ถูกตำรวจปฏิบัติการจับฟ้องศาล ฐานลักนาฬิกาคุณหญิงฉัตรชฎา ฌานสมาธิ\n"); // Quotation from Wikipedia - $this -> checkOutput(); - } - - public function testTurkish() - { - $this -> buffer -> writeText("Pijamalı hasta, yağız şoföre çabucak güvendi.\n"); - $this -> checkOutput("\x1b@Pijamal\x1bt\x02\xd5 hasta, ya\x1bt\x0d\xa7\x8dz \x9fof\x94re \x87abucak g\x81vendi.\x0a"); - } - - public function testArabic() - { - $this -> markTestIncomplete("Right-to-left text not yet supported."); - $this -> buffer -> writeText("صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ" . "\n"); // Quotation from Wikipedia - $this -> checkOutput(); - } - - public function testHebrew() - { - // RTL text is more complex than the above. - $this -> markTestIncomplete("Right-to-left text not yet supported."); - $this -> buffer -> writeText("דג סקרן שט בים מאוכזב ולפתע מצא לו חברה איך הקליטה" . "\n"); - $this -> checkOutput(); - } - - public function testVietnamese() { - $this -> buffer -> writeText("Tiếng Việt, còn gọi tiếng Việt Nam hay Việt ngữ, là ngôn ngữ của người Việt (người Kinh) và là ngôn ngữ chính thức tại Việt Nam.\n"); - $this -> checkOutput("\x1b@Ti\x1bt\x1e\xd5ng Vi\xd6t, c\xdfn g\xe4i ti\xd5ng Vi\xd6t Nam hay Vi\xd6t ng\xf7, l\xb5 ng\xabn ng\xf7 c\xf1a ng\xad\xeai Vi\xd6t (ng\xad\xeai Kinh) v\xb5 l\xb5 ng\xabn ng\xf7 ch\xddnh th\xf8c t\xb9i Vi\xd6t Nam.\x0a"); - } - - public function testWindowsLineEndings() { - $this -> buffer -> writeText("Hello World!\r\n"); - $this -> checkOutput("\x1b@Hello World!\x0a"); - } - - public function testWindowsLineEndingsRaw() { - $this -> buffer -> writeTextRaw("Hello World!\r\n"); - $this -> checkOutput("\x1b@Hello World!\x0a"); - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/EscposTest.php b/htdocs/includes/mike42/escpos-php/test/unit/EscposTest.php deleted file mode 100644 index 0b70e96b370..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/EscposTest.php +++ /dev/null @@ -1,1127 +0,0 @@ - outputConnector = new DummyPrintConnector(); - $this -> printer = new Printer($this -> outputConnector); - } - - protected function checkOutput($expected = null) - { - /* Check those output strings */ - $outp = $this -> outputConnector -> getData(); - if ($expected === null) { - echo "\nOutput was:\n\"" . friendlyBinary($outp) . "\"\n"; - } - $this -> assertEquals($expected, $outp); - } - - protected function tearDown() - { - $this -> outputConnector -> finalize(); - } - - protected function requireGraphicsLibrary() - { - if (!EscposImage::isGdLoaded() && !EscposImage::isImagickLoaded()) { - // If the test is about to do something which requires a library, - // something must throw an exception. - $this -> setExpectedException('Exception'); - } - } - - public function testInitializeOutput() - { - $this -> checkOutput("\x1b\x40"); - } - - public function testTextStringOutput() - { - $this -> printer -> text("The quick brown fox jumps over the lazy dog\n"); - $this -> checkOutput("\x1b@The quick brown fox jumps over the lazy dog\n"); - } - - public function testTextDefault() - { - $this -> printer -> text(); - $this -> checkOutput("\x1b@"); - } - - public function testTextChinese() - { - // Switch to chinese print mode, GBK output, switch back to alphanumeric. - $this -> printer -> textChinese("示例文本打印机!\n"); - $this -> checkOutput("\x1b@\x1c&\xca\xbe\xc0\xfd\xce\xc4\xb1\xbe\xb4\xf2\xd3\xa1\xbb\xfa!\x0a\x1c."); - } - - public function testTextRaw() - { - // Under raw output, the raw bytes are sent to the printer, so typing a UTF-8 euro literally causes \xE2 \x82 \xAC to be sent. - // Under text(), this would cause a code-page change (to a page that contains a Euro symbol), and single byte. - $this -> printer -> textRaw("€\n"); - $this -> checkOutput("\x1b@\xe2\x82\xac\x0a"); - } - - public function testTextString() - { - $this -> printer -> text("String"); - $this -> printer -> text(123); - $this -> printer -> text(); - $this -> printer -> text(null); - $this -> printer -> text(1.2); - $this -> printer -> text(new FooBar("FooBar")); - $this -> checkOutput("\x1b@String1231.2FooBar"); - } - - public function testTextObject() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> text(new DateTime()); - } - - public function testFeedDefault() - { - $this -> printer -> feed(); - $this -> checkOutput("\x1b@\x0a"); - } - - public function testFeed3Lines() - { - $this -> printer -> feed(3); - $this -> checkOutput("\x1b@\x1bd\x03"); - } - - public function testFeedZero() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feed(0); - } - - public function testFeedNonInteger() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feed("ab"); - } - - public function testFeedTooLarge() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feed(256); - } - - /* Print mode */ - public function testSelectPrintModeDefault() - { - $this -> printer -> selectPrintMode(); - $this -> checkOutput("\x1b@\x1b!\x00"); - } - - public function testSelectPrintModeAcceptedValues() - { - /* This iterates over a bunch of numbers, figures out which - ones contain invalid flags, and checks that the driver - rejects those, but accepts the good inputs */ - - for ($i = -1; $i <= 256; $i++) { - $invalid = ($i < 0) || ($i > 255) || (($i & 2) == 2) || (($i & 4) == 4) || (($i & 64) == 64); - $failed = false; - try { - $this -> printer -> selectPrintMode($i); - } catch (Exception $e) { - $failed = true; - } - $this -> assertEquals($failed, $invalid); - } - } - - /* Underline */ - public function testSetUnderlineDefault() - { - $this -> printer -> setUnderline(); - $this -> checkOutput("\x1b@\x1b-\x01"); - } - - public function testSetUnderlineOff() - { - $this -> printer -> setUnderline(Printer::UNDERLINE_NONE); - $this -> checkOutput("\x1b@\x1b-\x00"); - } - - public function testSetUnderlineOn() - { - $this -> printer -> setUnderline(Printer::UNDERLINE_SINGLE); - $this -> checkOutput("\x1b@\x1b-\x01"); - } - - public function testSetUnderlineDbl() - { - $this -> printer -> setUnderline(Printer::UNDERLINE_DOUBLE); - $this -> checkOutput("\x1b@\x1b-\x02"); - } - - public function testSetUnderlineAcceptedValues() - { - $this -> printer -> setUnderline(0); - $this -> printer -> setUnderline(1); - $this -> printer -> setUnderline(2); - /* These map to 0 & 1 for interchangeability with setEmphasis */ - $this -> printer -> setUnderline(true); - $this -> printer -> setUnderline(false); - $this -> checkOutput("\x1b@\x1b-\x00\x1b-\x01\x1b-\x02\x1b-\x01\x1b-\x00"); - } - - public function testSetUnderlineTooLarge() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setUnderline(3); - } - - public function testSetUnderlineNegative() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setUnderline(-1); - } - - public function testSetUnderlineNonInteger() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setUnderline("Hello"); - } - - /* Emphasis */ - public function testSetEmphasisDefault() - { - $this -> printer -> setEmphasis(); - $this -> checkOutput("\x1b@\x1bE\x01"); - } - - public function testSetEmphasisOn() - { - $this -> printer -> setEmphasis(true); - $this -> checkOutput("\x1b@\x1bE\x01"); - } - - public function testSetEmphasisOff() - { - $this -> printer -> setEmphasis(false); - $this -> checkOutput("\x1b@\x1bE\x00"); - } - - public function testSetEmphasisNonBoolean() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setEmphasis(7); - } - - /* Double strike */ - public function testSetDoubleStrikeDefault() - { - $this -> printer -> setDoubleStrike(); - $this -> checkOutput("\x1b@\x1bG\x01"); - } - - public function testSetDoubleStrikeOn() - { - $this -> printer -> setDoubleStrike(true); - $this -> checkOutput("\x1b@\x1bG\x01"); - } - - public function testSetDoubleStrikeOff() - { - $this -> printer -> setDoubleStrike(false); - $this -> checkOutput("\x1b@\x1bG\x00"); - } - - public function testSetDoubleStrikeNonBoolean() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setDoubleStrike(4); - } - - /* Font */ - public function testSetFontDefault() - { - $this -> printer -> setFont(); - $this -> checkOutput("\x1b@\x1bM\x00"); - } - - public function testSetFontAcceptedValues() - { - $this -> printer -> setFont(Printer::FONT_A); - $this -> printer -> setFont(Printer::FONT_B); - $this -> printer -> setFont(Printer::FONT_C); - $this -> checkOutput("\x1b@\x1bM\x00\x1bM\x01\x1bM\x02"); - } - - public function testSetFontNegative() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setFont(-1); - } - - - public function testSetFontTooLarge() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setFont(3); - } - - public function testSetFontNonInteger() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setFont('hello'); - } - - /* Justification */ - public function testSetJustificationDefault() - { - $this -> printer -> setJustification(); - $this -> checkOutput("\x1b@\x1ba\x00"); - } - - public function testSetJustificationLeft() - { - $this -> printer -> setJustification(Printer::JUSTIFY_LEFT); - $this -> checkOutput("\x1b@\x1ba\x00"); - } - - public function testSetJustificationRight() - { - $this -> printer -> setJustification(Printer::JUSTIFY_RIGHT); - $this -> checkOutput("\x1b@\x1ba\x02"); - } - - public function testSetJustificationCenter() - { - $this -> printer -> setJustification(Printer::JUSTIFY_CENTER); - $this -> checkOutput("\x1b@\x1ba\x01"); - } - - public function testSetJustificationNegative() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setJustification(-1); - } - - - public function testSetJustificationTooLarge() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setFont(3); - } - - public function testSetJustificationNonInteger() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setJustification('hello'); - } - - /* Reverse feed */ - public function testFeedReverseDefault() - { - $this -> printer -> feedReverse(); - $this -> checkOutput("\x1b@\x1be\x01"); - } - - public function testFeedReverse3() - { - $this -> printer -> feedReverse(3); - $this -> checkOutput("\x1b@\x1be\x03"); - } - - public function testFeedReverseNegative() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feedReverse(-1); - } - - public function testFeedReverseTooLarge() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feedReverse(256); - } - - public function testFeedReverseNonInteger() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> feedReverse('hello'); - } - - /* Cut */ - public function testCutDefault() - { - // TODO check what the accepted range of values should be for $line - // cut($mode = self::CUT_FULL, $lines = 3) - $this -> printer -> cut(); - $this -> checkOutput("\x1b@\x1dVA\x03"); - } - - /* Set barcode height */ - public function testSetBarcodeHeightDefault() - { - $this -> printer -> setBarcodeHeight(); - $this -> checkOutput("\x1b@\x1dh\x08"); - } - - public function testBarcodeHeight10() - { - $this -> printer -> setBarcodeHeight(10); - $this -> checkOutput("\x1b@\x1dh\x0a"); - } - - public function testSetBarcodeHeightNegative() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeHeight(-1); - } - - public function testSetBarcodeHeightTooLarge() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeHeight(256); - } - - public function testSetBarcodeHeightNonInteger() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeHeight('hello'); - } - - /* Set barcode width */ - public function testSetBarcodeWidthDefault() - { - $this -> printer -> setBarcodeWidth(); - $this -> checkOutput("\x1b@\x1dw\x03"); - } - - public function testBarcodeWidth1() - { - $this -> printer -> setBarcodeWidth(1); - $this -> checkOutput("\x1b@\x1dw\x01"); - } - - public function testSetBarcodeWidthNegative() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeWidth(-1); - } - - public function testSetBarcodeWidthTooLarge() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeWidth(256); - } - - public function testSetBarcodeWidthNonInteger() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeWidth('hello'); - } - - /* Barcode text position */ - public function testSetBarcodeTextPositionDefault() - { - $this -> printer -> setBarcodeTextPosition(); - $this -> checkOutput("\x1b@\x1dH\x00"); - } - - public function testSetBarcodeTextPositionBelow() - { - $this -> printer -> setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW); - $this -> checkOutput("\x1b@\x1dH\x02"); - } - - public function testSetBarcodeTextPositionBoth() - { - $this -> printer -> setBarcodeTextPosition(Printer::BARCODE_TEXT_BELOW | Printer::BARCODE_TEXT_ABOVE); - $this -> checkOutput("\x1b@\x1dH\x03"); - } - - public function testSetBarcodeTextPositionNegative() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeTextPosition(-1); - } - - public function testSetBarcodeTextPositionTooLarge() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeTextPosition(4); - } - - public function tesSetBarcodeTextPositionNonInteger() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setBarcodeTextPosition('hello'); - } - - /* Barcode - UPC-A */ - public function testBarcodeUpcaNumeric11Char() - { - $this -> printer -> barcode("01234567890", Printer::BARCODE_UPCA); - $this -> checkOutput("\x1b@\x1dkA\x0b01234567890"); - } - - public function testBarcodeUpcaNumeric12Char() - { - $this -> printer -> barcode("012345678901", Printer::BARCODE_UPCA); - $this -> checkOutput("\x1b@\x1dkA\x0c012345678901"); - } - - public function testBarcodeUpcaNumeric13Char() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("0123456789012", Printer::BARCODE_UPCA); - } - - public function testBarcodeUpcaNonNumeric12Char() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A12345678901", Printer::BARCODE_UPCA); - } - - /* Barcode - UPC-E */ - public function testBarcodeUpceNumeric6Char() - { - $this -> printer -> barcode("123456", Printer::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x06123456"); - } - - public function testBarcodeUpceNumeric7Char() - { - $this -> printer -> barcode("0123456", Printer::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x070123456"); - } - - public function testBarcodeUpceNumeric8Char() - { - $this -> printer -> barcode("01234567", Printer::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x0801234567"); - } - - public function testBarcodeUpceNumeric11Char() - { - $this -> printer -> barcode("01234567890", Printer::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x0b01234567890"); - } - - public function testBarcodeUpceNumeric12Char() - { - $this -> printer -> barcode("012345678901", Printer::BARCODE_UPCE); - $this -> checkOutput("\x1b@\x1dkB\x0c012345678901"); - } - - public function testBarcodeUpceNumeric9Char() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("012345678", Printer::BARCODE_UPCE); - } - - public function testBarcodeUpceNonNumeric12Char() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A12345678901", Printer::BARCODE_UPCE); - } - - /* Barcode - JAN13 */ - public function testBarcodeJan13Numeric12Char() - { - $this -> printer -> barcode("012345678901", Printer::BARCODE_JAN13); - $this -> checkOutput("\x1b@\x1dkC\x0c012345678901"); - } - - public function testBarcodeJan13Numeric13Char() - { - $this -> printer -> barcode("0123456789012", Printer::BARCODE_JAN13); - $this -> checkOutput("\x1b@\x1dkC\x0d0123456789012"); - } - - public function testBarcodeJan13Numeric11Char() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("01234567890", Printer::BARCODE_JAN13); - } - - public function testBarcodeJan13NonNumeric13Char() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A123456789012", Printer::BARCODE_JAN13); - } - - /* Barcode - JAN8 */ - public function testBarcodeJan8Numeric7Char() - { - $this -> printer -> barcode("0123456", Printer::BARCODE_JAN8); - $this -> checkOutput("\x1b@\x1dkD\x070123456"); - } - - public function testBarcodeJan8Numeric8Char() - { - $this -> printer -> barcode("01234567", Printer::BARCODE_JAN8); - $this -> checkOutput("\x1b@\x1dkD\x0801234567"); - } - - public function testBarcodeJan8Numeric9Char() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("012345678", Printer::BARCODE_JAN8); - } - - public function testBarcodeJan8NonNumeric8Char() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A1234567", Printer::BARCODE_JAN8); - } - - /* Barcode - Code39 */ - public function testBarcodeCode39AsDefault() - { - $this -> printer -> barcode("1234"); - $this -> checkOutput("\x1b@\x1dkE\x041234"); - } - - public function testBarcodeCode39Text() - { - $this -> printer -> barcode("ABC 012", Printer::BARCODE_CODE39); - $this -> checkOutput("\x1b@\x1dkE\x07ABC 012"); - } - - public function testBarcodeCode39SpecialChars() - { - $this -> printer -> barcode("$%+-./", Printer::BARCODE_CODE39); - $this -> checkOutput("\x1b@\x1dkE\x06$%+-./"); - } - - public function testBarcodeCode39Asterisks() - { - $this -> printer -> barcode("*TEXT*", Printer::BARCODE_CODE39); - $this -> checkOutput("\x1b@\x1dkE\x06*TEXT*"); - } - - public function testBarcodeCode39AsterisksUnmatched() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("*TEXT", Printer::BARCODE_CODE39); - } - - public function testBarcodeCode39AsteriskInText() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("12*34", Printer::BARCODE_CODE39); - } - - public function testBarcodeCode39Lowercase() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("abcd", Printer::BARCODE_CODE39); - } - - public function testBarcodeCode39Empty() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("**", Printer::BARCODE_CODE39); - } - - /* Barcode - ITF */ - public function testBarcodeItfNumericEven() - { - $this -> printer -> barcode("1234", Printer::BARCODE_ITF); - $this -> checkOutput("\x1b@\x1dkF\x041234"); - } - - public function testBarcodeItfNumericOdd() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("123", Printer::BARCODE_ITF); - } - - public function testBarcodeItfNonNumericEven() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("A234", Printer::BARCODE_ITF); - } - - /* Barcode - Codabar */ - public function testBarcodeCodabarNumeric() - { - $this -> printer -> barcode("A012345A", Printer::BARCODE_CODABAR); - $this -> checkOutput("\x1b@\x1dkG\x08A012345A"); - } - - public function testBarcodeCodabarSpecialChars() - { - $this -> printer -> barcode("A012$+-./:A", Printer::BARCODE_CODABAR); - $this -> checkOutput("\x1b@\x1dkG\x0bA012$+-./:A"); - } - - public function testBarcodeCodabarNotWrapped() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("012345", Printer::BARCODE_CODABAR); - } - - public function testBarcodeCodabarStartStopWrongPlace() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("012A45", Printer::BARCODE_CODABAR); - } - - /* Barcode - Code93 */ - public function testBarcodeCode93Valid() - { - $this -> printer -> barcode("012abcd", Printer::BARCODE_CODE93); - $this -> checkOutput("\x1b@\x1dkH\x07012abcd"); - } - - public function testBarcodeCode93Empty() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("", Printer::BARCODE_CODE93); - } - - /* Barcode - Code128 */ - public function testBarcodeCode128ValidA() - { - $this -> printer -> barcode("{A" . "012ABCD", Printer::BARCODE_CODE128); - $this -> checkOutput("\x1b@\x1dkI\x09{A012ABCD"); - } - - public function testBarcodeCode128ValidB() - { - $this -> printer -> barcode("{B" . "012ABCDabcd", Printer::BARCODE_CODE128); - $this -> checkOutput("\x1b@\x1dkI\x0d{B012ABCDabcd"); - } - - public function testBarcodeCode128ValidC() - { - $this -> printer -> barcode("{C" . chr(21) . chr(32) . chr(43), Printer::BARCODE_CODE128); - $this -> checkOutput("\x1b@\x1dkI\x05{C\x15 +"); - } - - public function testBarcodeCode128NoCodeSet() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> barcode("ABCD", Printer::BARCODE_CODE128); - } - - /* Pulse */ - function testPulseDefault() - { - $this -> printer -> pulse(); - $this -> checkOutput("\x1b@\x1bp0 printer -> pulse(1); - $this -> checkOutput("\x1b@\x1bp1 printer -> pulse(0, 2, 2); - $this -> checkOutput("\x1b@\x1bp0\x01\x01"); - } - - function testPulseOddMs() - { - $this -> printer -> pulse(0, 3, 3); // Should be rounded down and give same output - $this -> checkOutput("\x1b@\x1bp0\x01\x01"); - } - - function testPulseTooHigh() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> pulse(0, 512, 2); - } - - function testPulseTooLow() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> pulse(0, 0, 2); - } - - function testPulseNotANumber() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> pulse("fish"); - } - - /* Set reverse */ - public function testSetReverseColorsDefault() - { - $this -> printer -> setReverseColors(); - $this -> checkOutput("\x1b@\x1dB\x01"); - } - - public function testSetReverseColorsOn() - { - $this -> printer -> setReverseColors(true); - $this -> checkOutput("\x1b@\x1dB\x01"); - } - - public function testSetReverseColorsOff() - { - $this -> printer -> setReverseColors(false); - $this -> checkOutput("\x1b@\x1dB\x00"); - } - - public function testSetReverseColorsNonBoolean() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setReverseColors(7); - } - - /* Bit image print */ - public function testBitImageBlack() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_black.png"); - $this -> printer -> bitImage($img); - $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x01\x00\x80"); - } - - public function testBitImageWhite() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_white.png"); - $this -> printer -> bitImage($img); - $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x01\x00\x00"); - } - - public function testBitImageBoth() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/black_white.png"); - $this -> printer -> bitImage($img); - $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x02\x00\xc0\x00"); - } - - public function testBitImageTransparent() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/black_transparent.png"); - $this -> printer -> bitImage($img); - $this -> checkOutput("\x1b@\x1dv0\x00\x01\x00\x02\x00\xc0\x00"); - } - - /* Bit image column format */ - public function testBitImageColumnFormatBlack() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_black.png"); - $this -> printer -> bitImageColumnFormat($img); - $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x01\x00\x80\x00\x00\x0a\x1b2"); - } - - public function testBitImageColumnFormatWhite() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_white.png"); - $this -> printer -> bitImageColumnFormat($img); - $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x01\x00\x00\x00\x00\x0a\x1b2"); - } - - public function testBitImageColumnFormatBoth() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/black_white.png"); - $this -> printer -> bitImageColumnFormat($img); - $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x02\x00\x80\x00\x00\x80\x00\x00\x0a\x1b2"); - } - - public function testBitImageColumnFormatTransparent() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/black_transparent.png"); - $this -> printer -> bitImageColumnFormat($img); - $this -> checkOutput("\x1b@\x1b3\x10\x1b*!\x02\x00\x80\x00\x00\x80\x00\x00\x0a\x1b2"); - } - - /* Graphics print */ - public function testGraphicsWhite() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_white.png"); - $this -> printer -> graphics($img); - $this -> checkOutput("\x1b@\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x00\x1d(L\x02\x0002"); - } - - public function testGraphicsBlack() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/canvas_black.png"); - $this -> printer -> graphics($img); - $this -> checkOutput("\x1b@\x1d(L\x0b\x000p0\x01\x011\x01\x00\x01\x00\x80\x1d(L\x02\x0002"); - } - - public function testGraphicsBoth() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/black_white.png"); - $this -> printer -> graphics($img); - $this -> checkOutput("\x1b@\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002"); - } - - public function testGraphicsTransparent() - { - $this -> requireGraphicsLibrary(); - $img = EscposImage::load(dirname(__FILE__)."/resources/black_transparent.png"); - $this -> printer -> graphics($img); - $this -> checkOutput("\x1b@\x1d(L\x0c\x000p0\x01\x011\x02\x00\x02\x00\xc0\x00\x1d(L\x02\x0002"); - } - - /* PDF417 code */ - public function testPdf417CodeDefaults() - { - $this -> printer -> pdf417Code("1234"); - $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x00\x1d(k\x03\x000A\x00\x1d(k\x03\x000C\x03\x1d(k\x03\x000D\x03\x1d(k\x04\x000E1\x01\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0"); - } - - public function testPdf417CodeEmpty() - { - $this -> printer -> pdf417Code(''); - $this -> checkOutput("\x1b@"); // No commands actually sent - } - - public function testPdf417CodeNotSupported() - { - $this -> setExpectedException('Exception'); - $profile = SimpleCapabilityProfile::getInstance(); - $this -> printer = new Printer($this -> outputConnector, $profile); - $this -> printer -> pdf417Code("1234"); - } - - public function testPdf417CodeChangeGeometry() - { - // 7-dot wide, 4-times height, 4 data columns - $this -> printer -> pdf417Code("1234", 7, 4, 4); - $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x00\x1d(k\x03\x000A\x04\x1d(k\x03\x000C\x07\x1d(k\x03\x000D\x04\x1d(k\x04\x000E1\x01\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0"); - } - - public function testPdf417CodeChangeErrorCorrection() - { - $this -> printer -> pdf417Code("1234", 3, 3, 0, 0.5); - $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x00\x1d(k\x03\x000A\x00\x1d(k\x03\x000C\x03\x1d(k\x03\x000D\x03\x1d(k\x04\x000E1\x05\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0"); - } - - public function testPdf417CodeChangeErrorCorrectionOutOfRange() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> pdf417Code("1234", 3, 3, 0, 5.0); - } - - public function testPdf417CodeChangeErrorCorrectionInvalid() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> pdf417Code("1234", 3, 3, 0, "Foobar"); - } - - public function testPdf417CodeChangeOption() - { - // Use the alternate truncated format - $this -> printer -> pdf417Code("1234", 3, 3, 0, 0.1, Printer::PDF417_TRUNCATED); - $this -> checkOutput("\x1b@\x1d(k\x03\x000F\x01\x1d(k\x03\x000A\x00\x1d(k\x03\x000C\x03\x1d(k\x03\x000D\x03\x1d(k\x04\x000E1\x01\x1d(k\x07\x000P01234\x1d(k\x03\x000Q0"); - } - - /* QR code */ - public function testQRCodeDefaults() - { - // Test will fail if default values change - $this -> printer -> qrCode("1234"); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } - - public function testQRCodeDefaultsAreCorrect() - { - // Below tests assume that defaults are as written here (output string should be same as above) - $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_L, 3, Printer::QR_MODEL_2); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } - - public function testQRCodeEmpty() - { - $this -> printer -> qrCode(''); - $this -> checkOutput("\x1b@"); // No commands actually sent - } - - public function testQRCodeChangeEC() - { - $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_H); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E3\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } - - public function testQRCodeChangeSize() - { - $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_L, 7); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A2\x00\x1d(k\x03\x001C\x07\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } - - public function testQRCodeChangeModel() - { - $this -> printer -> qrCode("1234", Printer::QR_ECLEVEL_L, 3, Printer::QR_MODEL_1); - $this -> checkOutput("\x1b@\x1d(k\x04\x001A1\x00\x1d(k\x03\x001C\x03\x1d(k\x03\x001E0\x1d(k\x07\x001P01234\x1d(k\x03\x001Q0"); - } - - /* Feed form - Required on page-mode only printers */ - public function testFeedForm() - { - $this -> printer -> feedForm(); - $this -> checkOutput("\x1b@\x0c"); - } - - /* Release */ - public function testRelease() - { - $this -> printer -> release(); - $this -> checkOutput("\x1b@\x1b\x71"); - } - - /* Set text size */ - public function testSetTextSizeNormal() - { - $this -> printer -> setTextSize(1, 1); - $this -> checkOutput("\x1b@\x1d!\x00"); - } - - public function testSetTextSizeWide() - { - $this -> printer -> setTextSize(4, 1); - $this -> checkOutput("\x1b@\x1d!0"); - } - - public function testSetTextSizeNarrow() - { - $this -> printer -> setTextSize(1, 4); - $this -> checkOutput("\x1b@\x1d!\x03"); - } - - public function testSetTextSizeLarge() - { - $this -> printer -> setTextSize(4, 4); - $this -> checkOutput("\x1b@\x1d!3"); - } - - public function testSetTextSizeInvalid() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setTextSize(0, 9); - } - - /* Set color */ - public function testSetColorDefault() - { - $this -> printer -> setColor(Printer::COLOR_1); - $this -> checkOutput("\x1b@\x1br\x00"); - } - - public function testSetColorAlternative() - { - $this -> printer -> setColor(Printer::COLOR_2); - $this -> checkOutput("\x1b@\x1br\x01"); - } - - public function testSetColorInvalid() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setColor(3); - } - - /* Set line spacing */ - public function testSetLineSpacingDefault() - { - $this -> printer -> setLineSpacing(); - $this -> checkOutput("\x1b@\x1b2"); - } - - public function testSetLineSpacingInvalid() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setLineSpacing(300); - } - - public function testSetLineSpacingSmaller() - { - $this -> printer -> setLineSpacing(16); - $this -> checkOutput("\x1b@\x1b3\x10"); - } - - public function testSetLineSpacingLarger() - { - $this -> printer -> setLineSpacing(32); - $this -> checkOutput("\x1b@\x1b3\x20"); - } - - /* Set print width */ - public function testSetPrintWidthDefault() - { - $this -> printer -> setPrintWidth(); - $this -> checkOutput("\x1b@\x1dW\x00\x02"); - } - - public function testSetPrintWidthNarrow() - { - $this -> printer -> setPrintWidth(400); - $this -> checkOutput("\x1b@\x1dW\x90\x01"); - } - - public function testSetPrintWidthInvalid() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setPrintWidth(0); - } - - /* Set print left margin */ - public function testSetPrintLeftMarginDefault() - { - $this -> printer -> setPrintLeftMargin(); - $this -> checkOutput("\x1b@\x1dL\x00\x00"); - } - - public function testSetPrintLeftMarginWide() - { - $this -> printer -> setPrintLeftMargin(32); - $this -> checkOutput("\x1b@\x1dL\x20\x00"); - } - - public function testPrintLeftMarginInvalid() - { - $this -> setExpectedException('InvalidArgumentException'); - $this -> printer -> setPrintLeftMargin(70000); - $this -> checkOutput(); - } - - /* Upside-down print */ - public function testSetUpsideDown() - { - $this -> printer -> setUpsideDown(true); - $this -> checkOutput("\x1b@\x1b{\x01"); - } -} - -/* - * For testing that string-castable objects are handled - */ -class FooBar -{ - private $foo; - public function __construct($foo) - { - $this -> foo = $foo; - } - - public function __toString() - { - return $this -> foo; - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/FilePrintConnectorTest.php b/htdocs/includes/mike42/escpos-php/test/unit/FilePrintConnectorTest.php deleted file mode 100644 index 63728717017..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/FilePrintConnectorTest.php +++ /dev/null @@ -1,26 +0,0 @@ - finalize(); - $connector -> finalize(); // Silently do nothing if printer already closed - unlink($tmpfname); - } - - public function testReadAfterClose() - { - // Should attempt to send data to the local printer by writing to it - $this -> setExpectedException('Exception'); - $tmpfname = tempnam("/tmp", "php"); - $connector = new FilePrintConnector($tmpfname); - $connector -> finalize(); - $connector -> write("Test"); - unlink($tmpfname); - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/GdEscposImageTest.php b/htdocs/includes/mike42/escpos-php/test/unit/GdEscposImageTest.php deleted file mode 100644 index da755f7b9ee..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/GdEscposImageTest.php +++ /dev/null @@ -1,101 +0,0 @@ - setExpectedException('Exception'); - $this -> loadAndCheckImg('not a real file.png', 1, 1, null, null); - } - - /** - * @medium - */ - public function testGdEmpty() - { - $this -> loadAndCheckImg(null, 0, 0, "", array()); - } - - /** - * @medium - */ - public function testGdBlack() - { - foreach (array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('canvas_black.' . $format, 1, 1, "\x80", array("\x80")); - } - } - - /** - * @medium - */ - public function testGdBlackTransparent() - { - foreach (array('png', 'gif') as $format) { - $this -> loadAndCheckImg('black_transparent.' . $format, 2, 2, "\xc0\x00", array("\x80\x80")); - } - } - - /** - * @medium - */ - public function testGdBlackWhite() - { - foreach (array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('black_white.' . $format, 2, 2, "\xc0\x00", array("\x80\x80")); - } - } - - /** - * @medium - */ - public function testGdWhite() - { - foreach (array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('canvas_white.' . $format, 1, 1, "\x00", array("\x00")); - } - } - - /** - * Load an EscposImage with (optionally) certain libraries disabled and run a check. - */ - private function loadAndCheckImg($fn, $width, $height, $rasterFormat = null, $columnFormat = null) - { - if (!EscposImage::isGdLoaded()) { - $this -> markTestSkipped("imagick plugin is required for this test"); - } - $onDisk = ($fn === null ? null : (dirname(__FILE__) . "/resources/$fn")); - // With optimisations - $imgOptimised = new GdEscposImage($onDisk, true); - $this -> checkImg($imgOptimised, $width, $height, $rasterFormat, $columnFormat); - // ... and without - $imgUnoptimised = new GdEscposImage($onDisk, false); - $this -> checkImg($imgUnoptimised, $width, $height, $rasterFormat, $columnFormat); - } - - /** - * Check image against known width, height, output. - */ - private function checkImg(EscposImage $img, $width, $height, $rasterFormatExpected = null, $columnFormatExpected = null) - { - $rasterFormatActual = $img -> toRasterFormat(); - $columnFormatActual = $img -> toColumnFormat(); - if ($rasterFormatExpected === null) { - echo "\nImage was: " . $img -> getWidth() . "x" . $img -> getHeight() . ", raster data \"" . friendlyBinary($rasterFormatActual) . "\""; - } - if ($columnFormatExpected === null) { - echo "\nImage was: " . $img -> getWidth() . "x" . $img -> getHeight() . ", column data \"" . friendlyBinary($columnFormatActual) . "\""; - } - $this -> assertTrue($img -> getHeight() == $height); - $this -> assertTrue($img -> getWidth() == $width); - $this -> assertTrue($rasterFormatExpected === $rasterFormatActual); - $this -> assertTrue($columnFormatExpected === $columnFormatActual); - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/ImagickEscposImageTest.php b/htdocs/includes/mike42/escpos-php/test/unit/ImagickEscposImageTest.php deleted file mode 100644 index 76831f761c6..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/ImagickEscposImageTest.php +++ /dev/null @@ -1,142 +0,0 @@ - setExpectedException('Exception'); - $this -> loadAndCheckImg('not a real file.png', 1, 1, null, null); - } - - /** - * @medium - */ - public function testImagickEmpty() - { - $this -> loadAndCheckImg(null, 0, 0, "", array()); - } - - /** - * @medium - */ - public function testImagickBlack() - { - foreach (array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('canvas_black.' . $format, 1, 1, "\x80", array("\x80")); - } - } - - /** - * @medium - */ - public function testImagickBlackTransparent() - { - foreach (array('png', 'gif') as $format) { - $this -> loadAndCheckImg('black_transparent.' . $format, 2, 2, "\xc0\x00", array("\x80\x80")); - } - } - - /** - * @medium - */ - public function testImagickBlackWhite() - { - foreach (array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('black_white.' . $format, 2, 2, "\xc0\x00", array("\x80\x80")); - } - } - - /** - * @medium - */ - public function testImagickBlackWhiteTall() - { - // We're very interested in correct column format chopping here at 8 pixels - $this -> loadAndCheckImg('black_white_tall.png', 2, 16, - "\xc0\xc0\xc0\xc0\xc0\xc0\xc0\xc0\x00\x00\x00\x00\x00\x00\x00\x00", array("\xff\xff", "\x00\x00")); - } - - /** - * @medium - */ - public function testImagickWhite() - { - foreach (array('png', 'jpg', 'gif') as $format) { - $this -> loadAndCheckImg('canvas_white.' . $format, 1, 1, "\x00", array("\x00")); - } - } - - /** - * PDF test - load tiny PDF and check for well-formedness - * These are also skipped if you don't have imagick - * @medium - */ - public function testPdfAllPages() - { - $this -> loadAndCheckPdf('doc.pdf', 1, 1, array("\x00", "\x80"), array(array("\x00"), array("\x80"))); - } - - public function testPdfBadFilename() - { - $this -> setExpectedException('Exception'); - $this -> loadAndCheckPdf('not a real file', 1, 1, array(), array()); - } - - /** - * Load an EscposImage and run a check. - */ - private function loadAndCheckImg($fn, $width, $height, $rasterFormat = null, $columnFormat = null) - { - if (!EscposImage::isImagickLoaded()) { - $this -> markTestSkipped("imagick plugin is required for this test"); - } - $onDisk = ($fn === null ? null : (dirname(__FILE__) . "/resources/$fn")); - // With optimisations - $imgOptimised = new ImagickEscposImage($onDisk, true); - $this -> checkImg($imgOptimised, $width, $height, $rasterFormat, $columnFormat); - // ... and without - $imgUnoptimised = new ImagickEscposImage($onDisk, false); - $this -> checkImg($imgUnoptimised, $width, $height, $rasterFormat, $columnFormat); - } - - /** - * Same as above, loading document and checking pages against some expected values. - */ - private function loadAndCheckPdf($fn, $width, $height, array $rasterFormat = null, array $columnFormat = null) - { - if (!EscposImage::isImagickLoaded()) { - $this -> markTestSkipped("imagick plugin required for this test"); - } - $pdfPages = ImagickEscposImage::loadPdf(dirname(__FILE__) . "/resources/$fn", $width); - $this -> assertTrue(count($pdfPages) == count($rasterFormat), "Got back wrong number of pages"); - foreach ($pdfPages as $id => $img) { - $this -> checkImg($img, $width, $height, $rasterFormat[$id], $columnFormat[$id]); - } - } - - /** - * Check image against known width, height, output. - */ - private function checkImg(EscposImage $img, $width, $height, $rasterFormatExpected = null, $columnFormatExpected = null) - { - $rasterFormatActual = $img -> toRasterFormat(); - $columnFormatActual = $img -> toColumnFormat(); - if ($rasterFormatExpected === null) { - echo "\nImage was: " . $img -> getWidth() . "x" . $img -> getHeight() . ", raster data \"" . friendlyBinary($rasterFormatActual) . "\""; - } - if ($columnFormatExpected === null) { - echo "\nImage was: " . $img -> getWidth() . "x" . $img -> getHeight() . ", column data \"" . friendlyBinary($columnFormatActual) . "\""; - } - $this -> assertEquals($height , $img -> getHeight()); - $this -> assertEquals($width, $img -> getWidth()); - $this -> assertEquals($rasterFormatExpected, $rasterFormatActual, "Raster format did not match expected"); - $this -> assertEquals($columnFormatExpected, $columnFormatActual, "Column format did not match expected"); - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/LegacyCapabilityProfileTest.php b/htdocs/includes/mike42/escpos-php/test/unit/LegacyCapabilityProfileTest.php deleted file mode 100644 index 360dee90fe7..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/LegacyCapabilityProfileTest.php +++ /dev/null @@ -1,79 +0,0 @@ - profiles = array( - 'Mike42\Escpos\CapabilityProfiles\DefaultCapabilityProfile', - 'Mike42\Escpos\CapabilityProfiles\EposTepCapabilityProfile', - 'Mike42\Escpos\CapabilityProfiles\SimpleCapabilityProfile', - 'Mike42\Escpos\CapabilityProfiles\StarCapabilityProfile', - 'Mike42\Escpos\CapabilityProfiles\P822DCapabilityProfile'); - $this -> checklist = array(); - foreach ($this -> profiles as $profile) { - $this-> checklist[] = $profile::getInstance(); - } - } - - function testSupportedCodePages() - { - foreach ($this -> checklist as $obj) { - $check = $obj -> getCodePages(); - $this -> assertTrue(is_array($check) && isset($check[0])); - foreach ($check as $num => $page) { - $this -> assertTrue(is_numeric($num)); - } - } - } - - function testText() { - /* Smoke test over text rendering with each profile. - * Just makes sure we can attempt to print 'hello world' and a non-ASCII - * char without anything blowing up */ - foreach ($this -> checklist as $obj) { - $connector = new DummyPrintConnector(); - $printer = new Printer($connector, $obj); - $printer -> text("Hello world €\n"); - $printer -> close(); - // Check for character cache - $profileName = $obj -> getId(); - $expected = "Characters-$profileName.ser.z"; - $filename = __DIR__ . "/../../src/Mike42/Escpos/PrintBuffers/cache/$expected"; - $this -> assertFileExists($filename); - } - } - - function testSupportsBitImageRaster() - { - foreach ($this -> checklist as $obj) { - $check = $obj -> getSupportsBitImageRaster(); - $this -> assertTrue(is_bool($check)); - } - } - - function testSupportsGraphics() - { - foreach ($this -> checklist as $obj) { - $check = $obj -> getSupportsGraphics(); - $this -> assertTrue(is_bool($check)); - } - } - - function testSupportsQrCode() - { - foreach ($this -> checklist as $obj) { - $check = $obj -> getSupportsQrCode(); - $this -> assertTrue(is_bool($check)); - } - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/UriPrintConnectorTest.php b/htdocs/includes/mike42/escpos-php/test/unit/UriPrintConnectorTest.php deleted file mode 100644 index 715dd8d77de..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/UriPrintConnectorTest.php +++ /dev/null @@ -1,59 +0,0 @@ - write("AAA"); - $connector -> finalize(); - $this -> assertEquals("AAA", file_get_contents($filename)); - $this -> assertEquals('Mike42\Escpos\PrintConnectors\FilePrintConnector', get_class($connector)); - unlink($filename); - } - - /** - * @expectedException PHPUnit_Framework_Error - * @expectedExceptionMessage not finalized - */ - public function testSmb() - { - $connector = UriPrintConnector::get("smb://windows/printer"); - $this -> assertEquals('Mike42\Escpos\PrintConnectors\WindowsPrintConnector', get_class($connector)); - // We expect that this will throw an exception, we can't - // realistically print to a real printer in this test though... :) - $connector -> __destruct(); - } - - /** - * @expectedException InvalidArgumentException - * @expectedExceptionMessage Malformed connector URI - */ - public function testBadUri() - { - $connector = UriPrintConnector::get("foooooo"); - } - - /** - * @expectedException Exception - * @expectedExceptionMessage Connection refused - */ - public function testNetwork() - { - // Port should be closed so we can catch an error and move on - $connector = UriPrintConnector::get("tcp://localhost:45987/"); - } - - /** - * @expectedException InvalidArgumentException - * @expectedExceptionMessage URI sheme is not supported: ldap:// - */ - public function testUnsupportedUri() - { - // Try to print to something silly - $connector = UriPrintConnector::get("ldap://host:1234/"); - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/WindowsPrintConnectorTest.php b/htdocs/includes/mike42/escpos-php/test/unit/WindowsPrintConnectorTest.php deleted file mode 100644 index f6e10fae5f5..00000000000 --- a/htdocs/includes/mike42/escpos-php/test/unit/WindowsPrintConnectorTest.php +++ /dev/null @@ -1,304 +0,0 @@ - getMockConnector("LPT1", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runWrite') - -> with($this -> equalTo(''), $this -> equalTo("LPT1")); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } - - public function testLptMac() - { - // Cannot print to local printer on Mac with this connector - $this -> setExpectedException('BadMethodCallException'); - $connector = $this -> getMockConnector("LPT1", WindowsPrintConnector::PLATFORM_MAC); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } - - public function testLptLinux() - { - // Cannot print to local printer on Linux with this connector - $this -> setExpectedException('BadMethodCallException'); - $connector = $this -> getMockConnector("LPT1", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } - - public function testComWindows() - { - // Simple file write - $connector = $this -> getMockConnector("COM1", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runWrite') - -> with($this -> equalTo(''), $this -> equalTo("COM1")); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } - - public function testComMac() - { - // Cannot print to local printer on Mac with this connector - $this -> setExpectedException('BadMethodCallException'); - $connector = $this -> getMockConnector("COM1", WindowsPrintConnector::PLATFORM_MAC); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } - - public function testComLinux() - { - // Cannot print to local printer on Linux with this connector - $this -> setExpectedException('BadMethodCallException'); - $connector = $this -> getMockConnector("COM1", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } - - public function testLocalShareWindows() - { - $connector = $this -> getMockConnector("Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> stringContains('\\Printer')); - $connector -> finalize(); - } - - public function testSharedPrinterWindows() - { - $connector = $this -> getMockConnector("smb://example-pc/Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); - $connector -> finalize(); - } - - public function testSharedPrinterWindowsUsername() - { - $connector = $this -> getMockConnector("smb://bob@example-pc/Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('net use \'\\\\example-pc\\Printer\' \'/user:bob\'')); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); - $connector -> finalize(); - } - - public function testSharedPrinterWindowsUsernameDomain() - { - $connector = $this -> getMockConnector("smb://bob@example-pc/home/Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('net use \'\\\\example-pc\\Printer\' \'/user:home\\bob\'')); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); - $connector -> finalize(); - } - - public function testSharedPrinterWindowsUsernamePassword() - { - $connector = $this -> getMockConnector("smb://bob:secret@example-pc/Printer", WindowsPrintConnector::PLATFORM_WIN); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('net use \'\\\\example-pc\\Printer\' \'/user:bob\' \'secret\'')); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> once()) - -> method('runCopy') - -> with($this -> anything(), $this -> equalTo('\\\\example-pc\\Printer')); - $connector -> finalize(); - } - - public function testSharedPrinterMac() - { - // Not implemented - $this -> setExpectedException('Exception'); - $connector = $this -> getMockConnector("smb://Guest@example-pc/Printer", WindowsPrintConnector::PLATFORM_MAC); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> expects($this -> exactly(0)) - -> method('runCommand'); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> finalize(); - } - - public function testSharedPrinterLinux() - { - $connector = $this -> getMockConnector("smb://example-pc/Printer", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('smbclient \'//example-pc/Printer\' -c \'print -\' -N -m SMB2')); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> finalize(); - } - - public function testSharedPrinterLinuxUsername() - { - $connector = $this -> getMockConnector("smb://bob@example-pc/Printer", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('smbclient \'//example-pc/Printer\' -U \'bob\' -c \'print -\' -N -m SMB2')); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> finalize(); - } - - public function testSharedPrinterLinuxUsernameDomain() - { - $connector = $this -> getMockConnector("smb://bob@example-pc/home/Printer", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('smbclient \'//example-pc/Printer\' -U \'home\\bob\' -c \'print -\' -N -m SMB2')); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> finalize(); - } - - public function testSharedPrinterLinuxUsernamePassword() - { - $connector = $this -> getMockConnector("smb://bob:secret@example-pc/Printer", WindowsPrintConnector::PLATFORM_LINUX); - $connector -> expects($this -> once()) - -> method('runCommand') - -> with($this -> equalTo('smbclient \'//example-pc/Printer\' \'secret\' -U \'bob\' -c \'print -\' -m SMB2')); - $connector -> expects($this -> exactly(0)) - -> method('runCopy'); - $connector -> expects($this -> exactly(0)) - -> method('runWrite'); - $connector -> finalize(); - } - - private function getMockConnector($path, $platform) - { - $stub = $this -> getMockBuilder('Mike42\Escpos\PrintConnectors\WindowsPrintConnector') - -> setMethods(array('runCopy', 'runCommand', 'getCurrentPlatform', 'runWrite')) - -> disableOriginalConstructor() - -> getMock(); - $stub -> method('runCommand') - -> willReturn(0); - $stub -> method('runCopy') - -> willReturn(true); - $stub -> method('runWrite') - -> willReturn(true); - $stub -> method('getCurrentPlatform') - -> willReturn($platform); - $stub -> __construct($path); - return $stub; - } - - /** - * Test for correct identification of bogus or non-supported Samba strings. - */ - public function testSambaRegex() - { - $good = array("smb://foo/bar", - "smb://foo/bar baz", - "smb://bob@foo/bar", - "smb://bob:secret@foo/bar", - "smb://foo-computer/FooPrinter", - "smb://foo-computer/workgroup/FooPrinter", - "smb://foo-computer/Foo-Printer", - "smb://foo-computer/workgroup/Foo-Printer", - "smb://foo-computer/Foo Printer", - "smb://foo-computer.local/Foo Printer", - "smb://127.0.0.1/abcd" - ); - $bad = array("", - "http://google.com", - "smb:/foo/bar", - "smb://", - "smb:///bar", - "smb://@foo/bar", - "smb://bob:@foo/bar", - "smb://:secret@foo/bar", - "smb://foo/bar/baz/quux", - "smb://foo-computer//FooPrinter"); - foreach ($good as $item) { - $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_SMB, $item) == 1, "Windows samba regex should pass '$item'."); - } - foreach ($bad as $item) { - $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_SMB, $item) != 1, "Windows samba regex should fail '$item'."); - } - } - - public function testPrinterNameRegex() - { - $good = array("a", - "ab", - "a b", - "a-b", - "Abcd Efg-", - "-a", - "OK1" - ); - $bad = array("", - " ", - "a ", - " a", - " a ", - "a/B", - "A:b" - ); - foreach ($good as $item) { - $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_PRINTERNAME, $item) == 1, "Windows printer name regex should pass '$item'."); - } - foreach ($bad as $item) { - $this -> assertTrue(preg_match(WindowsPrintConnector::REGEX_PRINTERNAME, $item) != 1, "Windows printer name regex should fail '$item'."); - } - } -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/black_transparent.gif b/htdocs/includes/mike42/escpos-php/test/unit/resources/black_transparent.gif deleted file mode 100644 index 6c54bad9eea0d1cd39e55504d181b6607b6028d4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65 zcmZ?wbhEHbWMW`q_`m=Kia%Kx85kHD6#of27o{eaq^2m8XO?6rxO@5rFzA33fs`{a LF|!D<>&kwgnNLhfd<&=O9H5Y7iEBiObAE1aYF-J0b5UwyNotBh zd1gt5g1e`0KzJjcI8YJ4r;B3<$MxitgoGdG8+aJ_#26XR&Dh)tlw$C7^>bP0l+XkK D$`C0q diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.bmp b/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.bmp deleted file mode 100644 index 0acbf66506f8ae152df4bfabc835e03505112878..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 ycmZ?r?P7p{Dj<~u#7t1k$RGih5CD?G+z<>F01{5_LB%jOu{6kBWbhvh5F!BXKMAt{ diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.gif b/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.gif deleted file mode 100644 index 0a044a671f59c3c4a5f859eb6a09a71d809be683..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 65 zcmZ?wbhEHbWMW`q_`t{j1poj4SNzEWVlgQG6Lc<0O)N=GQ7F$W$xv|j^bKIp0m*=r NGcYl;2(dC)0{}064pjgE diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.jpg b/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.jpg deleted file mode 100644 index 6539cece59e6c5ce41bf50f1ced121096ead5aed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmex=>ukC3pCfH06P@c#e52OWR?s5zX<@pgBjQW diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.png b/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white.png deleted file mode 100644 index 33ba331fa1e8642247b0cd1e48e03e7bb24a624b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmeAS@N?(olHy`uVBq!ia0vp^Od!kwBL7~QRScv!3p^r$G`BDaGcwGYBLNg-FY)ws zWxvnN$08&+x9_71P)M@GHKN2hKQ}iuuY|$5C^fMpHASI3vm`^o-P1Q9ypc~Fs7TDy o#W95AdU65;{Q3Xio|&1MfuD`(|Am>%Vn7uPp00i_>zopr06?22>i_@% diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white_tall.png b/htdocs/includes/mike42/escpos-php/test/unit/resources/black_white_tall.png deleted file mode 100644 index 7e0869dcbed532acfd38204f6539d22d93b515ef..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Ea0U|e_vV07rI14-?iy0WWg+Z8+Vb&Z8pdfpR zr>`sfBW7Mkas6JV#5+JC+02lL66gHf+|;}hAeVu`xhOTUBsE2$JhLQ2!QIn0AVn{g z9Vjm0>Eal|aXmRff#2ZY|NrwF8yh(fDbHhKSlq|V+q`4SH;`seS3j3^P6uW{_V`Jfl cv@|t`v^2H_GiP$za9w9siRm{&HU*ox0Ab1$MF0Q* diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_black.gif b/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_black.gif deleted file mode 100644 index 49b19dbc179f5995e4ff5338e7039d3a47b4a888..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72 zcmZ?wbhEHbWMp7u_`t{j1poj4SNzEWVlgQG=l0A^Oi%SqOwUZt=1ot`%}um5&@(YL UF*Rk-0jU6KV_;%(VPvod0K2{rbpQYW diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_black.jpg b/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_black.jpg deleted file mode 100644 index d059f431b267596da878937214280915c89f51ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 160 zcmZ9GK@P$|3!+y-7X048hz>mPHCTnRfR>gOhxmUMTR+ao=IO?3^7bqx(d49u-eEv*bK owG9oe3=Ayq=dVT4kei>9nO2EggGbYKL7)Z(Pgg&ebxsLQ05fwqK>z>% diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.bmp b/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.bmp deleted file mode 100644 index e47e0ef617583acde08ae6d8ddf8045fb1a4e55e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142 zcmZ?r?PGv|E+AC{#Eft(0hV9^ljy{M1_lTMN&I(m4=Qdr^i?Bahn%QF>uW{_V`Jfl hv@|t`v^2H_GiP$za9w9siRm{&HU-_>|Ns9p003&i7eW94 diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.gif b/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.gif deleted file mode 100644 index 7881ce629acf8d6918eb5ac07169bc67b99a904b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72 zcmZ?wbhEHbWMp7u_`t{j1poj4SNzEWVlgQG=l0A^Oi%SqOwUZt=1ot`%}um5&@(YL UF*Rk-0jU6KV_;(PVPvod0K480eEnh z;e>7%gm;ZT^#P}}Pr|CgB3h=RdCVe19mdJ5nwEK)ZE4y3hRm@?RN;3VV)+M&*8W@g M3*4UIi0j**UsypDH2?qr diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.png b/htdocs/includes/mike42/escpos-php/test/unit/resources/canvas_white.png deleted file mode 100644 index 4231a4bb5400c5554d146b0f8b32b717c109c1bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^j35jm7|ip2ssJgLbVpxD28NCO++aH!(Ecb readImage("doc.pdf[5]"); - $im -> destroy(); -} catch (ImagickException $e) { - echo "Error: " . $e -> getMessage() . "\n"; -} - -$im = new Imagick(); -try { - ob_start(); - @$im -> readImage("doc.pdf[5]"); - ob_end_clean(); - $im -> destroy(); -} catch (ImagickException $e) { - echo "Error: " . $e -> getMessage() . "\n"; -} diff --git a/htdocs/includes/mike42/escpos-php/test/unit/resources/doc.pdf b/htdocs/includes/mike42/escpos-php/test/unit/resources/doc.pdf deleted file mode 100644 index 22247b918dbbcbfb0981d9442c966c99a47361b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6681 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 bQ5=#CZ9g8L&gBcKi39DzR8)+usIdP4$C)m7 From d797ea590e94770d77f7e08563540c5d482eeaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 3 Nov 2019 00:50:58 +0100 Subject: [PATCH 03/10] rework an experimental module --- COPYRIGHT | 8 +- htdocs/admin/receiptprinter.php | 37 ++--- htdocs/core/class/dolreceiptprinter.class.php | 131 ++++++++++-------- htdocs/langs/en_US/receiptprinter.lang | 3 + htdocs/takepos/admin/setup.php | 10 ++ htdocs/takepos/admin/terminal.php | 15 ++ htdocs/takepos/invoice.php | 21 ++- htdocs/takepos/takepos.php | 22 ++- 8 files changed, 161 insertions(+), 86 deletions(-) diff --git a/COPYRIGHT b/COPYRIGHT index 1af09e6fdaf..fe707c1d63d 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -2,7 +2,7 @@ License ------- -Dolibarr is released under the terms of the GNU General Public License as +Dolibarr is released under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version (GPL-3+). More information: https://www.gnu.org/licenses/gpl-3.0.txt @@ -15,13 +15,13 @@ PHP libraries: AdoDb-Date 0.36 Modified BSD License Yes Date convertion (not into rpm package) CKEditor 4.12.1 LGPL-2.1+ Yes Editor WYSIWYG EvalMath 1.0 BSD Yes Safe math expressions evaluation -Escpos-php ? MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers +Escpos-php 2.2 MIT License Yes Thermal receipt printer library, for use with ESC/POS compatible printers GeoIP 1.4 LGPL-2.1+ Yes Sample code to make geoip convert (not into deb package) Mobiledetect 2.8.33 MIT License Yes Detect mobile devices browsers NuSoap 0.9.5 LGPL 2.1+ Yes Library to develop SOAP Web services (not into rpm and deb package) PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency ParseDown 1.6 MIT License Yes Markdown parser -PHPDebugBar 1.15.0 MIT License Yes Used only by the module "debugbar" for developers +PHPDebugBar 1.15.0 MIT License Yes Used only by the module "debugbar" for developers PHPExcel 1.8.1 LGPL-2.1+ Yes Read/Write XLS files, read ODS files PHPSpreadSheet ? LGPL-2.1+ Yes Read/Write XLS files, read ODS files php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP @@ -37,7 +37,7 @@ TCPDF 6.3.2 LGPL-3+ Yes TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement JS libraries: -Ace 1.4.6 BSD Yes JS library to get code syntaxique coloration in a textarea. +Ace 1.4.6 BSD Yes JS library to get code syntaxique coloration in a textarea. jQuery 3.4.1 MIT License Yes JS library jQuery UI 1.12.1 GPL and MIT License Yes JS library plugin UI jQuery select2 4.0.5 GPL and Apache License Yes JS library plugin for sexier multiselect diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index 42b0ecb9ea9..e01fc4402a8 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -174,14 +174,19 @@ if ($action == 'testtemplate' && $user->admin) { // } // if (! $error) { - // // test - // $ret = $printer->sendTestToPrinter($printerid); - // if ($ret == 0) { - setEventMessages($langs->trans("TestTemplateToPrinter", $printername), null); - // } else { - // setEventMessages($printer->error, $printer->errors, 'errors'); - // } - // } + // test + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $object = new Facture($db); + //$object->initAsSpecimen(); + $object->fetch(8); + //var_dump($object->lines); + $ret = $printer->sendToPrinter($object, $templateid, 1); + if ($ret == 0) { + setEventMessages($langs->trans("TestTemplateToPrinter", $printername), null); + } else { + setEventMessages($printer->error, $printer->errors, 'errors'); + } + //} $action = ''; } @@ -310,7 +315,7 @@ if ($mode == 'config' && $user->admin) { } } - if ($action!='editprinter') { + if ($action != 'editprinter') { if ($nbofprinters > 0) { print ''; print ''.$langs->trans("Name").''; @@ -446,7 +451,7 @@ if ($mode == 'template' && $user->admin) { } print ''; print '

'; - print ''."\n"; + print '
'."\n"; print ''; print ''; print ''; @@ -462,18 +467,6 @@ if ($mode == 'template' && $user->admin) { dol_fiche_end(); } -// to remove after test -// $object=new stdClass(); -// $object->date_time = '2015-11-02 22:30:25'; -// $object->id = 1234; -// $object->customer_firstname = 'John'; -// $object->customer_lastname = 'Deuf'; -// $object->vendor_firstname = 'Jim'; -// $object->vendor_lastname = 'Big'; -// $object->barcode = '3700123862396'; -//$printer->sendToPrinter($object, 1, 16); -//setEventMessages($printer->error, $printer->errors, 'errors'); - // End of page llxFooter(); $db->close(); diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index 1f9ea78bf95..c18c6e0be9b 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -59,12 +59,12 @@ * Print payment method * Print logo stored on printer. Example : 32|32 * Print logo stored on printer. Must be followed by logo code. For old printers. - * Print order lines - * Print order total tax - * Print order local tax - * Print order total - * Print order number - * Print order number after validation + * Print object lines + * Print object total tax + * Print object local tax + * Print object total + * Print object number + * Print object number after validation * Print customer firstname * Print customer name * Print customer mail @@ -77,15 +77,15 @@ * Print vendor firstname * Print vendor mail * Print customer points - * Print number of points for this order + * Print number of points for this object * * Conditional code at line start (if�then Print) - * Print the line IF a customer is affected to the order - * Print the line IF a vendor is affected to the order + * Print the line IF a customer is affected to the object + * Print the line IF a vendor is affected to the object * Print the line IF Happy Hour - * Print the line IF order is validated + * Print the line IF object is validated * Print the line IF customer points > 0 - * Print the line IF points of the order > 0 + * Print the line IF points of the object > 0 * Print the line IF customer has vat number * Print the line IF customer balance > 0 * @@ -141,6 +141,7 @@ class dolReceiptPrinter extends Printer { $this->db=$db; $this->tags = array( + 'dol_line_feed', 'dol_align_left', 'dol_align_center', 'dol_align_right', @@ -167,7 +168,8 @@ class dolReceiptPrinter extends Printer 'dol_cut_paper_full', 'dol_cut_paper_partial', 'dol_open_drawer', - 'dol_activate_buzzer', + //'dol_activate_buzzer', + 'dol_print_text', 'dol_print_qrcode', 'dol_print_date', 'dol_print_date_time', @@ -181,12 +183,14 @@ class dolReceiptPrinter extends Printer 'dol_print_payment', 'dol_print_logo', 'dol_print_logo_old', - 'dol_print_order_lines', - 'dol_print_order_tax', - 'dol_print_order_local_tax', - 'dol_print_order_total', - 'dol_print_order_number', - 'dol_print_order_number_unique', + 'dol_print_object_id', + 'dol_print_object_ref', + 'dol_print_object_lines', + 'dol_print_object_tax', + 'dol_print_object_local_tax', + 'dol_print_object_total', + 'dol_print_object_number', + 'dol_print_object_number_unique', 'dol_print_customer_firstname', 'dol_print_customer_lastname', 'dol_print_customer_mail', @@ -199,13 +203,13 @@ class dolReceiptPrinter extends Printer 'dol_print_vendor_firstname', 'dol_print_vendor_mail', 'dol_print_customer_points', - 'dol_print_order_points', + 'dol_print_object_points', 'dol_print_if_customer', 'dol_print_if_vendor', 'dol_print_if_happy_hour', - 'dol_print_if_num_order_unique', + 'dol_print_if_num_object_unique', 'dol_print_if_customer_points', - 'dol_print_if_order_points', + 'dol_print_if_object_points', 'dol_print_if_customer_tax_number', 'dol_print_if_customer_account_balance_positive', ); @@ -521,12 +525,13 @@ class dolReceiptPrinter extends Printer */ public function sendToPrinter($object, $templateid, $printerid) { - global $conf; + global $conf, $mysoc; $error = 0; $ret = $this->loadTemplate($templateid); // tags a remplacer par leur valeur avant de parser - $this->template = str_replace('', $object->id, $this->template); + $this->template = str_replace('', $object->id, $this->template); + $this->template = str_replace('', $object->ref, $this->template); $this->template = str_replace('', $object->customer_firstname, $this->template); $this->template = str_replace('', $object->customer_lastname, $this->template); $this->template = str_replace('', $object->customer_mail, $this->template); @@ -536,7 +541,7 @@ class dolReceiptPrinter extends Printer $this->template = str_replace('', $object->customer_tax_number, $this->template); $this->template = str_replace('', $object->customer_account_balance, $this->template); $this->template = str_replace('', $object->customer_points, $this->template); - $this->template = str_replace('', $object->order_points, $this->template); + $this->template = str_replace('', $object->object_points, $this->template); $this->template = str_replace('', $object->vendor_firstname, $this->template); $this->template = str_replace('', $object->vendor_lastname, $this->template); $this->template = str_replace('', $object->vendor_mail, $this->template); @@ -558,78 +563,92 @@ class dolReceiptPrinter extends Printer //print '
'.print_r($vals, true).'
'; // print ticket $level = 0; - $html = '
'.$langs->trans("Tag").''.$langs->trans("Description").'
';
+        $nbcaractbyline = 47;
         $ret = $this->initPrinter($printerid);
         if ($ret>0) {
             setEventMessages($this->error, $this->errors, 'errors');
         } else {
             $nboflines = count($vals);
-            for ($line=0; $line < $nboflines; $line++) {
-                switch ($vals[$line]['tag']) {
+            for ($tplline=0; $tplline < $nboflines; $tplline++) {
+                //var_dump($vals[$tplline]['value']);
+                switch ($vals[$tplline]['tag']) {
+                    case 'DOL_PRINT_TEXT':
+                        $this->printer->text($vals[$tplline]['value']);
+                        break;
+                    case 'DOL_PRINT_OBJECT_LINES':
+                        foreach ($object->lines as $line) {
+                            $spacestoadd = $nbcaractbyline - strlen($line->ref) - strlen(price($line->total_ttc, 'MT'));
+                            $spaces = str_repeat(' ', $spacestoadd);
+                            $this->printer->text($line->ref.$spaces.price($line->total_ttc, 'MT')."\n");
+                            //var_dump($line->ref);
+                        }
+                        break;
+                    case 'DOL_LINE_FEED':
+                        $this->printer->feed();
+                        break;
                     case 'DOL_ALIGN_CENTER':
-                        $this->printer->setJustification(Escpos::JUSTIFY_CENTER);
-                        $html.='
'; - $this->printer->text($vals[$line]['value']); + $this->printer->setJustification(Printer::JUSTIFY_CENTER); break; case 'DOL_ALIGN_RIGHT': - $this->printer->setJustification(Escpos::JUSTIFY_RIGHT); - $html.=''; + $this->printer->setJustification(Printer::JUSTIFY_RIGHT); break; case 'DOL_ALIGN_LEFT': - $this->printer->setJustification(Escpos::JUSTIFY_LEFT); - $html.=''; + $this->printer->setJustification(Printer::JUSTIFY_LEFT); break; case 'DOL_OPEN_DRAWER': $this->printer->pulse(); - $html.= ' ϟ'.nl2br($vals[$line]['value']); break; case 'DOL_ACTIVATE_BUZZER': //$this->printer->buzzer(); - $html.= ' ♫'.nl2br($vals[$line]['value']); break; case 'DOL_PRINT_BARCODE': - // $vals[$line]['value'] -> barcode($content, $type) + // $vals[$tplline]['value'] -> barcode($content, $type) $this->printer->barcode($object->barcode); break; + case 'DOL_PRINT_LOGO': + // $vals[$tplline]['value'] -> barcode($content, $type) + $img = EscposImage::load(DOL_DATA_ROOT .'/mycompany/logos/'.$mysoc->logo); + $this->printer->graphics($img); + break; + case 'DOL_PRINT_LOGO_OLD': + // $vals[$tplline]['value'] -> barcode($content, $type) + $img = EscposImage::load(DOL_DATA_ROOT .'/mycompany/logos/'.$mysoc->logo); + $this->printer->bitImage($img); + break; case 'DOL_PRINT_BARCODE_CUSTOMER_ID': - // $vals[$line]['value'] -> barcode($content, $type) + // $vals[$tplline]['value'] -> barcode($content, $type) $this->printer->barcode($object->customer_id); break; case 'DOL_PRINT_QRCODE': - // $vals[$line]['value'] -> qrCode($content, $ec, $size, $model) - $this->printer->qrcode($vals[$line]['value']); - $html.='QRCODE: '.$vals[$line]['value']; + // $vals[$tplline]['value'] -> qrCode($content, $ec, $size, $model) + $this->printer->qrcode($vals[$tplline]['value']); break; case 'DOL_CUT_PAPER_FULL': - $this->printer->cut(Escpos::CUT_FULL); - $html.= ' ✂'.nl2br($vals[$line]['value']); + $this->printer->cut(Printer::CUT_FULL); break; case 'DOL_CUT_PAPER_PARTIAL': - $this->printer->cut(Escpos::CUT_PARTIAL); - $html.= ' ✂'.nl2br($vals[$line]['value']); + $this->printer->cut(Printer::CUT_PARTIAL); break; case 'DOL_USE_FONT_A': - $this->printer->setFont(Escpos::FONT_A); - $this->printer->text($vals[$line]['value']); + $this->printer->setFont(Printer::FONT_A); + $this->printer->text($vals[$tplline]['value']); break; case 'DOL_USE_FONT_B': - $this->printer->setFont(Escpos::FONT_B); - $this->printer->text($vals[$line]['value']); + $this->printer->setFont(Printer::FONT_B); + $this->printer->text($vals[$tplline]['value']); break; case 'DOL_USE_FONT_C': - $this->printer->setFont(Escpos::FONT_C); - $this->printer->text($vals[$line]['value']); + $this->printer->setFont(Printer::FONT_C); + $this->printer->text($vals[$tplline]['value']); break; default: - $this->printer->text($vals[$line]['value']); - $html.= nl2br($vals[$line]['value']); - $this->errors[] = 'UnknowTag: <'.strtolower($vals[$line]['tag']).'>'; + $this->printer->text($vals[$tplline]['value']); + $html.= nl2br($vals[$tplline]['value']); + $this->errors[] = 'UnknowTag: <'.strtolower($vals[$tplline]['tag']).'>'; $error++; break; } } - $html.= '
'; - print $html; // Close and print // uncomment next line to see content sent to printer //print '
'.print_r($this->connector, true).'
'; diff --git a/htdocs/langs/en_US/receiptprinter.lang b/htdocs/langs/en_US/receiptprinter.lang index aa61848fc9d..5714ba78151 100644 --- a/htdocs/langs/en_US/receiptprinter.lang +++ b/htdocs/langs/en_US/receiptprinter.lang @@ -29,6 +29,7 @@ PROFILE_SIMPLE_HELP=Simple Profile No Graphics PROFILE_EPOSTEP_HELP=Epos Tep Profile PROFILE_P822D_HELP=P822D Profile No Graphics PROFILE_STAR_HELP=Star Profile +DOL_LINE_FEED=Skip line DOL_ALIGN_LEFT=Left align text DOL_ALIGN_CENTER=Center text DOL_ALIGN_RIGHT=Right align text @@ -42,3 +43,5 @@ DOL_CUT_PAPER_PARTIAL=Cut ticket partially DOL_OPEN_DRAWER=Open cash drawer DOL_ACTIVATE_BUZZER=Activate buzzer DOL_PRINT_QRCODE=Print QR Code +DOL_PRINT_LOGO=Print logo of my company +DOL_PRINT_LOGO_OLD=Print logo of my company (old printers) diff --git a/htdocs/takepos/admin/setup.php b/htdocs/takepos/admin/setup.php index a1f07f4f7ad..2c9cc3cb495 100644 --- a/htdocs/takepos/admin/setup.php +++ b/htdocs/takepos/admin/setup.php @@ -68,6 +68,7 @@ if (GETPOST('action', 'alpha') == 'set') $res = dolibarr_set_const($db, "TAKEPOS_ROOT_CATEGORY_ID", GETPOST('TAKEPOS_ROOT_CATEGORY_ID', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOSCONNECTOR", GETPOST('TAKEPOSCONNECTOR', 'alpha'), 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, "TAKEPOS_DOLIBARR_PRINTER", GETPOST('TAKEPOS_DOLIBARR_PRINTER', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOS_BAR_RESTAURANT", GETPOST('TAKEPOS_BAR_RESTAURANT', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOS_TICKET_VAT_GROUPPED", GETPOST('TAKEPOS_TICKET_VAT_GROUPPED', 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOS_PRINT_SERVER", GETPOST('TAKEPOS_PRINT_SERVER', 'alpha'), 'chaine', 0, '', $conf->entity); @@ -163,6 +164,15 @@ print $form->select_all_categories(Categorie::TYPE_PRODUCT, $conf->global->TAKEP print ajax_combobox('TAKEPOS_ROOT_CATEGORY_ID'); print "\n"; +if ($conf->receiptprinter->enabled) { + // Use Dolibarr printing + print ''; + print $langs->trans("DolibarrReceiptPrinterModule"); + print ''; + print $form->selectyesno("TAKEPOS_DOLIBARR_PRINTER", $conf->global->TAKEPOS_DOLIBARR_PRINTER, 1); + print "\n"; +} + // Use Takepos printing print ''; print $langs->trans("DolibarrReceiptPrinter").' (
'.$langs->trans("TakeposConnectorNecesary").')'; diff --git a/htdocs/takepos/admin/terminal.php b/htdocs/takepos/admin/terminal.php index 167735e901d..1bbe339c852 100644 --- a/htdocs/takepos/admin/terminal.php +++ b/htdocs/takepos/admin/terminal.php @@ -81,6 +81,7 @@ if (GETPOST('action', 'alpha') == 'set') } $res = dolibarr_set_const($db, "CASHDESK_ID_WAREHOUSE".$terminaltouse, (GETPOST('CASHDESK_ID_WAREHOUSE'.$terminaltouse, 'alpha') > 0 ? GETPOST('CASHDESK_ID_WAREHOUSE'.$terminaltouse, 'alpha') : ''), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "CASHDESK_NO_DECREASE_STOCK".$terminaltouse, GETPOST('CASHDESK_NO_DECREASE_STOCK'.$terminaltouse, 'alpha'), 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, "TAKEPOS_PRINTER_TO_USE".$terminaltouse, GETPOST('TAKEPOS_PRINTER_TO_USE'.$terminaltouse, 'alpha'), 'chaine', 0, '', $conf->entity); dol_syslog("admin/cashdesk: level ".GETPOST('level', 'alpha')); @@ -193,6 +194,20 @@ if (! empty($conf->stock->enabled)) print ''.$langs->trans("StockDecreaseForPointOfSaleDisabled").''; } print ''; + if ($conf->receiptprinter->enabled) { + // Select printer to use with terminal + require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php'; + $printer = new dolReceiptPrinter($db); + $printer->listprinters(); + $printers = array(); + foreach ($printer->listprinters as $key => $value) { + $printers[$key] = $value['name']; + } + print ''.$langs->trans("TakeposTerminalPrinterToUse").''; + print ''; + print $form->selectarray('TAKEPOS_PRINTER_TO_USE'.$terminal, $printers, (empty($conf->global->{'TAKEPOS_PRINTER_TO_USE'.$terminal})?'0':$conf->global->{'TAKEPOS_PRINTER_TO_USE'.$terminal}), 1); + print ''; + } } print ''; diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index 126fea907a9..df2a839fb0e 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -444,8 +444,13 @@ if ($action=="valid" || $action=="history") else $sectionwithinvoicelink.=$langs->trans('BillShortStatusValidated'); } $sectionwithinvoicelink.=''; - if ($conf->global->TAKEPOSCONNECTOR) $sectionwithinvoicelink.=' '; - else $sectionwithinvoicelink.=' '; + if ($conf->global->TAKEPOSCONNECTOR) { + $sectionwithinvoicelink.=' '; + } elseif ($conf->global->TAKEPOS_DOLIBARR_PRINTER) { + $sectionwithinvoicelink.=' '; + } else { + $sectionwithinvoicelink.=' '; + } if ($conf->global->TAKEPOS_AUTO_PRINT_TICKETS) $sectionwithinvoicelink.=''; } @@ -548,6 +553,18 @@ function TakeposPrinting(id){ }); }); } +function DolibarrTakeposPrinting(id) { + console.log('Printing ticket ' + id) + var receipt; + // $.get("receipt.php?facid="+id, function(data, status) { + // receipt=data.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, ''); + // $.ajax({ + // type: "POST", + // url: 'http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print', + // data: receipt + // }); + // }); +} global->TAKEPOS_BAR_RESTAURANT) //add temp ticket button if ($conf->global->TAKEPOS_BAR_RESTAURANT) { - if ($conf->global->TAKEPOSCONNECTOR) $menus[$r++]=array('title'=>'
'.$langs->trans("Receipt").'
','action'=>'TakeposPrinting(placeid);'); - else $menus[$r++]=array('title'=>'
'.$langs->trans("Receipt").'
','action'=>'Print(placeid);'); + if ($conf->global->TAKEPOSCONNECTOR) { + $menus[$r++]=array('title'=>'
'.$langs->trans("Receipt").'
','action'=>'TakeposPrinting(placeid);'); + } else { + $menus[$r++]=array('title'=>'
'.$langs->trans("Receipt").'
','action'=>'Print(placeid);'); + } } if ($conf->global->TAKEPOSCONNECTOR && $conf->global->TAKEPOS_ORDER_NOTES==1) { @@ -713,6 +725,12 @@ if ($conf->global->TAKEPOS_BAR_RESTAURANT) if ($conf->global->TAKEPOSCONNECTOR) { $menus[$r++]=array('title'=>'
'.$langs->trans("DOL_OPEN_DRAWER").'
', 'action'=>'OpenDrawer();'); } +if ($conf->global->TAKEPOS_DOLIBARR_PRINTER) { + $menus[$r++] = array( + 'title' => '
'.$langs->trans("DOL_OPEN_DRAWER").'
', + 'action' => 'DolibarrOpenDrawer();', + ); +} $hookmanager->initHooks(array('takeposfrontend')); $reshook=$hookmanager->executeHooks('ActionButtons'); From c2d66a9e64d5e8307f53a2faa2d2972f2982b120 Mon Sep 17 00:00:00 2001 From: stickler-ci Date: Sat, 2 Nov 2019 23:53:11 +0000 Subject: [PATCH 04/10] Fixing style errors. --- .../includes/mike42/escpos-php/autoload.php | 18 ++-- .../src/Mike42/Escpos/CapabilityProfile.php | 4 +- .../src/Mike42/Escpos/EscposImage.php | 56 +++++------ .../src/Mike42/Escpos/GdEscposImage.php | 4 +- .../src/Mike42/Escpos/ImagickEscposImage.php | 6 +- .../Escpos/PrintBuffers/EscposPrintBuffer.php | 6 +- .../Escpos/PrintBuffers/ImagePrintBuffer.php | 2 +- .../PrintConnectors/CupsPrintConnector.php | 24 ++--- .../PrintConnectors/DummyPrintConnector.php | 2 +- .../PrintConnectors/FilePrintConnector.php | 4 +- .../escpos-php/src/Mike42/Escpos/Printer.php | 92 +++++++++---------- 11 files changed, 109 insertions(+), 109 deletions(-) diff --git a/htdocs/includes/mike42/escpos-php/autoload.php b/htdocs/includes/mike42/escpos-php/autoload.php index 7779486b824..47ed7d9e9c3 100644 --- a/htdocs/includes/mike42/escpos-php/autoload.php +++ b/htdocs/includes/mike42/escpos-php/autoload.php @@ -1,26 +1,26 @@ imgHeight; } - + /** * @return int Number of bytes to represent a row of this image */ public function getHeightBytes() { - return (int)(($this -> imgHeight + 7) / 8); + return (int) (($this -> imgHeight + 7) / 8); } - + /** * @return int Width of the image */ @@ -117,13 +117,13 @@ abstract class EscposImage { return $this -> imgWidth; } - + /** * @return int Number of bytes to represent a row of this image */ public function getWidthBytes() { - return (int)(($this -> imgWidth + 7) / 8); + return (int) (($this -> imgWidth + 7) / 8); } /** @@ -155,7 +155,7 @@ abstract class EscposImage } return $this -> imgRasterData; } - + /** * Output the image in column format. * @@ -199,7 +199,7 @@ abstract class EscposImage $this -> setImgHeight(0); $this -> setImgData(""); } - + /** * Set image data. * @@ -209,7 +209,7 @@ abstract class EscposImage { $this -> imgData = $data; } - + /** * Set image width. * @@ -219,7 +219,7 @@ abstract class EscposImage { $this -> imgWidth = $width; } - + /** * Set image height. * @@ -229,7 +229,7 @@ abstract class EscposImage { $this -> imgHeight = $height; } - + /** * @param string $filename * Filename to load from @@ -242,7 +242,7 @@ abstract class EscposImage // No optimised implementation to provide return null; } - + /** * @param string $filename * Filename to load from @@ -257,7 +257,7 @@ abstract class EscposImage // No optimised implementation to provide return null; } - + /** * Get column fromat from loaded image pixels, line by line. * @@ -279,7 +279,7 @@ abstract class EscposImage return $data; } do { - $byteVal |= (int)$this -> imgData[$y * $widthPixels + $x] << (7 - $bit); + $byteVal |= (int) $this -> imgData[$y * $widthPixels + $x] << (7 - $bit); $x++; $bit++; if ($x >= $widthPixels) { @@ -303,7 +303,7 @@ abstract class EscposImage } return $data; } - + /** * Get column fromat from loaded image pixels, line by line. * @@ -322,7 +322,7 @@ abstract class EscposImage } return $out; } - + /** * Output image in column format. Must be called once for each line of output. * @@ -356,7 +356,7 @@ abstract class EscposImage do { $yReal = $y + $yStart; if ($yReal < $heightPixels) { - $byteVal |= (int)$this -> imgData[$yReal * $widthPixels + $x] << (7 - $bit); + $byteVal |= (int) $this -> imgData[$yReal * $widthPixels + $x] << (7 - $bit); } $y++; $bit++; @@ -381,7 +381,7 @@ abstract class EscposImage } return $data; } - + /** * @return boolean True if GD is loaded, false otherwise */ @@ -389,7 +389,7 @@ abstract class EscposImage { return extension_loaded('gd'); } - + /** * @return boolean True if Imagick is loaded, false otherwise */ @@ -397,7 +397,7 @@ abstract class EscposImage { return extension_loaded('imagick'); } - + /** * This is a convinience method to load an image from file, auto-selecting diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php index 32edf76ef7c..41b17ff4749 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php @@ -33,7 +33,7 @@ class GdEscposImage extends EscposImage /* Set to blank image */ return parent::loadImageData($filename); } - + $ext = pathinfo($filename, PATHINFO_EXTENSION); switch ($ext) { case "png": @@ -73,7 +73,7 @@ class GdEscposImage extends EscposImage /* Faster to average channels, blend alpha and negate the image here than via filters (tested!) */ $cols = imagecolorsforindex($im, imagecolorat($im, $x, $y)); // 1 for white, 0 for black, ignoring transparency - $greyness = (int)(($cols['red'] + $cols['green'] + $cols['blue']) / 3) >> 7; + $greyness = (int) (($cols['red'] + $cols['green'] + $cols['blue']) / 3) >> 7; // 1 for black, 0 for white, taking into account transparency $black = (1 - $greyness) >> ($cols['alpha'] >> 6); $imgData[$y * $imgWidth + $x] = $black; diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php index 13851a4d034..8905e6eb051 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php @@ -44,7 +44,7 @@ class ImagickEscposImage extends EscposImage /* Faster to average channels, blend alpha and negate the image here than via filters (tested!) */ $cols = $im -> getImagePixelColor($x, $y); $cols = $cols -> getcolor(); - $greyness = (int)(($cols['r'] + $cols['g'] + $cols['b']) / 3) >> 7; // 1 for white, 0 for black + $greyness = (int) (($cols['r'] + $cols['g'] + $cols['b']) / 3) >> 7; // 1 for white, 0 for black $imgData[$y * $imgWidth + $x] = (1 - $greyness); // 1 for black, 0 for white } } @@ -70,7 +70,7 @@ class ImagickEscposImage extends EscposImage $im = $this -> getImageFromFile($filename); $this -> setImgWidth($im -> getimagewidth()); $this -> setImgHeight($im -> getimageheight()); - + /* Strip transparency */ $im = self::alphaRemove($im); $im -> setformat('pbm'); @@ -95,7 +95,7 @@ class ImagickEscposImage extends EscposImage /* Set to blank image */ return parent::loadImageData($filename); } - + $im = $this -> getImageFromFile($filename); $this -> readImageFromImagick($im); } diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php index 4e04176521e..f564132ea9f 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php @@ -136,7 +136,7 @@ class EscposPrintBuffer implements PrintBuffer if ($c == "\r") { /* Skip past Windows line endings (raw usage). */ continue; - } else if (self::asciiCheck($c, true)) { + } elseif (self::asciiCheck($c, true)) { $outp[$j] = $c; } $j++; @@ -167,7 +167,7 @@ class EscposPrintBuffer implements PrintBuffer } return false; } - + /** * Based on the printer's connector, compute (or load a cached copy of) maps * of UTF character to unicode characters for later use. @@ -219,7 +219,7 @@ class EscposPrintBuffer implements PrintBuffer $encode[$num][$utf8] = chr($char); } } - + /* Use generated data */ $dataArray = ["available" => $available, "encode" => $encode, "key" => $cacheKey]; $this -> available = $dataArray["available"]; diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php index d4fdefaf130..c59db99e60b 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php @@ -74,7 +74,7 @@ class ImagePrintBuffer implements PrintBuffer $draw = new \ImagickDraw(); $color = new \ImagickPixel('#000000'); $background = new \ImagickPixel('white'); - + /* Create annotation */ if ($this->font !== null) { // Allow fallback on defaults as necessary diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php index 497887f37cd..fb3c3c24d35 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php @@ -21,20 +21,20 @@ use BadMethodCallException; */ class CupsPrintConnector implements PrintConnector { - + /** * @var array $buffer * Buffer of accumilated data. */ private $buffer; - + /** * * @var string $printerName * The name of the target printer. */ private $printerName; - + /** * Construct new CUPS print connector. * @@ -49,7 +49,7 @@ class CupsPrintConnector implements PrintConnector throw new BadMethodCallException("You do not have any printers installed on " . "this system via CUPS. Check 'lpr -a'."); } - + if (array_search($dest, $valid, true) === false) { throw new BadMethodCallException("'$dest' is not a printer on this system. " . "Printers are: [" . implode(", ", $valid) . "]"); @@ -57,7 +57,7 @@ class CupsPrintConnector implements PrintConnector $this->buffer = array (); $this->printerName = $dest; } - + /** * Cause a NOTICE if deconstructed before the job was printed. */ @@ -67,7 +67,7 @@ class CupsPrintConnector implements PrintConnector trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); } } - + /** * Send job to printer. */ @@ -75,7 +75,7 @@ class CupsPrintConnector implements PrintConnector { $data = implode($this->buffer); $this->buffer = null; - + // Build command to work on data $tmpfname = tempnam(sys_get_temp_dir(), 'print-'); file_put_contents($tmpfname, $data); @@ -92,7 +92,7 @@ class CupsPrintConnector implements PrintConnector } unlink($tmpfname); } - + /** * Run a command and throw an exception if it fails, or return the output if it works. * (Basically exec() with good error handling) @@ -129,7 +129,7 @@ class CupsPrintConnector implements PrintConnector } return $outputStr; } - + /** * Read data from the printer. * @@ -140,7 +140,7 @@ class CupsPrintConnector implements PrintConnector { return false; } - + /** * @param string $data */ @@ -148,7 +148,7 @@ class CupsPrintConnector implements PrintConnector { $this->buffer [] = $data; } - + /** * Load a list of CUPS printers. * @@ -164,7 +164,7 @@ class CupsPrintConnector implements PrintConnector } return $ret; } - + /** * Get the item before the first space in a string * diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php index b376cd87d83..07c7d7358b1 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php @@ -41,7 +41,7 @@ final class DummyPrintConnector implements PrintConnector { $this -> buffer = []; } - + public function __destruct() { if ($this -> buffer !== null) { diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php index ca44ad0ad7e..04c4c66a1d5 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php @@ -55,7 +55,7 @@ class FilePrintConnector implements PrintConnector $this -> fp = false; } } - + /* (non-PHPdoc) * @see PrintConnector::read() */ @@ -66,7 +66,7 @@ class FilePrintConnector implements PrintConnector } return fread($this -> fp, $len); } - + /** * Write data to the file * diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php index 753d2ea8ad3..b7f6767b533 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php @@ -362,7 +362,7 @@ class Printer { /* Set connector */ $this -> connector = $connector; - + /* Set capability profile */ if ($profile === null) { $profile = CapabilityProfile::load('default'); @@ -374,18 +374,18 @@ class Printer $this -> setPrintBuffer($buffer); $this -> initialize(); } - + /** * Print a barcode. * * @param string $content The information to encode. * @param int $type The barcode standard to output. Supported values are - * `Printer::BARCODE_UPCA`, `Printer::BARCODE_UPCE`, `Printer::BARCODE_JAN13`, - * `Printer::BARCODE_JAN8`, `Printer::BARCODE_CODE39`, `Printer::BARCODE_ITF`, - * `Printer::BARCODE_CODABAR`, `Printer::BARCODE_CODE93`, and `Printer::BARCODE_CODE128`. - * If not specified, `Printer::BARCODE_CODE39` will be used. Note that some - * barcode formats only support specific lengths or sets of characters, and that - * available barcode types vary between printers. + * `Printer::BARCODE_UPCA`, `Printer::BARCODE_UPCE`, `Printer::BARCODE_JAN13`, + * `Printer::BARCODE_JAN8`, `Printer::BARCODE_CODE39`, `Printer::BARCODE_ITF`, + * `Printer::BARCODE_CODABAR`, `Printer::BARCODE_CODE93`, and `Printer::BARCODE_CODE128`. + * If not specified, `Printer::BARCODE_CODE39` will be used. Note that some + * barcode formats only support specific lengths or sets of characters, and that + * available barcode types vary between printers. * @throws InvalidArgumentException Where the length or characters used in $content is invalid for the requested barcode format. */ public function barcode($content, $type = Printer::BARCODE_CODE39) @@ -441,7 +441,7 @@ class Printer // More advanced function B, used in preference $this -> connector -> write(self::GS . "k" . chr($type) . chr(strlen($content)) . $content); } - + /** * Print an image, using the older "bit image" command. This creates padding on the right of the image, * if its width is not divisible by 8. @@ -451,8 +451,8 @@ class Printer * * @param EscposImage $img The image to print * @param int $size Size modifier for the image. Must be either `Printer::IMG_DEFAULT` - * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and - * `Printer::IMG_DOUBLE_WIDTH` flags. + * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and + * `Printer::IMG_DOUBLE_WIDTH` flags. */ public function bitImage(EscposImage $img, $size = Printer::IMG_DEFAULT) { @@ -471,8 +471,8 @@ class Printer * * @param EscposImage $img The image to print * @param int $size Size modifier for the image. Must be either `Printer::IMG_DEFAULT` - * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and - * `Printer::IMG_DOUBLE_WIDTH` flags. + * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and + * `Printer::IMG_DOUBLE_WIDTH` flags. */ public function bitImageColumnFormat(EscposImage $img, $size = Printer::IMG_DEFAULT) { @@ -502,7 +502,7 @@ class Printer { $this -> connector -> finalize(); } - + /** * Cut the paper. * @@ -514,7 +514,7 @@ class Printer // TODO validation on cut() inputs $this -> connector -> write(self::GS . "V" . chr($mode) . chr($lines)); } - + /** * Print and feed line / Print and feed n lines. * @@ -565,7 +565,7 @@ class Printer { return $this -> characterTable; } - + /** * @return PrintBuffer */ @@ -606,8 +606,8 @@ class Printer * * @param EscposImage $img The image to print. * @param int $size Size modifier for the image. Must be either `Printer::IMG_DEFAULT` - * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and - * `Printer::IMG_DOUBLE_WIDTH` flags. + * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and + * `Printer::IMG_DOUBLE_WIDTH` flags. */ public function graphics(EscposImage $img, $size = Printer::IMG_DEFAULT) { @@ -622,7 +622,7 @@ class Printer $this -> wrapperSendGraphicsData('0', 'p', $header . $rasterData); $this -> wrapperSendGraphicsData('0', '2'); } - + /** * Initialize printer. This resets formatting back to the defaults. */ @@ -637,15 +637,15 @@ class Printer * * @param string $content Text or numbers to store in the code * @param int $width Width of a module (pixel) in the printed code. - * Default is 3 dots. + * Default is 3 dots. * @param int $heightMultiplier Multiplier for height of a module. - * Default is 3 times the width. + * Default is 3 times the width. * @param int $dataColumnCount Number of data columns to use. 0 (default) - * is to auto-calculate. Smaller numbers will result in a narrower code, - * making larger pixel sizes possible. Larger numbers require smaller pixel sizes. + * is to auto-calculate. Smaller numbers will result in a narrower code, + * making larger pixel sizes possible. Larger numbers require smaller pixel sizes. * @param float $ec Error correction ratio, from 0.01 to 4.00. Default is 0.10 (10%). * @param int $options Standard code Printer::PDF417_STANDARD with - * start/end bars, or truncated code Printer::PDF417_TRUNCATED with start bars only. + * start/end bars, or truncated code Printer::PDF417_TRUNCATED with start bars only. * @throws Exception If this profile indicates that PDF417 code is not supported */ public function pdf417Code($content, $width = 3, $heightMultiplier = 3, $dataColumnCount = 0, $ec = 0.10, $options = Printer::PDF417_STANDARD) @@ -672,7 +672,7 @@ class Printer $this -> wrapperSend2dCodeData(chr(67), $cn, chr($width)); $this -> wrapperSend2dCodeData(chr(68), $cn, chr($heightMultiplier)); // Set error correction ratio: 1% to 400% - $ec_int = (int)ceil(floatval($ec) * 10); + $ec_int = (int) ceil(floatval($ec) * 10); $this -> wrapperSend2dCodeData(chr(69), $cn, chr($ec_int), '1'); // Send content & print $this -> wrapperSend2dCodeData(chr(80), $cn, $content, '0'); @@ -772,7 +772,7 @@ class Printer $this -> connector -> write(self::ESC . "!" . chr($mode)); } - + /** * Set barcode height. * @@ -788,27 +788,27 @@ class Printer * Set barcode bar width. * * @param int $width Bar width in dots. If not specified, 3 will be used. - * Values above 6 appear to have no effect. + * Values above 6 appear to have no effect. */ public function setBarcodeWidth($width = 3) { self::validateInteger($width, 1, 255, __FUNCTION__); $this -> connector -> write(self::GS . "w" . chr($width)); } - + /** * Set the position for the Human Readable Interpretation (HRI) of barcode characters. * * @param int $position. Use Printer::BARCODE_TEXT_NONE to hide the text (default), - * or any combination of Printer::BARCODE_TEXT_ABOVE and Printer::BARCODE_TEXT_BELOW - * flags to display the text. + * or any combination of Printer::BARCODE_TEXT_ABOVE and Printer::BARCODE_TEXT_BELOW + * flags to display the text. */ public function setBarcodeTextPosition($position = Printer::BARCODE_TEXT_NONE) { self::validateInteger($position, 0, 3, __FUNCTION__, "Barcode text position"); $this -> connector -> write(self::GS . "H" . chr($position)); } - + /** * Turn double-strike mode on/off. * @@ -841,7 +841,7 @@ class Printer self::validateBoolean($on, __FUNCTION__); $this -> connector -> write(self::ESC . "E". ($on ? chr(1) : chr(0))); } - + /** * Select font. Most printers have two fonts (Fonts A and B), and some have a third (Font C). * @@ -852,7 +852,7 @@ class Printer self::validateInteger($font, 0, 2, __FUNCTION__); $this -> connector -> write(self::ESC . "M" . chr($font)); } - + /** * Select justification. * @@ -870,7 +870,7 @@ class Printer * Some printers will allow you to overlap lines with a smaller line feed. * * @param int|null $height The height of each line, in dots. If not set, the printer - * will reset to its default line spacing. + * will reset to its default line spacing. */ public function setLineSpacing($height = null) { @@ -926,7 +926,7 @@ class Printer $this -> buffer = $buffer; $this -> buffer -> setPrinter($this); } - + /** * Set black/white reverse mode on or off. In this mode, text is printed white on a black background. * @@ -995,7 +995,7 @@ class Printer public function text($str = "") { self::validateString($str, __FUNCTION__); - $this -> buffer -> writeText((string)$str); + $this -> buffer -> writeText((string) $str); } /** @@ -1010,7 +1010,7 @@ class Printer self::validateString($str, __FUNCTION__); $this -> connector -> write(self::FS . "&"); $str = iconv("UTF-8", "GBK//IGNORE", $str); - $this -> buffer -> writeTextRaw((string)$str); + $this -> buffer -> writeTextRaw((string) $str); $this -> connector -> write(self::FS . "."); } @@ -1025,9 +1025,9 @@ class Printer public function textRaw($str = "") { self::validateString($str, __FUNCTION__); - $this -> buffer -> writeTextRaw((string)$str); + $this -> buffer -> writeTextRaw((string) $str); } - + /** * Wrapper for GS ( k, to calculate and send correct data length. * @@ -1045,7 +1045,7 @@ class Printer $header = $this -> intLowHigh(strlen($data) + strlen($m) + 2, 2); $this -> connector -> write(self::GS . "(k" . $header . $cn . $fn . $m . $data); } - + /** * Wrapper for GS ( L, to calculate and send correct data length. * @@ -1062,7 +1062,7 @@ class Printer $header = $this -> intLowHigh(strlen($data) + 2, 2); $this -> connector -> write(self::GS . "(L" . $header . $m . $fn . $data); } - + /** * Convert widths and heights to characters. Used before sending graphics to set the size. * @@ -1083,7 +1083,7 @@ class Printer } return implode("", $outp); } - + /** * Generate two characters for a number: In lower and higher parts, or more parts as needed. * @@ -1098,11 +1098,11 @@ class Printer $outp = ""; for ($i = 0; $i < $length; $i++) { $outp .= chr($input % 256); - $input = (int)($input / 256); + $input = (int) ($input / 256); } return $outp; } - + /** * Throw an exception if the argument given is not a boolean * @@ -1148,7 +1148,7 @@ class Printer { self::validateIntegerMulti($test, [[$min, $max]], $source, $argument); } - + /** * Throw an exception if the argument given is not an integer within one of the specified ranges * @@ -1198,7 +1198,7 @@ class Printer throw new InvalidArgumentException("$argument to $source must be a string"); } } - + /** * Throw an exception if the argument doesn't match the given regex. * From 5a3347104f2413b6a034f280dd68f94db6672aa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 3 Nov 2019 12:57:06 +0100 Subject: [PATCH 05/10] rework an experimental module --- htdocs/admin/receiptprinter.php | 30 +- htdocs/core/class/dolreceiptprinter.class.php | 280 +++++++++++------- .../PrintConnectors/ApiPrintConnector.php | 8 +- htdocs/product/class/product.class.php | 1 - htdocs/product/fournisseurs.php | 3 +- 5 files changed, 188 insertions(+), 134 deletions(-) diff --git a/htdocs/admin/receiptprinter.php b/htdocs/admin/receiptprinter.php index e01fc4402a8..9d3d125f3da 100644 --- a/htdocs/admin/receiptprinter.php +++ b/htdocs/admin/receiptprinter.php @@ -178,7 +178,7 @@ if ($action == 'testtemplate' && $user->admin) { require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $object = new Facture($db); //$object->initAsSpecimen(); - $object->fetch(8); + $object->fetch(18); //var_dump($object->lines); $ret = $printer->sendToPrinter($object, $templateid, 1); if ($ret == 0) { @@ -263,15 +263,13 @@ if ($mode == 'config' && $user->admin) { print $langs->trans("ReceiptPrinterDesc")."

\n"; - print ''."\n"; + print '
'."\n"; print ''; print ''; print ''; print ''; print ''; print ''; - print ''; - print ''; print "\n"; $ret = $printer->listprinters(); $nbofprinters = count($printer->listprinters); @@ -290,8 +288,6 @@ if ($mode == 'config' && $user->admin) { print ''; print ''; print ''; - print ''; - print ''; print ''; } else { print ''; @@ -301,13 +297,13 @@ if ($mode == 'config' && $user->admin) { // edit icon print ''; + print ''; // delete icon - print ''; + print ''; // test icon - print ''; print ''; @@ -323,8 +319,6 @@ if ($mode == 'config' && $user->admin) { print ''; print ''; print ''; - print ''; - print ''; print "\n"; } @@ -413,21 +407,19 @@ if ($mode == 'template' && $user->admin) { print ''; print ''; - print ''; - print ''; } else { print ''; print ''; // edit icon print ''; + print ''; // delete icon - print ''; + print ''; // test icon - print ''; } @@ -442,8 +434,6 @@ if ($mode == 'template' && $user->admin) { print ''; print ''; - print ''; - print ''; print '
'; } else { diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index c18c6e0be9b..309f8fcc061 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -37,55 +37,65 @@ * Underline with double line * Emphasized text * Print in white on black - * Print barcode - * Print barcode customer id * Ticket print width of 57mm * Cut ticket completely * Cut ticket partially * Open cash drawer * Activate buzzer - * - * Code which can be placed everywhere + * Print barcode * Print QR Code - * Print date AAAA-MM-DD - * Print date and time AAAA-MM-DD HH:MM:SS - * Print Year - * Print month in letters (example : november) - * Print month number - * Print day number - * Print day number - * Print table number (for restaurant, bar...) - * Print number of cutlery (for restaurant) - * Print payment method * Print logo stored on printer. Example : 32|32 * Print logo stored on printer. Must be followed by logo code. For old printers. - * Print object lines - * Print object total tax - * Print object local tax - * Print object total - * Print object number - * Print object number after validation - * Print customer firstname - * Print customer name - * Print customer mail - * Print customer phone - * Print customer mobile - * Print customer skype - * Print customer VAT number - * Print customer account balance - * Print vendor name - * Print vendor firstname - * Print vendor mail - * Print customer points - * Print number of points for this object + * Print object lines + * Print object total tax + * Print object local tax + * Print object total + * Print payment method * - * Conditional code at line start (if�then Print) + * Code which can be placed everywhere + * Replaced by date AAAA-MM-DD + * Replaced by date and time AAAA-MM-DD HH:MM:SS + * Replaced by Year + * Replaced by month in letters (example : november) + * Replaced by month number + * Replaced by day number + * Replaced by day number + * Replaced by table number (for restaurant, bar...) + * Replaced by number of cutlery (for restaurant) + * Replaced by object id + * Replaced by object ref + * Replaced by customer firstname + * Replaced by customer name + * Replaced by customer mail + * Replaced by customer phone + * Replaced by customer mobile + * Replaced by customer skype + * Replaced by customer VAT number + * Replaced by customer account balance + * Replaced by mysoc name + * Replaced by mysoc address + * Replaced by mysoc zip + * Replaced by mysoc town + * Replaced by mysoc country + * Replaced by mysoc idprof1 + * Replaced by mysoc idprof2 + * Replaced by mysoc idprof3 + * Replaced by mysoc idprof4 + * Replaced by mysoc idprof5 + * Replaced by mysoc idprof6 + * Replaced by vendor name + * Replaced by vendor firstname + * Replaced by vendor mail + * Replaced by customer points + * Replaced by number of points for this object + * + * Conditional code at line start (if then Print) * Print the line IF a customer is affected to the object * Print the line IF a vendor is affected to the object * Print the line IF Happy Hour - * Print the line IF object is validated + * Print the line IF object is validated * Print the line IF customer points > 0 - * Print the line IF points of the object > 0 + * Print the line IF points of the object > 0 * Print the line IF customer has vat number * Print the line IF customer balance > 0 * @@ -116,6 +126,9 @@ class dolReceiptPrinter extends Printer */ public $db; + /* + * @var string[] array of tags + */ public $tags; public $printer; public $template; @@ -130,8 +143,6 @@ class dolReceiptPrinter extends Printer */ public $errors = array(); - - /** * Constructor * @@ -142,6 +153,7 @@ class dolReceiptPrinter extends Printer $this->db=$db; $this->tags = array( 'dol_line_feed', + 'dol_line_feed_reverse', 'dol_align_left', 'dol_align_center', 'dol_align_right', @@ -162,8 +174,6 @@ class dolReceiptPrinter extends Printer '/dol_emphasized', 'dol_switch_colors', '/dol_switch_colors', - 'dol_print_barcode', - 'dol_print_barcode_customer_id', 'dol_set_print_width_57', 'dol_cut_paper_full', 'dol_cut_paper_partial', @@ -171,39 +181,52 @@ class dolReceiptPrinter extends Printer //'dol_activate_buzzer', 'dol_print_text', 'dol_print_qrcode', - 'dol_print_date', - 'dol_print_date_time', - 'dol_print_year', - 'dol_print_month_letters', - 'dol_print_month', - 'dol_print_day', - 'dol_print_day_letters', - 'dol_print_table', - 'dol_print_cutlery', + 'dol_print_barcode', + 'dol_value_date', + 'dol_value_date_time', + 'dol_value_year', + 'dol_value_month_letters', + 'dol_value_month', + 'dol_value_day', + 'dol_value_day_letters', + 'dol_value_table', + 'dol_value_cutlery', 'dol_print_payment', 'dol_print_logo', 'dol_print_logo_old', - 'dol_print_object_id', - 'dol_print_object_ref', + 'dol_value_object_id', + 'dol_value_object_ref', 'dol_print_object_lines', 'dol_print_object_tax', 'dol_print_object_local_tax', 'dol_print_object_total', 'dol_print_object_number', - 'dol_print_object_number_unique', - 'dol_print_customer_firstname', - 'dol_print_customer_lastname', - 'dol_print_customer_mail', - 'dol_print_customer_phone', - 'dol_print_customer_mobile', - 'dol_print_customer_skype', - 'dol_print_customer_tax_number', - 'dol_print_customer_account_balance', - 'dol_print_vendor_lastname', - 'dol_print_vendor_firstname', - 'dol_print_vendor_mail', - 'dol_print_customer_points', - 'dol_print_object_points', + 'dol_value_customer_firstname', + 'dol_value_customer_lastname', + 'dol_value_customer_mail', + 'dol_value_customer_phone', + 'dol_value_customer_mobile', + 'dol_value_customer_skype', + 'dol_value_customer_tax_number', + 'dol_value_customer_account_balance', + 'dol_value_mysoc_name', + 'dol_value_mysoc_address', + 'dol_value_mysoc_zip', + 'dol_value_mysoc_town', + 'dol_value_mysoc_country', + 'dol_value_mysoc_idprof1', + 'dol_value_mysoc_idprof2', + 'dol_value_mysoc_idprof3', + 'dol_value_mysoc_idprof4', + 'dol_value_mysoc_idprof5', + 'dol_value_mysoc_idprof6', + 'dol_value_mysoc_tva_intra', + 'dol_value_mysoc_capital', + 'dol_value_vendor_lastname', + 'dol_value_vendor_firstname', + 'dol_value_vendor_mail', + 'dol_value_customer_points', + 'dol_value_object_points', 'dol_print_if_customer', 'dol_print_if_vendor', 'dol_print_if_happy_hour', @@ -328,7 +351,7 @@ class dolReceiptPrinter extends Printer 1 => $langs->trans('CONNECTOR_DUMMY'), 2 => $langs->trans('CONNECTOR_FILE_PRINT'), 3 => $langs->trans('CONNECTOR_NETWORK_PRINT'), - 4 => $langs->trans('CONNECTOR_WINDOWS_PRINT') + 4 => $langs->trans('CONNECTOR_WINDOWS_PRINT'), ); $this->resprint = Form::selectarray($htmlname, $options, $selected); @@ -353,7 +376,7 @@ class dolReceiptPrinter extends Printer 1 => $langs->trans('PROFILE_SIMPLE'), 2 => $langs->trans('PROFILE_EPOSTEP'), 3 => $langs->trans('PROFILE_P822D'), - 4 => $langs->trans('PROFILE_STAR') + 4 => $langs->trans('PROFILE_STAR'), ); $this->profileresprint = Form::selectarray($htmlname, $options, $selected); @@ -502,6 +525,7 @@ class dolReceiptPrinter extends Printer $this->printer->text("Hello World!\n"); $testStr = "1234567890"; $this->printer->barcode($testStr); + //$this->printer->qrcode($testStr, Printer::QR_ECLEVEL_M, 5, Printer::QR_MODEL_1); $this->printer->text("Most simple example\n"); $this->printer->feed(); $this->printer->cut(); @@ -525,35 +549,48 @@ class dolReceiptPrinter extends Printer */ public function sendToPrinter($object, $templateid, $printerid) { - global $conf, $mysoc; + global $conf, $mysoc, $langs; $error = 0; $ret = $this->loadTemplate($templateid); - // tags a remplacer par leur valeur avant de parser - $this->template = str_replace('', $object->id, $this->template); - $this->template = str_replace('', $object->ref, $this->template); - $this->template = str_replace('', $object->customer_firstname, $this->template); - $this->template = str_replace('', $object->customer_lastname, $this->template); - $this->template = str_replace('', $object->customer_mail, $this->template); - $this->template = str_replace('', $object->customer_phone, $this->template); - $this->template = str_replace('', $object->customer_mobile, $this->template); - $this->template = str_replace('', $object->customer_skype, $this->template); - $this->template = str_replace('', $object->customer_tax_number, $this->template); - $this->template = str_replace('', $object->customer_account_balance, $this->template); - $this->template = str_replace('', $object->customer_points, $this->template); - $this->template = str_replace('', $object->object_points, $this->template); - $this->template = str_replace('', $object->vendor_firstname, $this->template); - $this->template = str_replace('', $object->vendor_lastname, $this->template); - $this->template = str_replace('', $object->vendor_mail, $this->template); - $this->template = str_replace('', $object->date, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->date_time, $this->template); - $this->template = str_replace('', $object->table, $this->template); - $this->template = str_replace('', $object->cutlery, $this->template); + // tags a remplacer par leur valeur avant de parser (dol_value_xxx) + $this->template = str_replace('', $object->id, $this->template); + $this->template = str_replace('', $object->ref, $this->template); + $this->template = str_replace('', $object->points, $this->template); + $this->template = str_replace('', $object->customer_firstname, $this->template); + $this->template = str_replace('', $object->customer_lastname, $this->template); + $this->template = str_replace('', $object->customer_mail, $this->template); + $this->template = str_replace('', $object->customer_phone, $this->template); + $this->template = str_replace('', $object->customer_mobile, $this->template); + $this->template = str_replace('', $object->customer_skype, $this->template); + $this->template = str_replace('', $object->customer_tax_number, $this->template); + $this->template = str_replace('', $object->customer_account_balance, $this->template); + $this->template = str_replace('', $object->customer_points, $this->template); + $this->template = str_replace('', $mysoc->name, $this->template); + $this->template = str_replace('', $mysoc->address, $this->template); + $this->template = str_replace('', $mysoc->zip, $this->template); + $this->template = str_replace('', $mysoc->town, $this->template); + $this->template = str_replace('', $mysoc->country, $this->template); + $this->template = str_replace('', $mysoc->idprof1, $this->template); + $this->template = str_replace('', $mysoc->idprof2, $this->template); + $this->template = str_replace('', $mysoc->idprof3, $this->template); + $this->template = str_replace('', $mysoc->idprof4, $this->template); + $this->template = str_replace('', $mysoc->idprof5, $this->template); + $this->template = str_replace('', $mysoc->idprof6, $this->template); + $this->template = str_replace('', $mysoc->tva_intra, $this->template); + $this->template = str_replace('', $mysoc->capital, $this->template); + $this->template = str_replace('', $object->vendor_firstname, $this->template); + $this->template = str_replace('', $object->vendor_lastname, $this->template); + $this->template = str_replace('', $object->vendor_mail, $this->template); + $this->template = str_replace('', $object->date, $this->template); + $this->template = str_replace('', $object->date_time, $this->template); + $this->template = str_replace('', $object->date_time, $this->template); + $this->template = str_replace('', $object->date_time, $this->template); + $this->template = str_replace('', $object->date_time, $this->template); + $this->template = str_replace('', $object->date_time, $this->template); + $this->template = str_replace('', $object->date_time, $this->template); + $this->template = str_replace('', $object->table, $this->template); + $this->template = str_replace('', $object->cutlery, $this->template); // parse template $p = xml_parser_create(); @@ -563,7 +600,7 @@ class dolReceiptPrinter extends Printer //print '
'.print_r($vals, true).'
'; // print ticket $level = 0; - $nbcaractbyline = 47; + $nbcharactbyline = 48; $ret = $this->initPrinter($printerid); if ($ret>0) { setEventMessages($this->error, $this->errors, 'errors'); @@ -577,15 +614,45 @@ class dolReceiptPrinter extends Printer break; case 'DOL_PRINT_OBJECT_LINES': foreach ($object->lines as $line) { - $spacestoadd = $nbcaractbyline - strlen($line->ref) - strlen(price($line->total_ttc, 'MT')); + //var_dump($line); + $spacestoadd = $nbcharactbyline - strlen($line->ref)- strlen($line->qty) - 10 - 1; $spaces = str_repeat(' ', $spacestoadd); - $this->printer->text($line->ref.$spaces.price($line->total_ttc, 'MT')."\n"); - //var_dump($line->ref); + $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text(strip_tags(htmlspecialchars_decode($line->desc))."\n"); } break; + case 'DOL_PRINT_OBJECT_TAX': + //var_dump($object); + $vatarray = array(); + foreach ($object->lines as $line) { + $vatarray[$line->tva_tx] += $line->total_tva; + } + foreach($vatarray as $vatkey => $vatvalue) { + $spacestoadd = $nbcharactbyline - strlen($vatkey)- 12; + $spaces = str_repeat(' ', $spacestoadd); + $this->printer->text($spaces. $vatkey.'% '.str_pad(price($vatvalue, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + } + break; + case 'DOL_PRINT_OBJECT_TOTAL': + $title = $langs->trans('TotalHT'); + $spacestoadd = $nbcharactbyline - strlen($title) - 10; + $spaces = str_repeat(' ', $spacestoadd); + $this->printer->text($title.$spaces.str_pad(price($object->total_ht, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + $title = $langs->trans('TotalVAT'); + $spacestoadd = $nbcharactbyline - strlen($title) - 10; + $spaces = str_repeat(' ', $spacestoadd); + $this->printer->text($title.$spaces.str_pad(price($object->total_tva, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + $title = $langs->trans('TotalTTC'); + $spacestoadd = $nbcharactbyline - strlen($title) - 10; + $spaces = str_repeat(' ', $spacestoadd); + $this->printer->text($title.$spaces.str_pad(price($object->total_ttc, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + break; case 'DOL_LINE_FEED': $this->printer->feed(); break; + case 'DOL_LINE_FEED_REVERSE': + $this->printer->feedReverse(); + break; case 'DOL_ALIGN_CENTER': $this->printer->setJustification(Printer::JUSTIFY_CENTER); break; @@ -603,22 +670,22 @@ class dolReceiptPrinter extends Printer break; case 'DOL_PRINT_BARCODE': // $vals[$tplline]['value'] -> barcode($content, $type) - $this->printer->barcode($object->barcode); + // var_dump($vals[$tplline]['value']); + try { + $this->printer->barcode($vals[$tplline]['value']); + } catch (Exception $e) { + $this->errors[] = 'Invalid Barcode value: '.$vals[$tplline]['value']; + $error++; + } break; case 'DOL_PRINT_LOGO': - // $vals[$tplline]['value'] -> barcode($content, $type) $img = EscposImage::load(DOL_DATA_ROOT .'/mycompany/logos/'.$mysoc->logo); $this->printer->graphics($img); break; case 'DOL_PRINT_LOGO_OLD': - // $vals[$tplline]['value'] -> barcode($content, $type) $img = EscposImage::load(DOL_DATA_ROOT .'/mycompany/logos/'.$mysoc->logo); $this->printer->bitImage($img); break; - case 'DOL_PRINT_BARCODE_CUSTOMER_ID': - // $vals[$tplline]['value'] -> barcode($content, $type) - $this->printer->barcode($object->customer_id); - break; case 'DOL_PRINT_QRCODE': // $vals[$tplline]['value'] -> qrCode($content, $ec, $size, $model) $this->printer->qrcode($vals[$tplline]['value']); @@ -631,19 +698,16 @@ class dolReceiptPrinter extends Printer break; case 'DOL_USE_FONT_A': $this->printer->setFont(Printer::FONT_A); - $this->printer->text($vals[$tplline]['value']); break; case 'DOL_USE_FONT_B': $this->printer->setFont(Printer::FONT_B); - $this->printer->text($vals[$tplline]['value']); break; case 'DOL_USE_FONT_C': $this->printer->setFont(Printer::FONT_C); - $this->printer->text($vals[$tplline]['value']); break; default: + $this->printer->text($vals[$tplline]['tag']); $this->printer->text($vals[$tplline]['value']); - $html.= nl2br($vals[$tplline]['value']); $this->errors[] = 'UnknowTag: <'.strtolower($vals[$tplline]['tag']).'>'; $error++; break; diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/ApiPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/ApiPrintConnector.php index 893a4858c8e..80e8c1302af 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/ApiPrintConnector.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/ApiPrintConnector.php @@ -30,9 +30,9 @@ class ApiPrintConnector implements PrintConnector /** * Construct new connector * - * @param string $host - * @param string $printerId - * @param string $apiToken + * @param string $host Host + * @param string $printerId Printer Id + * @param string $apiToken Api Token */ public function __construct($host, $printerId, $apiToken) { @@ -57,6 +57,7 @@ class ApiPrintConnector implements PrintConnector /** * Finish using this print connector (close file, socket, send * accumulated output, etc). + * @return void */ public function finalize() { @@ -94,6 +95,7 @@ class ApiPrintConnector implements PrintConnector * Write data to the print connector. * * @param string $data The data to write + * @return void */ public function write($data) { diff --git a/htdocs/product/class/product.class.php b/htdocs/product/class/product.class.php index de14a5621a2..4d8afaad9aa 100644 --- a/htdocs/product/class/product.class.php +++ b/htdocs/product/class/product.class.php @@ -2093,7 +2093,6 @@ class Product extends CommonObject $resql = $this->db->query($sql); if ($resql) { - unset($this->oldcopy); if ($this->db->num_rows($resql) > 0) { diff --git a/htdocs/product/fournisseurs.php b/htdocs/product/fournisseurs.php index f0bedbcd7f5..e1940864dd0 100644 --- a/htdocs/product/fournisseurs.php +++ b/htdocs/product/fournisseurs.php @@ -269,7 +269,6 @@ if (empty($reshook)) $resql = $db->query("SELECT * FROM " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields WHERE fk_object = " . $object->product_fourn_price_id); // Insert a new extrafields row, if none exists if ($db->num_rows($resql) != 1) { - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "product_fournisseur_price_extrafields (fk_object, "; foreach ($extrafield_values as $key => $value) { $sql .= str_replace('options_', '', $key) . ', '; @@ -291,7 +290,7 @@ if (empty($reshook)) // Execute the sql command from above $db->query($sql); - + $newprice = price2num(GETPOST("price", "alpha")); if ($conf->multicurrency->enabled) From b048a2b4084507fe420eeac6e945b5784e247cd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 3 Nov 2019 15:06:20 +0100 Subject: [PATCH 06/10] can print from takepos --- htdocs/takepos/admin/terminal.php | 17 ++++++++++++++++- htdocs/takepos/ajax/ajax.php | 23 ++++++++++++++++++++++- htdocs/takepos/invoice.php | 15 +++++---------- htdocs/takepos/takepos.php | 19 +++++++++---------- 4 files changed, 52 insertions(+), 22 deletions(-) diff --git a/htdocs/takepos/admin/terminal.php b/htdocs/takepos/admin/terminal.php index 1bbe339c852..24418654457 100644 --- a/htdocs/takepos/admin/terminal.php +++ b/htdocs/takepos/admin/terminal.php @@ -82,6 +82,8 @@ if (GETPOST('action', 'alpha') == 'set') $res = dolibarr_set_const($db, "CASHDESK_ID_WAREHOUSE".$terminaltouse, (GETPOST('CASHDESK_ID_WAREHOUSE'.$terminaltouse, 'alpha') > 0 ? GETPOST('CASHDESK_ID_WAREHOUSE'.$terminaltouse, 'alpha') : ''), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "CASHDESK_NO_DECREASE_STOCK".$terminaltouse, GETPOST('CASHDESK_NO_DECREASE_STOCK'.$terminaltouse, 'alpha'), 'chaine', 0, '', $conf->entity); $res = dolibarr_set_const($db, "TAKEPOS_PRINTER_TO_USE".$terminaltouse, GETPOST('TAKEPOS_PRINTER_TO_USE'.$terminaltouse, 'alpha'), 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, "TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES".$terminaltouse, GETPOST('TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$terminaltouse, 'alpha'), 'chaine', 0, '', $conf->entity); + $res = dolibarr_set_const($db, "TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS".$terminaltouse, GETPOST('TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS'.$terminaltouse, 'alpha'), 'chaine', 0, '', $conf->entity); dol_syslog("admin/cashdesk: level ".GETPOST('level', 'alpha')); @@ -201,12 +203,25 @@ if (! empty($conf->stock->enabled)) $printer->listprinters(); $printers = array(); foreach ($printer->listprinters as $key => $value) { - $printers[$key] = $value['name']; + $printers[$value['rowid']] = $value['name']; } print '
'; print ''; + $printer->listPrintersTemplates(); + $templates = array(); + foreach ($printer->listprinterstemplates as $key => $value) { + $templates[$value['rowid']] = $value['name']; + } + print ''; + print ''; + print ''; + print ''; } } diff --git a/htdocs/takepos/ajax/ajax.php b/htdocs/takepos/ajax/ajax.php index 2a27094bb90..40cf0f2f0d3 100644 --- a/htdocs/takepos/ajax/ajax.php +++ b/htdocs/takepos/ajax/ajax.php @@ -22,7 +22,7 @@ //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language //if (! defined('NOREQUIREDB')) define('NOREQUIREDB','1'); // Not disabled cause need to load personalized language -if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); +//if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1'); //if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', '1'); if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', '1'); @@ -36,6 +36,7 @@ require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; $category = GETPOST('category', 'alpha'); $action = GETPOST('action', 'alpha'); $term = GETPOST('term', 'alpha'); +$id = GETPOST('id', 'int'); /* @@ -81,4 +82,24 @@ elseif ($action=="search" && $term != '') { else { echo 'Failed to search product : '.$db->lasterror(); } +} elseif ($action == "opendrawer" && $term != '') { + require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php'; + $printer = new dolReceiptPrinter($db); + // chek printer for terminal + if ($conf->global->{'TAKEPOS_PRINTER_TO_USE'.$term} > 0) { + $printer->initPrinter($conf->global->{'TAKEPOS_PRINTER_TO_USE'.$term}); + // open cashdrawer + $printer->pulse(); + $printer->close(); + } +} elseif ($action == "printinvoiceticket" && $term != '' && $id > 0) { + require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php'; + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; + $printer = new dolReceiptPrinter($db); + // check printer for terminal + if ($conf->global->{'TAKEPOS_PRINTER_TO_USE'.$term} > 0 && $conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$term} > 0) { + $object = new Facture($db); + $object->fetch($id); + $ret = $printer->sendToPrinter($object, $conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$term}, $conf->global->{'TAKEPOS_PRINTER_TO_USE'.$term}); + } } diff --git a/htdocs/takepos/invoice.php b/htdocs/takepos/invoice.php index df2a839fb0e..fb40169fa5a 100644 --- a/htdocs/takepos/invoice.php +++ b/htdocs/takepos/invoice.php @@ -554,16 +554,11 @@ function TakeposPrinting(id){ }); } function DolibarrTakeposPrinting(id) { - console.log('Printing ticket ' + id) - var receipt; - // $.get("receipt.php?facid="+id, function(data, status) { - // receipt=data.replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, ''); - // $.ajax({ - // type: "POST", - // url: 'http://global->TAKEPOS_PRINT_SERVER; ?>:8111/print', - // data: receipt - // }); - // }); + console.log('Printing invoice ticket ' + id) + $.ajax({ + type: "GET", + url: "" + id, + }); } diff --git a/htdocs/takepos/takepos.php b/htdocs/takepos/takepos.php index cf86e8eb635..8966c575f9f 100644 --- a/htdocs/takepos/takepos.php +++ b/htdocs/takepos/takepos.php @@ -539,19 +539,18 @@ function TakeposPrintingTemp(){ function OpenDrawer(){ console.log("OpenDrawer"); $.ajax({ - type: "POST", - url: 'http://global->TAKEPOS_PRINT_SERVER;?>:8111/print', - data: "opendrawer" - }); + type: "POST", + url: 'http://global->TAKEPOS_PRINT_SERVER;?>:8111/print', + data: "opendrawer" + }); } -function DolibarrOpenDrawer(){ +function DolibarrOpenDrawer() { console.log("DolibarrOpenDrawer"); - // $.ajax({ - // type: "POST", - // url: 'http://', - // data: "opendrawer" - // }); + $.ajax({ + type: "GET", + url: "", + }); } function MoreActions(totalactions){ From dd952ace2c8509bb6de7b1de51ff594d53fe4152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 3 Nov 2019 17:09:29 +0100 Subject: [PATCH 07/10] stickler --- .stickler.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.stickler.yml b/.stickler.yml index b68804448b2..6819f76db7d 100644 --- a/.stickler.yml +++ b/.stickler.yml @@ -8,3 +8,7 @@ linters: fixers: enable: true + +files: + ignore: + - 'dev/htdocs/includes/*' From 8a247339c3e303a6b20c0f77e7948f02b4053070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 3 Nov 2019 17:10:47 +0100 Subject: [PATCH 08/10] stickler --- .stickler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.stickler.yml b/.stickler.yml index 6819f76db7d..642dec27412 100644 --- a/.stickler.yml +++ b/.stickler.yml @@ -11,4 +11,4 @@ fixers: files: ignore: - - 'dev/htdocs/includes/*' + - 'htdocs/includes/*' From 430be760f30018192550db3a61bc47484be1bbf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 3 Nov 2019 17:13:27 +0100 Subject: [PATCH 09/10] restore files modified by stickler --- .../src/Mike42/Escpos/CapabilityProfile.php | 4 +- .../src/Mike42/Escpos/EscposImage.php | 56 +++++------ .../src/Mike42/Escpos/GdEscposImage.php | 4 +- .../src/Mike42/Escpos/ImagickEscposImage.php | 6 +- .../Escpos/PrintBuffers/EscposPrintBuffer.php | 6 +- .../Escpos/PrintBuffers/ImagePrintBuffer.php | 2 +- .../PrintConnectors/ApiPrintConnector.php | 8 +- .../PrintConnectors/CupsPrintConnector.php | 24 ++--- .../PrintConnectors/DummyPrintConnector.php | 2 +- .../PrintConnectors/FilePrintConnector.php | 4 +- .../escpos-php/src/Mike42/Escpos/Printer.php | 92 +++++++++---------- 11 files changed, 103 insertions(+), 105 deletions(-) diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfile.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfile.php index 5c989258201..9a91390594e 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfile.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/CapabilityProfile.php @@ -83,13 +83,13 @@ class CapabilityProfile */ protected $profileId; - + /** * @var string $vendor * Name of manufacturer. */ protected $vendor; - + /** * * @var array $encodings diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/EscposImage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/EscposImage.php index 0465f0889c5..9a625acb47c 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/EscposImage.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/EscposImage.php @@ -42,51 +42,51 @@ abstract class EscposImage * height of the image. */ protected $imgHeight = 0; - + /** * @var int $imgWidth * width of the image */ protected $imgWidth = 0; - + /** * @var string $imgData * Image data in rows: 1 for black, 0 for white. */ private $imgData = null; - + /** * @var array:string $imgColumnData * Cached column-format data to avoid re-computation */ private $imgColumnData = []; - + /** * @var string $imgRasterData * Cached raster format data to avoid re-computation */ private $imgRasterData = null; - + /** * @var string $filename * Filename of image on disk - null if not loaded from disk. */ private $filename = null; - + /** * @var boolean $allowOptimisations * True to allow faster library-specific rendering shortcuts, false to always just use * image libraries to read pixels (more reproducible between systems). */ private $allowOptimisations = true; - + /** * Construct a new EscposImage. * * @param string $filename Path to image filename, or null to create an empty image. * @param boolean $allowOptimisations True (default) to use any library-specific tricks - * to speed up rendering, false to force the image to be read in pixel-by-pixel, - * which is easier to unit test and more reproducible between systems, but slower. + * to speed up rendering, false to force the image to be read in pixel-by-pixel, + * which is easier to unit test and more reproducible between systems, but slower. */ public function __construct($filename = null, $allowOptimisations = true) { @@ -101,15 +101,15 @@ abstract class EscposImage { return $this -> imgHeight; } - + /** * @return int Number of bytes to represent a row of this image */ public function getHeightBytes() { - return (int) (($this -> imgHeight + 7) / 8); + return (int)(($this -> imgHeight + 7) / 8); } - + /** * @return int Width of the image */ @@ -117,13 +117,13 @@ abstract class EscposImage { return $this -> imgWidth; } - + /** * @return int Number of bytes to represent a row of this image */ public function getWidthBytes() { - return (int) (($this -> imgWidth + 7) / 8); + return (int)(($this -> imgWidth + 7) / 8); } /** @@ -155,7 +155,7 @@ abstract class EscposImage } return $this -> imgRasterData; } - + /** * Output the image in column format. * @@ -199,7 +199,7 @@ abstract class EscposImage $this -> setImgHeight(0); $this -> setImgData(""); } - + /** * Set image data. * @@ -209,7 +209,7 @@ abstract class EscposImage { $this -> imgData = $data; } - + /** * Set image width. * @@ -219,7 +219,7 @@ abstract class EscposImage { $this -> imgWidth = $width; } - + /** * Set image height. * @@ -229,7 +229,7 @@ abstract class EscposImage { $this -> imgHeight = $height; } - + /** * @param string $filename * Filename to load from @@ -242,7 +242,7 @@ abstract class EscposImage // No optimised implementation to provide return null; } - + /** * @param string $filename * Filename to load from @@ -257,7 +257,7 @@ abstract class EscposImage // No optimised implementation to provide return null; } - + /** * Get column fromat from loaded image pixels, line by line. * @@ -279,7 +279,7 @@ abstract class EscposImage return $data; } do { - $byteVal |= (int) $this -> imgData[$y * $widthPixels + $x] << (7 - $bit); + $byteVal |= (int)$this -> imgData[$y * $widthPixels + $x] << (7 - $bit); $x++; $bit++; if ($x >= $widthPixels) { @@ -303,7 +303,7 @@ abstract class EscposImage } return $data; } - + /** * Get column fromat from loaded image pixels, line by line. * @@ -322,7 +322,7 @@ abstract class EscposImage } return $out; } - + /** * Output image in column format. Must be called once for each line of output. * @@ -356,7 +356,7 @@ abstract class EscposImage do { $yReal = $y + $yStart; if ($yReal < $heightPixels) { - $byteVal |= (int) $this -> imgData[$yReal * $widthPixels + $x] << (7 - $bit); + $byteVal |= (int)$this -> imgData[$yReal * $widthPixels + $x] << (7 - $bit); } $y++; $bit++; @@ -381,7 +381,7 @@ abstract class EscposImage } return $data; } - + /** * @return boolean True if GD is loaded, false otherwise */ @@ -389,7 +389,7 @@ abstract class EscposImage { return extension_loaded('gd'); } - + /** * @return boolean True if Imagick is loaded, false otherwise */ @@ -397,7 +397,7 @@ abstract class EscposImage { return extension_loaded('imagick'); } - + /** * This is a convinience method to load an image from file, auto-selecting diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php index 41b17ff4749..32edf76ef7c 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/GdEscposImage.php @@ -33,7 +33,7 @@ class GdEscposImage extends EscposImage /* Set to blank image */ return parent::loadImageData($filename); } - + $ext = pathinfo($filename, PATHINFO_EXTENSION); switch ($ext) { case "png": @@ -73,7 +73,7 @@ class GdEscposImage extends EscposImage /* Faster to average channels, blend alpha and negate the image here than via filters (tested!) */ $cols = imagecolorsforindex($im, imagecolorat($im, $x, $y)); // 1 for white, 0 for black, ignoring transparency - $greyness = (int) (($cols['red'] + $cols['green'] + $cols['blue']) / 3) >> 7; + $greyness = (int)(($cols['red'] + $cols['green'] + $cols['blue']) / 3) >> 7; // 1 for black, 0 for white, taking into account transparency $black = (1 - $greyness) >> ($cols['alpha'] >> 6); $imgData[$y * $imgWidth + $x] = $black; diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php index 8905e6eb051..13851a4d034 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/ImagickEscposImage.php @@ -44,7 +44,7 @@ class ImagickEscposImage extends EscposImage /* Faster to average channels, blend alpha and negate the image here than via filters (tested!) */ $cols = $im -> getImagePixelColor($x, $y); $cols = $cols -> getcolor(); - $greyness = (int) (($cols['r'] + $cols['g'] + $cols['b']) / 3) >> 7; // 1 for white, 0 for black + $greyness = (int)(($cols['r'] + $cols['g'] + $cols['b']) / 3) >> 7; // 1 for white, 0 for black $imgData[$y * $imgWidth + $x] = (1 - $greyness); // 1 for black, 0 for white } } @@ -70,7 +70,7 @@ class ImagickEscposImage extends EscposImage $im = $this -> getImageFromFile($filename); $this -> setImgWidth($im -> getimagewidth()); $this -> setImgHeight($im -> getimageheight()); - + /* Strip transparency */ $im = self::alphaRemove($im); $im -> setformat('pbm'); @@ -95,7 +95,7 @@ class ImagickEscposImage extends EscposImage /* Set to blank image */ return parent::loadImageData($filename); } - + $im = $this -> getImageFromFile($filename); $this -> readImageFromImagick($im); } diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php index f564132ea9f..4e04176521e 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/EscposPrintBuffer.php @@ -136,7 +136,7 @@ class EscposPrintBuffer implements PrintBuffer if ($c == "\r") { /* Skip past Windows line endings (raw usage). */ continue; - } elseif (self::asciiCheck($c, true)) { + } else if (self::asciiCheck($c, true)) { $outp[$j] = $c; } $j++; @@ -167,7 +167,7 @@ class EscposPrintBuffer implements PrintBuffer } return false; } - + /** * Based on the printer's connector, compute (or load a cached copy of) maps * of UTF character to unicode characters for later use. @@ -219,7 +219,7 @@ class EscposPrintBuffer implements PrintBuffer $encode[$num][$utf8] = chr($char); } } - + /* Use generated data */ $dataArray = ["available" => $available, "encode" => $encode, "key" => $cacheKey]; $this -> available = $dataArray["available"]; diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php index c59db99e60b..d4fdefaf130 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintBuffers/ImagePrintBuffer.php @@ -74,7 +74,7 @@ class ImagePrintBuffer implements PrintBuffer $draw = new \ImagickDraw(); $color = new \ImagickPixel('#000000'); $background = new \ImagickPixel('white'); - + /* Create annotation */ if ($this->font !== null) { // Allow fallback on defaults as necessary diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/ApiPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/ApiPrintConnector.php index 80e8c1302af..893a4858c8e 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/ApiPrintConnector.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/ApiPrintConnector.php @@ -30,9 +30,9 @@ class ApiPrintConnector implements PrintConnector /** * Construct new connector * - * @param string $host Host - * @param string $printerId Printer Id - * @param string $apiToken Api Token + * @param string $host + * @param string $printerId + * @param string $apiToken */ public function __construct($host, $printerId, $apiToken) { @@ -57,7 +57,6 @@ class ApiPrintConnector implements PrintConnector /** * Finish using this print connector (close file, socket, send * accumulated output, etc). - * @return void */ public function finalize() { @@ -95,7 +94,6 @@ class ApiPrintConnector implements PrintConnector * Write data to the print connector. * * @param string $data The data to write - * @return void */ public function write($data) { diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php index fb3c3c24d35..497887f37cd 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/CupsPrintConnector.php @@ -21,20 +21,20 @@ use BadMethodCallException; */ class CupsPrintConnector implements PrintConnector { - + /** * @var array $buffer * Buffer of accumilated data. */ private $buffer; - + /** * * @var string $printerName * The name of the target printer. */ private $printerName; - + /** * Construct new CUPS print connector. * @@ -49,7 +49,7 @@ class CupsPrintConnector implements PrintConnector throw new BadMethodCallException("You do not have any printers installed on " . "this system via CUPS. Check 'lpr -a'."); } - + if (array_search($dest, $valid, true) === false) { throw new BadMethodCallException("'$dest' is not a printer on this system. " . "Printers are: [" . implode(", ", $valid) . "]"); @@ -57,7 +57,7 @@ class CupsPrintConnector implements PrintConnector $this->buffer = array (); $this->printerName = $dest; } - + /** * Cause a NOTICE if deconstructed before the job was printed. */ @@ -67,7 +67,7 @@ class CupsPrintConnector implements PrintConnector trigger_error("Print connector was not finalized. Did you forget to close the printer?", E_USER_NOTICE); } } - + /** * Send job to printer. */ @@ -75,7 +75,7 @@ class CupsPrintConnector implements PrintConnector { $data = implode($this->buffer); $this->buffer = null; - + // Build command to work on data $tmpfname = tempnam(sys_get_temp_dir(), 'print-'); file_put_contents($tmpfname, $data); @@ -92,7 +92,7 @@ class CupsPrintConnector implements PrintConnector } unlink($tmpfname); } - + /** * Run a command and throw an exception if it fails, or return the output if it works. * (Basically exec() with good error handling) @@ -129,7 +129,7 @@ class CupsPrintConnector implements PrintConnector } return $outputStr; } - + /** * Read data from the printer. * @@ -140,7 +140,7 @@ class CupsPrintConnector implements PrintConnector { return false; } - + /** * @param string $data */ @@ -148,7 +148,7 @@ class CupsPrintConnector implements PrintConnector { $this->buffer [] = $data; } - + /** * Load a list of CUPS printers. * @@ -164,7 +164,7 @@ class CupsPrintConnector implements PrintConnector } return $ret; } - + /** * Get the item before the first space in a string * diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php index 07c7d7358b1..b376cd87d83 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/DummyPrintConnector.php @@ -41,7 +41,7 @@ final class DummyPrintConnector implements PrintConnector { $this -> buffer = []; } - + public function __destruct() { if ($this -> buffer !== null) { diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php index 04c4c66a1d5..ca44ad0ad7e 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/PrintConnectors/FilePrintConnector.php @@ -55,7 +55,7 @@ class FilePrintConnector implements PrintConnector $this -> fp = false; } } - + /* (non-PHPdoc) * @see PrintConnector::read() */ @@ -66,7 +66,7 @@ class FilePrintConnector implements PrintConnector } return fread($this -> fp, $len); } - + /** * Write data to the file * diff --git a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php index b7f6767b533..753d2ea8ad3 100644 --- a/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php +++ b/htdocs/includes/mike42/escpos-php/src/Mike42/Escpos/Printer.php @@ -362,7 +362,7 @@ class Printer { /* Set connector */ $this -> connector = $connector; - + /* Set capability profile */ if ($profile === null) { $profile = CapabilityProfile::load('default'); @@ -374,18 +374,18 @@ class Printer $this -> setPrintBuffer($buffer); $this -> initialize(); } - + /** * Print a barcode. * * @param string $content The information to encode. * @param int $type The barcode standard to output. Supported values are - * `Printer::BARCODE_UPCA`, `Printer::BARCODE_UPCE`, `Printer::BARCODE_JAN13`, - * `Printer::BARCODE_JAN8`, `Printer::BARCODE_CODE39`, `Printer::BARCODE_ITF`, - * `Printer::BARCODE_CODABAR`, `Printer::BARCODE_CODE93`, and `Printer::BARCODE_CODE128`. - * If not specified, `Printer::BARCODE_CODE39` will be used. Note that some - * barcode formats only support specific lengths or sets of characters, and that - * available barcode types vary between printers. + * `Printer::BARCODE_UPCA`, `Printer::BARCODE_UPCE`, `Printer::BARCODE_JAN13`, + * `Printer::BARCODE_JAN8`, `Printer::BARCODE_CODE39`, `Printer::BARCODE_ITF`, + * `Printer::BARCODE_CODABAR`, `Printer::BARCODE_CODE93`, and `Printer::BARCODE_CODE128`. + * If not specified, `Printer::BARCODE_CODE39` will be used. Note that some + * barcode formats only support specific lengths or sets of characters, and that + * available barcode types vary between printers. * @throws InvalidArgumentException Where the length or characters used in $content is invalid for the requested barcode format. */ public function barcode($content, $type = Printer::BARCODE_CODE39) @@ -441,7 +441,7 @@ class Printer // More advanced function B, used in preference $this -> connector -> write(self::GS . "k" . chr($type) . chr(strlen($content)) . $content); } - + /** * Print an image, using the older "bit image" command. This creates padding on the right of the image, * if its width is not divisible by 8. @@ -451,8 +451,8 @@ class Printer * * @param EscposImage $img The image to print * @param int $size Size modifier for the image. Must be either `Printer::IMG_DEFAULT` - * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and - * `Printer::IMG_DOUBLE_WIDTH` flags. + * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and + * `Printer::IMG_DOUBLE_WIDTH` flags. */ public function bitImage(EscposImage $img, $size = Printer::IMG_DEFAULT) { @@ -471,8 +471,8 @@ class Printer * * @param EscposImage $img The image to print * @param int $size Size modifier for the image. Must be either `Printer::IMG_DEFAULT` - * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and - * `Printer::IMG_DOUBLE_WIDTH` flags. + * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and + * `Printer::IMG_DOUBLE_WIDTH` flags. */ public function bitImageColumnFormat(EscposImage $img, $size = Printer::IMG_DEFAULT) { @@ -502,7 +502,7 @@ class Printer { $this -> connector -> finalize(); } - + /** * Cut the paper. * @@ -514,7 +514,7 @@ class Printer // TODO validation on cut() inputs $this -> connector -> write(self::GS . "V" . chr($mode) . chr($lines)); } - + /** * Print and feed line / Print and feed n lines. * @@ -565,7 +565,7 @@ class Printer { return $this -> characterTable; } - + /** * @return PrintBuffer */ @@ -606,8 +606,8 @@ class Printer * * @param EscposImage $img The image to print. * @param int $size Size modifier for the image. Must be either `Printer::IMG_DEFAULT` - * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and - * `Printer::IMG_DOUBLE_WIDTH` flags. + * (default), or any combination of the `Printer::IMG_DOUBLE_HEIGHT` and + * `Printer::IMG_DOUBLE_WIDTH` flags. */ public function graphics(EscposImage $img, $size = Printer::IMG_DEFAULT) { @@ -622,7 +622,7 @@ class Printer $this -> wrapperSendGraphicsData('0', 'p', $header . $rasterData); $this -> wrapperSendGraphicsData('0', '2'); } - + /** * Initialize printer. This resets formatting back to the defaults. */ @@ -637,15 +637,15 @@ class Printer * * @param string $content Text or numbers to store in the code * @param int $width Width of a module (pixel) in the printed code. - * Default is 3 dots. + * Default is 3 dots. * @param int $heightMultiplier Multiplier for height of a module. - * Default is 3 times the width. + * Default is 3 times the width. * @param int $dataColumnCount Number of data columns to use. 0 (default) - * is to auto-calculate. Smaller numbers will result in a narrower code, - * making larger pixel sizes possible. Larger numbers require smaller pixel sizes. + * is to auto-calculate. Smaller numbers will result in a narrower code, + * making larger pixel sizes possible. Larger numbers require smaller pixel sizes. * @param float $ec Error correction ratio, from 0.01 to 4.00. Default is 0.10 (10%). * @param int $options Standard code Printer::PDF417_STANDARD with - * start/end bars, or truncated code Printer::PDF417_TRUNCATED with start bars only. + * start/end bars, or truncated code Printer::PDF417_TRUNCATED with start bars only. * @throws Exception If this profile indicates that PDF417 code is not supported */ public function pdf417Code($content, $width = 3, $heightMultiplier = 3, $dataColumnCount = 0, $ec = 0.10, $options = Printer::PDF417_STANDARD) @@ -672,7 +672,7 @@ class Printer $this -> wrapperSend2dCodeData(chr(67), $cn, chr($width)); $this -> wrapperSend2dCodeData(chr(68), $cn, chr($heightMultiplier)); // Set error correction ratio: 1% to 400% - $ec_int = (int) ceil(floatval($ec) * 10); + $ec_int = (int)ceil(floatval($ec) * 10); $this -> wrapperSend2dCodeData(chr(69), $cn, chr($ec_int), '1'); // Send content & print $this -> wrapperSend2dCodeData(chr(80), $cn, $content, '0'); @@ -772,7 +772,7 @@ class Printer $this -> connector -> write(self::ESC . "!" . chr($mode)); } - + /** * Set barcode height. * @@ -788,27 +788,27 @@ class Printer * Set barcode bar width. * * @param int $width Bar width in dots. If not specified, 3 will be used. - * Values above 6 appear to have no effect. + * Values above 6 appear to have no effect. */ public function setBarcodeWidth($width = 3) { self::validateInteger($width, 1, 255, __FUNCTION__); $this -> connector -> write(self::GS . "w" . chr($width)); } - + /** * Set the position for the Human Readable Interpretation (HRI) of barcode characters. * * @param int $position. Use Printer::BARCODE_TEXT_NONE to hide the text (default), - * or any combination of Printer::BARCODE_TEXT_ABOVE and Printer::BARCODE_TEXT_BELOW - * flags to display the text. + * or any combination of Printer::BARCODE_TEXT_ABOVE and Printer::BARCODE_TEXT_BELOW + * flags to display the text. */ public function setBarcodeTextPosition($position = Printer::BARCODE_TEXT_NONE) { self::validateInteger($position, 0, 3, __FUNCTION__, "Barcode text position"); $this -> connector -> write(self::GS . "H" . chr($position)); } - + /** * Turn double-strike mode on/off. * @@ -841,7 +841,7 @@ class Printer self::validateBoolean($on, __FUNCTION__); $this -> connector -> write(self::ESC . "E". ($on ? chr(1) : chr(0))); } - + /** * Select font. Most printers have two fonts (Fonts A and B), and some have a third (Font C). * @@ -852,7 +852,7 @@ class Printer self::validateInteger($font, 0, 2, __FUNCTION__); $this -> connector -> write(self::ESC . "M" . chr($font)); } - + /** * Select justification. * @@ -870,7 +870,7 @@ class Printer * Some printers will allow you to overlap lines with a smaller line feed. * * @param int|null $height The height of each line, in dots. If not set, the printer - * will reset to its default line spacing. + * will reset to its default line spacing. */ public function setLineSpacing($height = null) { @@ -926,7 +926,7 @@ class Printer $this -> buffer = $buffer; $this -> buffer -> setPrinter($this); } - + /** * Set black/white reverse mode on or off. In this mode, text is printed white on a black background. * @@ -995,7 +995,7 @@ class Printer public function text($str = "") { self::validateString($str, __FUNCTION__); - $this -> buffer -> writeText((string) $str); + $this -> buffer -> writeText((string)$str); } /** @@ -1010,7 +1010,7 @@ class Printer self::validateString($str, __FUNCTION__); $this -> connector -> write(self::FS . "&"); $str = iconv("UTF-8", "GBK//IGNORE", $str); - $this -> buffer -> writeTextRaw((string) $str); + $this -> buffer -> writeTextRaw((string)$str); $this -> connector -> write(self::FS . "."); } @@ -1025,9 +1025,9 @@ class Printer public function textRaw($str = "") { self::validateString($str, __FUNCTION__); - $this -> buffer -> writeTextRaw((string) $str); + $this -> buffer -> writeTextRaw((string)$str); } - + /** * Wrapper for GS ( k, to calculate and send correct data length. * @@ -1045,7 +1045,7 @@ class Printer $header = $this -> intLowHigh(strlen($data) + strlen($m) + 2, 2); $this -> connector -> write(self::GS . "(k" . $header . $cn . $fn . $m . $data); } - + /** * Wrapper for GS ( L, to calculate and send correct data length. * @@ -1062,7 +1062,7 @@ class Printer $header = $this -> intLowHigh(strlen($data) + 2, 2); $this -> connector -> write(self::GS . "(L" . $header . $m . $fn . $data); } - + /** * Convert widths and heights to characters. Used before sending graphics to set the size. * @@ -1083,7 +1083,7 @@ class Printer } return implode("", $outp); } - + /** * Generate two characters for a number: In lower and higher parts, or more parts as needed. * @@ -1098,11 +1098,11 @@ class Printer $outp = ""; for ($i = 0; $i < $length; $i++) { $outp .= chr($input % 256); - $input = (int) ($input / 256); + $input = (int)($input / 256); } return $outp; } - + /** * Throw an exception if the argument given is not a boolean * @@ -1148,7 +1148,7 @@ class Printer { self::validateIntegerMulti($test, [[$min, $max]], $source, $argument); } - + /** * Throw an exception if the argument given is not an integer within one of the specified ranges * @@ -1198,7 +1198,7 @@ class Printer throw new InvalidArgumentException("$argument to $source must be a string"); } } - + /** * Throw an exception if the argument doesn't match the given regex. * From 877f40a1c85a386fc7affeda1d2cad00425d82bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20FRANCE?= Date: Sun, 3 Nov 2019 20:07:11 +0100 Subject: [PATCH 10/10] price --- htdocs/core/class/dolreceiptprinter.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/htdocs/core/class/dolreceiptprinter.class.php b/htdocs/core/class/dolreceiptprinter.class.php index 309f8fcc061..1d445614981 100644 --- a/htdocs/core/class/dolreceiptprinter.class.php +++ b/htdocs/core/class/dolreceiptprinter.class.php @@ -617,7 +617,7 @@ class dolReceiptPrinter extends Printer //var_dump($line); $spacestoadd = $nbcharactbyline - strlen($line->ref)- strlen($line->qty) - 10 - 1; $spaces = str_repeat(' ', $spacestoadd); - $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text($line->ref.$spaces.$line->qty.' '.str_pad(price($line->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); $this->printer->text(strip_tags(htmlspecialchars_decode($line->desc))."\n"); } break; @@ -630,22 +630,22 @@ class dolReceiptPrinter extends Printer foreach($vatarray as $vatkey => $vatvalue) { $spacestoadd = $nbcharactbyline - strlen($vatkey)- 12; $spaces = str_repeat(' ', $spacestoadd); - $this->printer->text($spaces. $vatkey.'% '.str_pad(price($vatvalue, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text($spaces. $vatkey.'% '.str_pad(price($vatvalue), 10, ' ', STR_PAD_LEFT)."\n"); } break; case 'DOL_PRINT_OBJECT_TOTAL': $title = $langs->trans('TotalHT'); $spacestoadd = $nbcharactbyline - strlen($title) - 10; $spaces = str_repeat(' ', $spacestoadd); - $this->printer->text($title.$spaces.str_pad(price($object->total_ht, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text($title.$spaces.str_pad(price($object->total_ht), 10, ' ', STR_PAD_LEFT)."\n"); $title = $langs->trans('TotalVAT'); $spacestoadd = $nbcharactbyline - strlen($title) - 10; $spaces = str_repeat(' ', $spacestoadd); - $this->printer->text($title.$spaces.str_pad(price($object->total_tva, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text($title.$spaces.str_pad(price($object->total_tva), 10, ' ', STR_PAD_LEFT)."\n"); $title = $langs->trans('TotalTTC'); $spacestoadd = $nbcharactbyline - strlen($title) - 10; $spaces = str_repeat(' ', $spacestoadd); - $this->printer->text($title.$spaces.str_pad(price($object->total_ttc, 'MT'), 10, ' ', STR_PAD_LEFT)."\n"); + $this->printer->text($title.$spaces.str_pad(price($object->total_ttc), 10, ' ', STR_PAD_LEFT)."\n"); break; case 'DOL_LINE_FEED': $this->printer->feed();
'.$langs->trans("Name").''.$langs->trans("Type").''.$langs->trans("Profile").''.$langs->trans("Parameters").'
'.$printer->profileresprint.'
'.$printer->listprinters[$line]['name'].''; print img_picto($langs->trans("Edit"), 'edit'); - print ''; + print ''; print img_picto($langs->trans("Delete"), 'delete'); - print ''; + print ''; print img_picto($langs->trans("TestPrinter"), 'printer'); print '
'.$langs->trans("Profile").''.$langs->trans("Parameters").'
'; print ''.$printer->listprinterstemplates[$line]['name'].''.nl2br(htmlentities($printer->listprinterstemplates[$line]['template'])).''; print img_picto($langs->trans("Edit"), 'edit'); - print ''; + print ''; print img_picto($langs->trans("Delete"), 'delete'); - print ''; + print ''; print img_picto($langs->trans("TestPrinterTemplate"), 'printer'); print ''; print '
'.$langs->trans("TakeposTerminalPrinterToUse").''; print $form->selectarray('TAKEPOS_PRINTER_TO_USE'.$terminal, $printers, (empty($conf->global->{'TAKEPOS_PRINTER_TO_USE'.$terminal})?'0':$conf->global->{'TAKEPOS_PRINTER_TO_USE'.$terminal}), 1); print '
'.$langs->trans("TakeposTerminalTemplateToUseForInvoicesTicket").''; + print $form->selectarray('TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$terminal, $templates, (empty($conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$terminal})?'0':$conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_INVOICES'.$terminal}), 1); + print '
'.$langs->trans("TakeposTerminalTemplateToUseForOrdersTicket").''; + print $form->selectarray('TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS'.$terminal, $templates, (empty($conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS'.$terminal})?'0':$conf->global->{'TAKEPOS_TEMPLATE_TO_USE_FOR_ORDERS'.$terminal}), 1); + print '