|
|
@ -16,6 +16,7 @@ AdoDb-Date 0.33 Modified BSD License Yes
|
|||
ChromePHP 4.1.0 Apache Software License 2.0 Yes Return server log to chrome browser console
|
||||
CKEditor 4.3.3 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
|
||||
FirePHPCore 0.4.0 MIT License Yes Send logs to Firefox Firebug console
|
||||
FPDI 1.5.2 Apache Software License 2.0 Yes PDF templates management
|
||||
GeoIP 1.4 LGPL-2.1+ Yes Sample code to make geoip convert (not into deb package)
|
||||
|
|
|
|||
442
htdocs/admin/receiptprinter.php
Normal file
|
|
@ -0,0 +1,442 @@
|
|||
<?php
|
||||
/* Copyright (C) 2013 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2015 Frederic France <frederic.france@free.fr>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/admin/receiptprinter.php
|
||||
* \ingroup printing
|
||||
* \brief Page to setup receipt printer
|
||||
*/
|
||||
|
||||
require '../main.inc.php';
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/receiptprinter.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/dolreceiptprinter.class.php';
|
||||
|
||||
$langs->load("admin");
|
||||
$langs->load("receiptprinter");
|
||||
|
||||
if (! $user->admin) accessforbidden();
|
||||
|
||||
$action = GETPOST('action','alpha');
|
||||
$mode = GETPOST('mode','alpha');
|
||||
|
||||
$printername = GETPOST('printername', 'alpha');
|
||||
$printerid = GETPOST('printerid', 'int');
|
||||
$parameter = GETPOST('parameter', 'alpha');
|
||||
|
||||
$template = GETPOST('template', 'alpha');
|
||||
$templatename = GETPOST('templatename', 'alpha');
|
||||
$templateid = GETPOST('templateid', 'int');
|
||||
|
||||
$printer = new dolReceiptPrinter($db);
|
||||
|
||||
if (!$mode) $mode='config';
|
||||
|
||||
// used in library escpos maybe useful if php doesn't support gzdecode
|
||||
if (!function_exists('gzdecode')) {
|
||||
function gzdecode($data)
|
||||
{
|
||||
return gzinflate(substr($data,10,-8));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Action
|
||||
*/
|
||||
|
||||
if ($action == 'addprinter' && $user->admin)
|
||||
{
|
||||
$error=0;
|
||||
$db->begin();
|
||||
if (empty($printername)) {
|
||||
$error++;
|
||||
setEventMessages($langs->trans("PrinterNameEmpty"), null, 'errors');
|
||||
}
|
||||
|
||||
if (empty($parameter)) {
|
||||
setEventMessages($langs->trans("PrinterParameterEmpty"), null, 'warnings');
|
||||
}
|
||||
|
||||
if (! $error)
|
||||
{
|
||||
$result= $printer->AddPrinter($printername, GETPOST('printertypeid', 'int'), $parameter);
|
||||
if ($result > 0) $error++;
|
||||
|
||||
if (! $error)
|
||||
{
|
||||
$db->commit();
|
||||
setEventMessages($langs->trans("PrinterAdded",$printername), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->rollback();
|
||||
dol_print_error($db);
|
||||
}
|
||||
}
|
||||
$action = '';
|
||||
}
|
||||
|
||||
if ($action == 'deleteprinter' && $user->admin)
|
||||
{
|
||||
$error=0;
|
||||
$db->begin();
|
||||
if (empty($printerid)) {
|
||||
$error++;
|
||||
setEventMessages($langs->trans("PrinterIdEmpty"), null, 'errors');
|
||||
}
|
||||
|
||||
if (! $error)
|
||||
{
|
||||
$result= $printer->DeletePrinter($printerid);
|
||||
if ($result > 0) $error++;
|
||||
|
||||
if (! $error)
|
||||
{
|
||||
$db->commit();
|
||||
setEventMessages($langs->trans("PrinterDeleted",$printername), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->rollback();
|
||||
dol_print_error($db);
|
||||
}
|
||||
}
|
||||
$action = '';
|
||||
}
|
||||
|
||||
if ($action == 'updateprinter' && $user->admin)
|
||||
{
|
||||
$error=0;
|
||||
$db->begin();
|
||||
if (empty($printerid)) {
|
||||
$error++;
|
||||
setEventMessages($langs->trans("PrinterIdEmpty"), null, 'errors');
|
||||
}
|
||||
|
||||
if (! $error)
|
||||
{
|
||||
$result= $printer->UpdatePrinter($printername, GETPOST('printertypeid', 'int'), $parameter, $printerid);
|
||||
if ($result > 0) $error++;
|
||||
|
||||
if (! $error)
|
||||
{
|
||||
$db->commit();
|
||||
setEventMessages($langs->trans("PrinterUpdated",$printername), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->rollback();
|
||||
dol_print_error($db);
|
||||
}
|
||||
}
|
||||
$action = '';
|
||||
}
|
||||
|
||||
if ($action == 'testprinter' && $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("TestSentToPrinter", $printername), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
setEventMessages($printer->error, $printer->errors, 'errors');
|
||||
}
|
||||
}
|
||||
$action = '';
|
||||
}
|
||||
|
||||
|
||||
if ($action == 'updatetemplate' && $user->admin)
|
||||
{
|
||||
$error=0;
|
||||
$db->begin();
|
||||
if (empty($templateid)) {
|
||||
$error++;
|
||||
setEventMessages($langs->trans("TemplateIdEmpty"), null, 'errors');
|
||||
}
|
||||
|
||||
if (! $error)
|
||||
{
|
||||
$result= $printer->UpdateTemplate($templatename, $template, $templateid);
|
||||
if ($result > 0) $error++;
|
||||
|
||||
if (! $error)
|
||||
{
|
||||
$db->commit();
|
||||
setEventMessages($langs->trans("TemplateUpdated",$templatename), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
$db->rollback();
|
||||
dol_print_error($db);
|
||||
}
|
||||
}
|
||||
$action = '';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* View
|
||||
*/
|
||||
|
||||
$form = new Form($db);
|
||||
|
||||
llxHeader('',$langs->trans("ReceiptPrinterSetup"));
|
||||
|
||||
$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>';
|
||||
print load_fiche_titre($langs->trans("ReceiptPrinterSetup"),$linkback,'title_setup');
|
||||
|
||||
$head = receiptprinteradmin_prepare_head($mode);
|
||||
|
||||
if ($mode == 'config' && $user->admin)
|
||||
{
|
||||
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=config" autocomplete="off">';
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
if ($action!='editprinter') {
|
||||
print '<input type="hidden" name="action" value="addprinter">';
|
||||
} else {
|
||||
print '<input type="hidden" name="action" value="updateprinter">';
|
||||
}
|
||||
|
||||
dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic');
|
||||
|
||||
print $langs->trans("ReceiptPrinterDesc")."<br><br>\n";
|
||||
|
||||
print '<table class="noborder" width="100%">'."\n";
|
||||
$var=true;
|
||||
print '<tr class="liste_titre">';
|
||||
print '<th>'.$langs->trans("Name").'</th>';
|
||||
print '<th>'.$langs->trans("Type").'</th>';
|
||||
print '<th>'.$langs->trans("Parameters").'</th>';
|
||||
print '<th></th>';
|
||||
print '<th></th>';
|
||||
print '<th></th>';
|
||||
print "</tr>\n";
|
||||
$ret = $printer->listprinters();
|
||||
if ($ret > 0) {
|
||||
setEventMessages($printer->error, $printer->errors, 'errors');
|
||||
} else {
|
||||
for ($line=0; $line < count($printer->listprinters); $line++) {
|
||||
$var = !$var;
|
||||
print '<tr '.$bc[$var].'>';
|
||||
if ($action=='editprinter' && $printer->listprinters[$line]['rowid']==$printerid) {
|
||||
print '<input type="hidden" name="printerid" value="'.$printer->listprinters[$line]['rowid'].'">';
|
||||
print '<td><input size="50" type="text" name="printername" value="'.$printer->listprinters[$line]['name'].'"></td>';
|
||||
$ret = $printer->selectTypePrinter($printer->listprinters[$line]['fk_type']);
|
||||
print '<td>'.$printer->resprint.'</td>';
|
||||
print '<td><input size="60" type="text" name="parameter" value="'.$printer->listprinters[$line]['parameter'].'"></td>';
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
print '</tr>';
|
||||
} else {
|
||||
print '<td>'.$printer->listprinters[$line]['name'].'</td>';
|
||||
switch ($printer->listprinters[$line]['fk_type']) {
|
||||
case 1:
|
||||
$connector = 'CONNECTOR_DUMMY';
|
||||
break;
|
||||
case 2:
|
||||
$connector = 'CONNECTOR_FILE_PRINT';
|
||||
break;
|
||||
case 3:
|
||||
$connector = 'CONNECTOR_NETWORK_PRINT';
|
||||
break;
|
||||
case 4:
|
||||
$connector = 'CONNECTOR_WINDOWS_PRINT';
|
||||
break;
|
||||
case 5:
|
||||
$connector = 'CONNECTOR_JAVA';
|
||||
break;
|
||||
default:
|
||||
$connector = 'CONNECTOR_UNKNOWN';
|
||||
break;
|
||||
}
|
||||
print '<td>'.$langs->trans($connector).'</td>';
|
||||
print '<td>'.$printer->listprinters[$line]['parameter'].'</td>';
|
||||
// edit icon
|
||||
print '<td><a href="'.$_SERVER['PHP_SELF'].'?mode=config&action=editprinter&printerid='.$printer->listprinters[$line]['rowid'].'">';
|
||||
print img_picto($langs->trans("Edit"),'edit');
|
||||
print '</a></td>';
|
||||
// delete icon
|
||||
print '<td><a href="'.$_SERVER['PHP_SELF'].'?mode=config&action=deleteprinter&printerid='.$printer->listprinters[$line]['rowid'].'&printername='.$printer->listprinters[$line]['name'].'">';
|
||||
print img_picto($langs->trans("Delete"),'delete');
|
||||
print '</a></td>';
|
||||
// test icon
|
||||
print '<td><a href="'.$_SERVER['PHP_SELF'].'?mode=config&action=testprinter&printerid='.$printer->listprinters[$line]['rowid'].'&printername='.$printer->listprinters[$line]['name'].'">';
|
||||
print img_picto($langs->trans("TestPrinter"),'printer');
|
||||
print '</a></td>';
|
||||
print '</tr>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($action!='editprinter') {
|
||||
print '<tr class="liste_titre">';
|
||||
print '<th>'.$langs->trans("Name").'</th>';
|
||||
print '<th>'.$langs->trans("Type").'</th>';
|
||||
print '<th>'.$langs->trans("Parameters").'</th>';
|
||||
print '<th></th>';
|
||||
print '<th></th>';
|
||||
print '<th></th>';
|
||||
print "</tr>\n";
|
||||
print '<tr>';
|
||||
print '<td><input size="50" type="text" name="printername"></td>';
|
||||
$ret = $printer->selectTypePrinter();
|
||||
print '<td>'.$printer->resprint.'</td>';
|
||||
print '<td><input size="60" type="text" name="parameter"></td>';
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
print '</tr>';
|
||||
}
|
||||
print '</table>';
|
||||
|
||||
dol_fiche_end();
|
||||
if ($action!='editprinter') {
|
||||
print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Add")).'"></div>';
|
||||
} else {
|
||||
print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Save")).'"></div>';
|
||||
}
|
||||
print '</form>';
|
||||
|
||||
print '<div><p></div>';
|
||||
dol_fiche_head();
|
||||
print '<table class="noborder" width="100%">'."\n";
|
||||
$var=true;
|
||||
print '<tr><td>'.$langs->trans("CONNECTOR_DUMMY").':</td><td>'.$langs->trans("CONNECTOR_DUMMY_HELP").'</td></tr>';
|
||||
print '<td>'.$langs->trans("CONNECTOR_NETWORK_PRINT").':</td><td>'.$langs->trans("CONNECTOR_NETWORK_PRINT_HELP").'</td></tr>';
|
||||
print '<td>'.$langs->trans("CONNECTOR_FILE_PRINT").':</td><td>'.$langs->trans("CONNECTOR_FILE_PRINT_HELP").'</td></tr>';
|
||||
print '<td>'.$langs->trans("CONNECTOR_WINDOWS_PRINT").':</td><td>'.$langs->trans("CONNECTOR_WINDOWS_PRINT_HELP").'</td></tr>';
|
||||
//print '<td>'.$langs->trans("CONNECTOR_JAVA").':</td><td>'.$langs->trans("CONNECTOR_JAVA_HELP").'</td></tr>';
|
||||
print '</table>';
|
||||
dol_fiche_end();
|
||||
}
|
||||
|
||||
if ($mode == 'template' && $user->admin)
|
||||
{
|
||||
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=template" autocomplete="off">';
|
||||
print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">';
|
||||
if ($action!='edittemplate') {
|
||||
print '<input type="hidden" name="action" value="addtemplate">';
|
||||
} else {
|
||||
print '<input type="hidden" name="action" value="updatetemplate">';
|
||||
}
|
||||
|
||||
dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic');
|
||||
|
||||
print $langs->trans("ReceiptPrinterTemplateDesc")."<br><br>\n";
|
||||
print '<table class="noborder" width="100%">'."\n";
|
||||
$var=true;
|
||||
print '<tr class="liste_titre">';
|
||||
print '<th>'.$langs->trans("Name").'</th>';
|
||||
print '<th>'.$langs->trans("Template").'</th>';
|
||||
print '<th></th>';
|
||||
print '<th></th>';
|
||||
print '<th></th>';
|
||||
print "</tr>\n";
|
||||
$ret = $printer->listPrintersTemplates();
|
||||
//print '<pre>'.print_r($printer->listprinterstemplates, true).'</pre>';
|
||||
if ($ret > 0) {
|
||||
setEventMessages($printer->error, $printer->errors, 'errors');
|
||||
} else {
|
||||
for ($line=0; $line < count($printer->listprinterstemplates); $line++) {
|
||||
$var = !$var;
|
||||
print '<tr '.$bc[$var].'>';
|
||||
if ($action=='edittemplate' && $printer->listprinterstemplates[$line]['rowid']==$templateid) {
|
||||
print '<input type="hidden" name="templateid" value="'.$printer->listprinterstemplates[$line]['rowid'].'">';
|
||||
print '<td><input size="50" type="text" name="templatename" value="'.$printer->listprinterstemplates[$line]['name'].'"></td>';
|
||||
print '<td><textarea name="template" wrap="soft" cols="120" rows="12">'.$printer->listprinterstemplates[$line]['template'].'</textarea>';
|
||||
print '</td>';
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
print '<td></td>';
|
||||
} else {
|
||||
print '<td>'.$printer->listprinterstemplates[$line]['name'].'</td>';
|
||||
print '<td>'.nl2br(htmlentities($printer->listprinterstemplates[$line]['template'])).'</td>';
|
||||
// edit icon
|
||||
print '<td><a href="'.$_SERVER['PHP_SELF'].'?mode=template&action=edittemplate&templateid='.$printer->listprinterstemplates[$line]['rowid'].'">';
|
||||
print img_picto($langs->trans("Edit"),'edit');
|
||||
print '</a></td>';
|
||||
// delete icon
|
||||
print '<td><a href="'.$_SERVER['PHP_SELF'].'?mode=template&action=deletetemplate&templateid='.$printer->listprinterstemplates[$line]['rowid'].'&templatename='.$printer->listprinterstemplates[$line]['name'].'">';
|
||||
print img_picto($langs->trans("Delete"),'delete');
|
||||
print '</a></td>';
|
||||
// test icon
|
||||
print '<td><a href="'.$_SERVER['PHP_SELF'].'?mode=template&action=testtemplate&templateid='.$printer->listprinterstemplates[$line]['rowid'].'&templatename='.$printer->listprinterstemplates[$line]['name'].'">';
|
||||
print img_picto($langs->trans("TestPrinterTemplate"),'printer');
|
||||
print '</a></td>';
|
||||
}
|
||||
print '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
if ($action!='edittemplate') {
|
||||
print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Add")).'"></div>';
|
||||
} else {
|
||||
print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Save")).'"></div>';
|
||||
}
|
||||
print '</form>';
|
||||
print '<div><p></div>';
|
||||
print '<table class="noborder" width="100%">'."\n";
|
||||
$var=true;
|
||||
print '<tr class="liste_titre">';
|
||||
print '<th>'.$langs->trans("Tag").'</th>';
|
||||
print '<th>'.$langs->trans("Description").'</th>';
|
||||
print "</tr>\n";
|
||||
for ($tag=0; $tag < count($printer->tags); $tag++) {
|
||||
$var = !$var;
|
||||
print '<tr '.$bc[$var].'>';
|
||||
print '<td><'.$printer->tags[$tag].'></td><td>'.$langs->trans(strtoupper($printer->tags[$tag])).'</td>';
|
||||
print '</tr>';
|
||||
}
|
||||
print '</table>';
|
||||
|
||||
dol_fiche_end();
|
||||
|
||||
}
|
||||
|
||||
// to remove after test
|
||||
$object->date = '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');
|
||||
|
||||
llxFooter();
|
||||
|
||||
$db->close();
|
||||
|
||||
|
|
@ -58,6 +58,7 @@ if (GETPOST('action','alpha') == 'set')
|
|||
$res = dolibarr_set_const($db,"CASHDESK_ID_WAREHOUSE",(GETPOST('CASHDESK_ID_WAREHOUSE','alpha') > 0 ? GETPOST('CASHDESK_ID_WAREHOUSE','alpha') : ''),'chaine',0,'',$conf->entity);
|
||||
$res = dolibarr_set_const($db,"CASHDESK_NO_DECREASE_STOCK",GETPOST('CASHDESK_NO_DECREASE_STOCK','alpha'),'chaine',0,'',$conf->entity);
|
||||
$res = dolibarr_set_const($db,"CASHDESK_SERVICES", GETPOST('CASHDESK_SERVICES','alpha'),'chaine',0,'',$conf->entity);
|
||||
$res = dolibarr_set_const($db,"CASHDESK_DOLIBAR_RECEIPT_PRINTER", GETPOST('CASHDESK_DOLIBAR_RECEIPT_PRINTER','alpha'),'chaine',0,'',$conf->entity);
|
||||
|
||||
dol_syslog("admin/cashdesk: level ".GETPOST('level','alpha'));
|
||||
|
||||
|
|
@ -169,6 +170,17 @@ if (! empty($conf->service->enabled))
|
|||
print "</td></tr>\n";
|
||||
}
|
||||
|
||||
// Use Dolibarr Receipt Printer
|
||||
if (! empty($conf->receiptprinter->enabled))
|
||||
{
|
||||
$var=! $var;
|
||||
print '<tr '.$bc[$var].'><td>';
|
||||
print $langs->trans("DolibarrReceiptPrinter");
|
||||
print '<td colspan="2">';
|
||||
print $form->selectyesno("CASHDESK_DOLIBAR_RECEIPT_PRINTER",$conf->global->CASHDESK_DOLIBAR_RECEIPT_PRINTER,1);
|
||||
print "</td></tr>\n";
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
print '<br>';
|
||||
|
||||
|
|
|
|||
592
htdocs/core/class/dolreceiptprinter.class.php
Normal file
|
|
@ -0,0 +1,592 @@
|
|||
<?php
|
||||
/*
|
||||
* Copyright (C) 2015 Frederic France <frederic.france@free.fr>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* or see http://www.gnu.org/
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/core/class/dolreceiptprinter.class.php
|
||||
* \brief Print receipt ticket on various ESC/POS printer
|
||||
*/
|
||||
|
||||
/*
|
||||
* Tags for ticket template
|
||||
*
|
||||
* <dol_align_left> Left align text
|
||||
* <dol_align_center> Center text
|
||||
* <dol_align_right> Right align text
|
||||
* <dol_use_font_a> Use font A of printer
|
||||
* <dol_use_font_b> Use font B of printer
|
||||
* <dol_use_font_c> Use font C of printer
|
||||
* <dol_bold> </dol_bold> Text Bold
|
||||
* <dol_double_height> </dol_double_height> Text double height
|
||||
* <dol_double_width> </dol_double_width> Text double width
|
||||
* <dol_underline> </dol_underline> Underline text
|
||||
* <dol_underline_2dots> </dol_underline_2dots> Underline with double line
|
||||
* <dol_emphasized> </dol_emphasized> Emphasized text
|
||||
* <dol_switch_colors> </dol_switch_colors> Print in white on black
|
||||
* <dol_print_barcode> Print barcode
|
||||
* <dol_print_barcode_customer_id> Print barcode customer id
|
||||
* <dol_set_print_width_57> Ticket print width of 57mm
|
||||
* <dol_cut_paper_full> Cut ticket completely
|
||||
* <dol_cut_paper_partial> Cut ticket partially
|
||||
* <dol_open_drawer> Open cash drawer
|
||||
* <dol_activate_buzzer> Activate buzzer
|
||||
*
|
||||
* Code which can be placed everywhere
|
||||
* <dol_print_qrcode> Print QR Code
|
||||
* <dol_print_date> Print date AAAA-MM-DD
|
||||
* <dol_print_date_time> Print date and time AAAA-MM-DD HH:MM:SS
|
||||
* <dol_print_year> Print Year
|
||||
* <dol_print_month_letters> Print month in letters (example : november)
|
||||
* <dol_print_month> Print month number
|
||||
* <dol_print_day> Print day number
|
||||
* <dol_print_day_letters> Print day number
|
||||
* <dol_print_table> Print table number (for restaurant, bar...)
|
||||
* <dol_print_cutlery> Print number of cutlery (for restaurant)
|
||||
* <dol_print_payment> Print payment method
|
||||
* <dol_print_logo> Print logo stored on printer. Example : <print_logo>32|32
|
||||
* <dol_print_logo_old> Print logo stored on printer. Must be followed by logo code. For old printers.
|
||||
* <dol_print_order_lines> Print order lines
|
||||
* <dol_print_order_tax> Print order total tax
|
||||
* <dol_print_order_local_tax> Print order local tax
|
||||
* <dol_print_order_total> Print order total
|
||||
* <dol_print_order_number> Print order number
|
||||
* <dol_print_order_number_unique> Print order number after validation
|
||||
* <dol_print_customer_firstname> Print customer firstname
|
||||
* <dol_print_customer_lastname> Print customer name
|
||||
* <dol_print_customer_mail> Print customer mail
|
||||
* <dol_print_customer_phone> Print customer phone
|
||||
* <dol_print_customer_mobile> Print customer mobile
|
||||
* <dol_print_customer_skype> Print customer skype
|
||||
* <dol_print_customer_tax_number> Print customer VAT number
|
||||
* <dol_print_customer_account_balance> Print customer account balance
|
||||
* <dol_print_vendor_last_name> Print vendor name
|
||||
* <dol_print_vendor_first_name> Print vendor firstname
|
||||
* <dol_print_vendor_mail> Print vendor mail
|
||||
* <dol_print_customer_points> Print customer points
|
||||
* <dol_print_order_points> Print number of points for this order
|
||||
*
|
||||
* Conditional code at line start (if…then Print)
|
||||
* <dol_print_if_customer> Print the line IF a customer is affected to the order
|
||||
* <dol_print_if_vendor> Print the line IF a vendor is affected to the order
|
||||
* <dol_print_if_happy_hour> Print the line IF Happy Hour
|
||||
* <dol_print_if_num_order_unique> Print the line IF order is validated
|
||||
* <dol_print_if_customer_points> Print the line IF customer points > 0
|
||||
* <dol_print_if_order_points> Print the line IF points of the order > 0
|
||||
* <dol_print_if_customer_tax_number> Print the line IF customer has vat number
|
||||
* <dol_print_if_customer_account_balance_positive> Print the line IF customer balance > 0
|
||||
*
|
||||
*/
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT .'/includes/escpos/Escpos.php';
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage Receipt Printers
|
||||
*/
|
||||
class dolReceiptPrinter extends Escpos
|
||||
{
|
||||
const CONNECTOR_DUMMY = 1;
|
||||
const CONNECTOR_FILE_PRINT = 2;
|
||||
const CONNECTOR_NETWORK_PRINT = 3;
|
||||
const CONNECTOR_WINDOWS_PRINT = 4;
|
||||
//const CONNECTOR_JAVA = 5;
|
||||
var $db;
|
||||
var $tags;
|
||||
var $printer;
|
||||
var $template;
|
||||
var $error;
|
||||
var $errors;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param DoliDB $db database
|
||||
*/
|
||||
function __construct($db)
|
||||
{
|
||||
$this->db=$db;
|
||||
$this->tags = array(
|
||||
'dol_align_left',
|
||||
'dol_align_center',
|
||||
'dol_align_right',
|
||||
'dol_use_font_a',
|
||||
'dol_use_font_b',
|
||||
'dol_use_font_c',
|
||||
'dol_bold',
|
||||
'/dol_bold',
|
||||
'dol_double_height',
|
||||
'/dol_double_height',
|
||||
'dol_double_width',
|
||||
'/dol_double_width',
|
||||
'dol_underline',
|
||||
'/dol_underline',
|
||||
'dol_underline_2dots',
|
||||
'/dol_underline',
|
||||
'dol_emphasized',
|
||||
'/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',
|
||||
'dol_open_drawer',
|
||||
'dol_activate_buzzer',
|
||||
'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_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_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_order_points',
|
||||
'dol_print_if_customer',
|
||||
'dol_print_if_vendor',
|
||||
'dol_print_if_happy_hour',
|
||||
'dol_print_if_num_order_unique',
|
||||
'dol_print_if_customer_points',
|
||||
'dol_print_if_order_points',
|
||||
'dol_print_if_customer_tax_number',
|
||||
'dol_print_if_customer_account_balance_positive',
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* list printers
|
||||
*
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function listPrinters()
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
$line = 0;
|
||||
$sql = 'SELECT rowid, name, fk_type, parameter';
|
||||
$sql.= ' FROM '.MAIN_DB_PREFIX.'printer_receipt';
|
||||
$sql.= ' WHERE entity = '.$conf->entity;
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$num = $this->db->num_rows($resql);
|
||||
while ($line < $num) {
|
||||
$obj[] = $this->db->fetch_array($resql);
|
||||
$line++;
|
||||
}
|
||||
} else {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror;
|
||||
}
|
||||
$this->listprinters = $obj;
|
||||
return $error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* List printers templates
|
||||
*
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function listPrintersTemplates()
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
$line = 0;
|
||||
$sql = 'SELECT rowid, name, template';
|
||||
$sql.= ' FROM '.MAIN_DB_PREFIX.'printer_receipt_template';
|
||||
$sql.= ' WHERE entity = '.$conf->entity;
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$num = $this->db->num_rows($resql);
|
||||
while ($line < $num) {
|
||||
$obj[] = $this->db->fetch_array($resql);
|
||||
$line++;
|
||||
}
|
||||
} else {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror;
|
||||
}
|
||||
$this->listprinterstemplates = $obj;
|
||||
return $error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Form to Select type printer
|
||||
*
|
||||
* @param string $selected Id printer type pre-selected
|
||||
* @param string $htmlname select html name
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function selectTypePrinter($selected='', $htmlname='printertypeid')
|
||||
{
|
||||
global $langs;
|
||||
$error = 0;
|
||||
$html = '<select class="flat" name="'.$htmlname.'">';
|
||||
$html.= '<option value="1" '.($selected==1?'selected="selected"':'').'>'.$langs->trans('CONNECTOR_DUMMY').'</option>';
|
||||
$html.= '<option value="2" '.($selected==2?'selected="selected"':'').'>'.$langs->trans('CONNECTOR_FILE_PRINT').'</option>';
|
||||
$html.= '<option value="3" '.($selected==3?'selected="selected"':'').'>'.$langs->trans('CONNECTOR_NETWORK_PRINT').'</option>';
|
||||
$html.= '<option value="4" '.($selected==4?'selected="selected"':'').'>'.$langs->trans('CONNECTOR_WINDOWS_PRINT').'</option>';
|
||||
//$html.= '<option value="5" '.($selected==5?'selected="selected"':'').'>'.$langs->trans('CONNECTOR_JAVA').'</option>';
|
||||
$html.= '</select>';
|
||||
|
||||
$this->resprint = $html;
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to Add a printer in db
|
||||
*
|
||||
* @param string $name Printer name
|
||||
* @param int $type Printer type
|
||||
* @param string $parameter Printer parameter
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function AddPrinter($name, $type, $parameter)
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
$sql = 'INSERT INTO '.MAIN_DB_PREFIX.'printer_receipt';
|
||||
$sql.= ' (name, fk_type, parameter, entity)';
|
||||
$sql.= ' VALUES ("'.$this->db->escape($name).'", '.$type.', "'.$this->db->escape($parameter).'", '.$conf->entity.')';
|
||||
$resql = $this->db->query($sql);
|
||||
if (! $resql) {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror;
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to Update a printer in db
|
||||
*
|
||||
* @param string $name Printer name
|
||||
* @param int $type Printer type
|
||||
* @param string $parameter Printer parameter
|
||||
* @param int $printerid Printer id
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function UpdatePrinter($name, $type, $parameter, $printerid)
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
$sql = 'UPDATE '.MAIN_DB_PREFIX.'printer_receipt';
|
||||
$sql.= ' SET name="'.$this->db->escape($name).'"';
|
||||
$sql.= ', fk_type='.$type;
|
||||
$sql.= ', parameter="'.$this->db->escape($parameter).'"';
|
||||
$sql.= ' WHERE rowid='.$printerid;
|
||||
$resql = $this->db->query($sql);
|
||||
if (! $resql) {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror;
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to Delete a printer from db
|
||||
*
|
||||
* @param int $printerid Printer id
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function DeletePrinter($printerid)
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
$sql = 'DELETE FROM '.MAIN_DB_PREFIX.'printer_receipt';
|
||||
$sql.= ' WHERE rowid='.$printerid;
|
||||
$resql = $this->db->query($sql);
|
||||
if (! $resql) {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror;
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to Update a printer template in db
|
||||
*
|
||||
* @param string $name Template name
|
||||
* @param int $template Template
|
||||
* @param int $templateid Template id
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function UpdateTemplate($name, $template, $templateid)
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
$sql = 'UPDATE '.MAIN_DB_PREFIX.'printer_receipt_template';
|
||||
$sql.= ' SET name="'.$this->db->escape($name).'"';
|
||||
$sql.= ', template="'.$this->db->escape($template).'"';
|
||||
$sql.= ' WHERE rowid='.$templateid;
|
||||
$resql = $this->db->query($sql);
|
||||
if (! $resql) {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror;
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function to Send Test page to Printer
|
||||
*
|
||||
* @param int $printerid Printer id
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function SendTestToPrinter($printerid)
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
$img = new EscposImage(DOL_DOCUMENT_ROOT .'/theme/common/dolibarr_logo_bw.png');
|
||||
$ret = $this->InitPrinter($printerid);
|
||||
if ($ret>0) {
|
||||
setEventMessages($this->error, $this->errors, 'errors');
|
||||
} else {
|
||||
try {
|
||||
$this->printer->graphics($img);
|
||||
$this->printer->text("Hello World!\n");
|
||||
$testStr = "Testing 123";
|
||||
$this->printer->qrCode($testStr);
|
||||
$this->printer->text("Most simple example\n");
|
||||
$this->printer->feed();
|
||||
$this->printer->cut();
|
||||
//print '<pre>'.print_r($this->connector, true).'</pre>';
|
||||
$this->printer->close();
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->errors[] = $e->getMessage();
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to Print Receipt Ticket
|
||||
*
|
||||
* @param object $object order or invoice object
|
||||
* @param int $templateid Template id
|
||||
* @param int $printerid Printer id
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function SendToPrinter($object, $templateid, $printerid)
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
$ret = $this->loadTemplate($templateid);
|
||||
|
||||
// tags a remplacer par leur valeur avant de parser
|
||||
$this->template = str_replace('<dol_print_num_order>', $object->id, $this->template);
|
||||
$this->template = str_replace('<dol_print_customer_firstname>', $object->customer_firstname, $this->template);
|
||||
$this->template = str_replace('<dol_print_customer_lastname>', $object->customer_lastname, $this->template);
|
||||
$this->template = str_replace('<dol_print_customer_mail>', $object->customer_mail, $this->template);
|
||||
$this->template = str_replace('<dol_print_customer_phone>', $object->customer_phone, $this->template);
|
||||
$this->template = str_replace('<dol_print_customer_mobile>', $object->customer_mobile, $this->template);
|
||||
$this->template = str_replace('<dol_print_customer_skype>', $object->customer_skype, $this->template);
|
||||
$this->template = str_replace('<dol_print_customer_tax_number>', $object->customer_tax_number, $this->template);
|
||||
$this->template = str_replace('<dol_print_customer_account_balance>', $object->customer_account_balance, $this->template);
|
||||
$this->template = str_replace('<dol_print_vendor_firstname>', $object->vendor_firstname, $this->template);
|
||||
$this->template = str_replace('<dol_print_vendor_lastname>', $object->vendor_lastname, $this->template);
|
||||
|
||||
// parse template
|
||||
$p = xml_parser_create();
|
||||
xml_parse_into_struct($p, $this->template, $vals, $index);
|
||||
xml_parser_free($p);
|
||||
//print '<pre>'.print_r($index, true).'</pre>';
|
||||
//print '<pre>'.print_r($vals, true).'</pre>';
|
||||
// print ticket
|
||||
$level = 0;
|
||||
$ret = $this->InitPrinter($printerid);
|
||||
if ($ret>0) {
|
||||
setEventMessages($this->error, $this->errors, 'errors');
|
||||
} else {
|
||||
for ($line=0; $line < count($vals); $line++) {
|
||||
switch ($vals[$line]['tag']) {
|
||||
case 'DOL_ALIGN_CENTER':
|
||||
$this->printer->setJustification(Escpos::JUSTIFY_CENTER);
|
||||
$this->printer->text($vals[$line]['value']);
|
||||
break;
|
||||
case 'DOL_ALIGN_RIGHT':
|
||||
$this->printer->setJustification(Escpos::JUSTIFY_RIGHT);
|
||||
break;
|
||||
case 'DOL_ALIGN_LEFT':
|
||||
$this->printer->setJustification(Escpos::JUSTIFY_LEFT);
|
||||
break;
|
||||
case 'DOL_OPEN_DRAWER':
|
||||
$this->printer->pulse();
|
||||
break;
|
||||
case 'DOL_PRINT_BARCODE':
|
||||
// $vals[$line]['value'] -> barcode($content, $type)
|
||||
$this->printer->barcode($object->barcode);
|
||||
break;
|
||||
case 'DOL_PRINT_DATE_TIME':
|
||||
$this->printer->text($object->date);
|
||||
break;
|
||||
case 'DOL_PRINT_QRCODE':
|
||||
// $vals[$line]['value'] -> qrCode($content, $ec, $size, $model)
|
||||
$this->printer->qrcode($vals[$line]['value']);
|
||||
break;
|
||||
case 'DOL_CUT_PAPER_FULL':
|
||||
$this->printer->cut(Escpos::CUT_FULL);
|
||||
break;
|
||||
case 'DOL_CUT_PAPER_PARTIAL':
|
||||
$this->printer->cut(Escpos::CUT_PARTIAL);
|
||||
break;
|
||||
case 'DOL_USE_FONT_A':
|
||||
$this->printer->setFont(Escpos::FONT_A);
|
||||
$this->printer->text($vals[$line]['value']);
|
||||
break;
|
||||
case 'DOL_USE_FONT_B':
|
||||
$this->printer->setFont(Escpos::FONT_B);
|
||||
$this->printer->text($vals[$line]['value']);
|
||||
break;
|
||||
case 'DOL_USE_FONT_C':
|
||||
$this->printer->setFont(Escpos::FONT_C);
|
||||
$this->printer->text($vals[$line]['value']);
|
||||
break;
|
||||
default:
|
||||
$this->printer->text($vals[$line]['value']);
|
||||
$this->errors[] = 'UnknowTag: <'.strtolower($vals[$line]['tag']).'>';
|
||||
$error++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Close and print
|
||||
// uncomment next line to see content sent to printer
|
||||
//print '<pre>'.print_r($this->connector, true).'</pre>';
|
||||
$this->printer->close();
|
||||
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to load Template
|
||||
*
|
||||
* @param int $templateid Template id
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function loadTemplate($templateid)
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
$sql = 'SELECT template';
|
||||
$sql.= ' FROM '.MAIN_DB_PREFIX.'printer_receipt_template';
|
||||
$sql.= ' WHERE rowid='.$templateid;
|
||||
$sql.= ' AND entity = '.$conf->entity;
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$obj = $this->db->fetch_array($resql);
|
||||
} else {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror;
|
||||
}
|
||||
if (empty($obj)) {
|
||||
$error++;
|
||||
$this->errors[] = 'TemplateDontExist';
|
||||
} else {
|
||||
$this->template = $obj['0'];
|
||||
}
|
||||
|
||||
return $error;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Init Printer
|
||||
*
|
||||
* @param int $printerid Printer id
|
||||
* @return int 0 if OK; >0 if KO
|
||||
*/
|
||||
function InitPrinter($printerid)
|
||||
{
|
||||
global $conf;
|
||||
$error=0;
|
||||
$sql = 'SELECT rowid, name, fk_type, parameter';
|
||||
$sql.= ' FROM '.MAIN_DB_PREFIX.'printer_receipt';
|
||||
$sql.= ' WHERE rowid = '.$printerid;
|
||||
$sql.= ' AND entity = '.$conf->entity;
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$obj = $this->db->fetch_array($resql);
|
||||
} else {
|
||||
$error++;
|
||||
$this->errors[] = $this->db->lasterror;
|
||||
}
|
||||
if (empty($obj)) {
|
||||
$error++;
|
||||
$this->errors[] = 'PrinterDontExist';
|
||||
}
|
||||
if (! $error) {
|
||||
$parameter = $obj['parameter'];
|
||||
try {
|
||||
switch ($obj['fk_type']) {
|
||||
case 1:
|
||||
require_once DOL_DOCUMENT_ROOT .'/includes/escpos/src/DummyPrintConnector.php';
|
||||
$this->connector = new DummyPrintConnector();
|
||||
break;
|
||||
case 2:
|
||||
$this->connector = new FilePrintConnector($parameter);
|
||||
break;
|
||||
case 3:
|
||||
$parameters = explode(':', $parameter);
|
||||
$this->connector = new NetworkPrintConnector($parameters[0], $parameters[1]);
|
||||
break;
|
||||
case 4:
|
||||
$this->connector = new WindowsPrintConnector($parameter);
|
||||
break;
|
||||
default:
|
||||
$this->connector = 'CONNECTOR_UNKNOWN';
|
||||
break;
|
||||
}
|
||||
$this->printer = new Escpos($this->connector);
|
||||
} catch (Exception $e) {
|
||||
$this->errors[] = $e->getMessage();
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
return $error;
|
||||
}
|
||||
}
|
||||
72
htdocs/core/lib/receiptprinter.lib.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
/* Copyright (C) 2015 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2015 Frederic France <frederic.france@free.fr>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/core/lib/receiptprinter.lib.php
|
||||
* \ingroup printing
|
||||
* \brief Library for receipt printer functions
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Define head array for tabs of receipt printer setup pages
|
||||
*
|
||||
* @param string $mode Mode
|
||||
* @return Array of head
|
||||
*/
|
||||
function receiptprinteradmin_prepare_head($mode)
|
||||
{
|
||||
global $langs, $conf;
|
||||
|
||||
$h = 0;
|
||||
$head = array();
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT."/admin/receiptprinter.php?mode=config";
|
||||
$head[$h][1] = $langs->trans("ListPrinters");
|
||||
$head[$h][2] = 'config';
|
||||
$h++;
|
||||
|
||||
$head[$h][0] = DOL_URL_ROOT."/admin/receiptprinter.php?mode=template";
|
||||
$head[$h][1] = $langs->trans("SetupReceiptTemplate");
|
||||
$head[$h][2] = 'template';
|
||||
$h++;
|
||||
|
||||
if ($mode == 'test')
|
||||
{
|
||||
$head[$h][0] = DOL_URL_ROOT."/admin/receiptprinter.php?mode=test";
|
||||
$head[$h][1] = $langs->trans("TargetedPrinter");
|
||||
$head[$h][2] = 'test';
|
||||
$h++;
|
||||
}
|
||||
|
||||
|
||||
//$object=new stdClass();
|
||||
|
||||
// Show more tabs from modules
|
||||
// Entries must be declared in modules descriptor with line
|
||||
// $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
|
||||
// $this->tabs = array('entity:-tabname); to remove a tab
|
||||
//complete_head_from_modules($conf,$langs,$object,$head,$h,'printingadmin');
|
||||
|
||||
//complete_head_from_modules($conf,$langs,$object,$head,$h,'printing','remove');
|
||||
|
||||
return $head;
|
||||
}
|
||||
|
||||
|
||||
145
htdocs/core/modules/modReceiptPrinter.class.php
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
<?php
|
||||
/* Copyright (C) 2014-2015 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2015 Frederic France <frederic.france@free.fr>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \defgroup printing Module Receipt Printer
|
||||
* \brief Module for activation of printing icon to make receipt ticket
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file htdocs/core/modules/modReceiptPrinter.class.php
|
||||
* \ingroup printing
|
||||
* \brief File of class to describe and activate module Receipt Printer
|
||||
*/
|
||||
include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class to describe and activate module Receipt Printer
|
||||
*/
|
||||
class modReceiptPrinter extends DolibarrModules
|
||||
{
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param DoliDB $db Database handler
|
||||
*/
|
||||
function __construct($db)
|
||||
{
|
||||
$this->db = $db ;
|
||||
$this->numero = 67000;
|
||||
// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
|
||||
// It is used to group modules in module setup page
|
||||
$this->family = "technic";
|
||||
// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
|
||||
$this->name = preg_replace('/^mod/i','',get_class($this));
|
||||
// Module description, used if translation string 'ModuleXXXDesc' not found (where XXX is value of numeric property 'numero' of module)
|
||||
$this->description = "ReceiptPrinterDesc";
|
||||
$this->version = 'dolibarr'; // 'development' or 'experimental' or 'dolibarr' or version
|
||||
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
|
||||
// Where to store the module in setup page (0=common,1=interface,2=others,3=very specific)
|
||||
$this->special = 1;
|
||||
// Name of image file used for this module.
|
||||
// If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
|
||||
// If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
|
||||
$this->picto = 'printer';
|
||||
|
||||
// Data directories to create when module is enabled.
|
||||
$this->dirs = array();
|
||||
|
||||
// Config pages
|
||||
$this->config_page_url = array("receiptprinter.php");
|
||||
|
||||
// Dependencies
|
||||
$this->depends = array();
|
||||
$this->requiredby = array();
|
||||
$this->phpmin = array(5,1); // Minimum version of PHP required by module
|
||||
$this->need_dolibarr_version = array(3,9,-2); // Minimum version of Dolibarr required by module
|
||||
$this->conflictwith = array();
|
||||
$this->langfiles = array("receiptprinter");
|
||||
|
||||
// Constants
|
||||
$this->const = array();
|
||||
|
||||
// Boxes
|
||||
$this->boxes = array();
|
||||
|
||||
// Permissions
|
||||
$this->rights = array();
|
||||
$this->rights_class = 'receiptprinter';
|
||||
|
||||
$r=0;
|
||||
// $this->rights[$r][0] Id permission (unique tous modules confondus)
|
||||
// $this->rights[$r][1] Libelle par defaut si traduction de cle "PermissionXXX" non trouvee (XXX = Id permission)
|
||||
// $this->rights[$r][2] Non utilise
|
||||
// $this->rights[$r][3] 1=Permis par defaut, 0=Non permis par defaut
|
||||
// $this->rights[$r][4] Niveau 1 pour nommer permission dans code
|
||||
// $this->rights[$r][5] Niveau 2 pour nommer permission dans code
|
||||
|
||||
$r++;
|
||||
$this->rights[$r][0] = 67000;
|
||||
$this->rights[$r][1] = 'ReceiptPrinter';
|
||||
$this->rights[$r][2] = 'r';
|
||||
$this->rights[$r][3] = 1;
|
||||
$this->rights[$r][4] = 'read';
|
||||
|
||||
// Main menu entries
|
||||
$this->menus = array(); // List of menus to add
|
||||
$r=0;
|
||||
|
||||
// This is to declare the Top Menu entry:
|
||||
//$this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools', // Put 0 if this is a top menu
|
||||
// 'type'=>'left', // This is a Top menu entry
|
||||
// 'titre'=>'MenuDirectPrinting',
|
||||
// 'mainmenu'=>'printing',
|
||||
// 'url'=>'/printing/index.php',
|
||||
// 'langs'=>'printing', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
|
||||
// 'position'=>300,
|
||||
// 'enabled'=>'$conf->printing->enabled && $leftmenu==\'modulesadmintools\'',
|
||||
// 'perms'=>'$user->rights->printing->read', // Use 'perms'=>'1' if you want your menu with no permission rules
|
||||
// 'target'=>'',
|
||||
// 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both
|
||||
|
||||
$r++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function called when module is enabled.
|
||||
* The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
|
||||
* It also creates data directories
|
||||
*
|
||||
* @param string $options Options when enabling module ('', 'noboxes')
|
||||
* @return int 1 if OK, 0 if KO
|
||||
*/
|
||||
function init($options='')
|
||||
{
|
||||
global $conf;
|
||||
// Clean before activation
|
||||
$this->remove($options);
|
||||
$sql = array(
|
||||
"CREATE TABLE IF NOT EXISTS llx_printer_receipt (rowid int(11) NOT NULL AUTO_INCREMENT, name varchar(128), fk_type int(11), parameter varchar(128), entity int(11), PRIMARY KEY (rowid)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;",
|
||||
"CREATE TABLE IF NOT EXISTS llx_printer_receipt_template (rowid int(11) NOT NULL AUTO_INCREMENT, name varchar(128), template text, entity int(11), PRIMARY KEY (rowid)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;",
|
||||
);
|
||||
return $this->_init($sql,$options);
|
||||
}
|
||||
|
||||
}
|
||||
12
htdocs/includes/escpos/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Eclipse files
|
||||
.settings/*
|
||||
.project
|
||||
.buildpath
|
||||
|
||||
# doxygen files
|
||||
doc/html
|
||||
doc/latex
|
||||
doc/doxygen_sqlite3.db
|
||||
|
||||
# composer files
|
||||
vendor/
|
||||
851
htdocs/includes/escpos/Escpos.php
Normal file
|
|
@ -0,0 +1,851 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
27
htdocs/includes/escpos/LICENSE.md
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
escpos-php, a Thermal receipt printer library, for use with
|
||||
ESC/POS compatible printers.
|
||||
|
||||
Copyright (c) 2014-15 Michael Billington <michael.billington@gmail.com>,
|
||||
incorporating modifications by:
|
||||
- Roni Saha <roni.cse@gmail.com>
|
||||
- Gergely Radics <gerifield@ustream.tv>
|
||||
- Warren Doyle <w.doyle@fuelled.co>
|
||||
|
||||
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.
|
||||
|
||||
352
htdocs/includes/escpos/README.md
Normal file
|
|
@ -0,0 +1,352 @@
|
|||
ESC/POS Print Driver for PHP
|
||||
============================
|
||||
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
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . "/Escpos.php");
|
||||
$printer = new Escpos();
|
||||
$printer -> 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
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . "/Escpos.php");
|
||||
$connector = new NetworkPrintConnector("10.x.x.x", 9100);
|
||||
$printer = new Escpos($connector);
|
||||
$printer -> text("Hello World!\n");
|
||||
$printer -> cut();
|
||||
$printer -> close();
|
||||
```
|
||||
|
||||
Or to a local printer:
|
||||
```php
|
||||
<?php
|
||||
require_once(dirname(__FILE__) . "/Escpos.php");
|
||||
$connector = new FilePrintConnector("/dev/ttyS0");
|
||||
$printer = new Escpos($connector);
|
||||
$printer -> 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
|
||||
-------------
|
||||
|
||||
### Interfaces and operating systems
|
||||
This driver is known to work with the following OS/interface combinations:
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th>Linux</th>
|
||||
<th>Mac</th>
|
||||
<th>Windows</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Ethernet</th>
|
||||
<td><a href="https://github.com/mike42/escpos-php/tree/master/example/interface/ethernet.php">Yes</a></td>
|
||||
<td><a href="https://github.com/mike42/escpos-php/tree/master/example/interface/ethernet.php">Yes</a></td>
|
||||
<td><a href="https://github.com/mike42/escpos-php/tree/master/example/interface/ethernet.php">Yes</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>USB</th>
|
||||
<td><a href="https://github.com/mike42/escpos-php/tree/master/example/interface/linux-usb.php">Yes</a></td>
|
||||
<td>Not tested</td>
|
||||
<td><a href="https://github.com/mike42/escpos-php/tree/master/example/interface/windows-usb.php">Yes</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>USB-serial</th>
|
||||
<td>Yes</td>
|
||||
<td>Yes</td>
|
||||
<td>Yes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Serial</th>
|
||||
<td>Yes</td>
|
||||
<td>Yes</td>
|
||||
<td>Yes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Parallel</th>
|
||||
<td><a href="https://github.com/mike42/escpos-php/tree/master/example/interface/windows-lpt.php">Yes</a></td>
|
||||
<td>Not tested</td>
|
||||
<td>Yes</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>SMB shared</th>
|
||||
<td><a href="https://github.com/mike42/escpos-php/tree/master/example/interface/smb.php">Yes</a></td>
|
||||
<td>No</td>
|
||||
<td><a href="https://github.com/mike42/escpos-php/tree/master/example/interface/smb.php">Yes</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Printers
|
||||
Many thermal receipt printers support ESC/POS to some degree. This driver has been known to work with:
|
||||
|
||||
- EPOS TEP 220M
|
||||
- Epson TM-T88III
|
||||
- Epson TM-T88IV
|
||||
- Epson TM-T70
|
||||
- Epson TM-T82II
|
||||
- Epson TM-T20
|
||||
- Epson TM-T70II
|
||||
- Epson TM-U220
|
||||
- Epson FX-890 (requires `feedForm()` to release paper).
|
||||
- Okipos 80 Plus III
|
||||
- P-822D
|
||||
- SEYPOS PRP-300 (Also marketed as TYSSO PRP-300)
|
||||
- Star TSP-650
|
||||
- Star TUP-592
|
||||
- Xprinter XP-Q800
|
||||
- Zijang NT-58H
|
||||
- Zijang ZJ-5870
|
||||
- Zijang ZJ-5890T (Marketed as POS 5890T)
|
||||
|
||||
If you use any other printer with this code, please let me know so I can add it to the list.
|
||||
|
||||
Available methods
|
||||
-----------------
|
||||
|
||||
### __construct(PrintConnector $connector, AbstractCapabilityProfile $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.
|
||||
|
||||
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.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `string $content`: The information to encode.
|
||||
- `int $type`: The barcode standard to output. If not specified, `Escpos::BARCODE_CODE39` will be used.
|
||||
|
||||
Currently supported barcode standards are (depending on your printer):
|
||||
|
||||
- `BARCODE_UPCA`
|
||||
- `BARCODE_UPCE`
|
||||
- `BARCODE_JAN13`
|
||||
- `BARCODE_JAN8`
|
||||
- `BARCODE_CODE39`
|
||||
- `BARCODE_ITF`
|
||||
- `BARCODE_CODABAR`
|
||||
|
||||
Note that some barcode standards can only encode numbers, so attempting to print non-numeric codes with them may result in strange behaviour.
|
||||
|
||||
### bitImage(EscposImage $image, $size)
|
||||
See [graphics()](#graphicsescposimage-image-size) below.
|
||||
|
||||
### cut($mode, $lines)
|
||||
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 $lines`: Number of lines to feed before cutting. If not specified, 3 will be used.
|
||||
|
||||
### feed($lines)
|
||||
Print and feed line / Print and feed n lines.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `int $lines`: Number of lines to feed
|
||||
|
||||
### feedForm()
|
||||
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.
|
||||
|
||||
### feedReverse($lines)
|
||||
Print and reverse feed n lines.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `int $lines`: number of lines to feed. If not specified, 1 line will be fed.
|
||||
|
||||
### graphics(EscposImage $image, $size)
|
||||
Print an image to the printer.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `EscposImage $img`: The image to print.
|
||||
- `int $size`: Output size modifier for the image.
|
||||
|
||||
Size modifiers are:
|
||||
|
||||
- `IMG_DEFAULT` (leave image at original size)
|
||||
- `IMG_DOUBLE_WIDTH`
|
||||
- `IMG_DOUBLE_HEIGHT`
|
||||
|
||||
A minimal example:
|
||||
|
||||
```php
|
||||
<?php
|
||||
$img = new EscposImage("logo.png");
|
||||
$printer -> 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.
|
||||
|
||||
### initialize()
|
||||
Initialize printer. This resets formatting back to the defaults.
|
||||
|
||||
### 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.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `int $pin`: 0 or 1, for pin 2 or pin 5 kick-out connector respectively.
|
||||
- `int $on_ms`: pulse ON time, in milliseconds.
|
||||
- `int $off_ms`: pulse OFF time, in milliseconds.
|
||||
|
||||
### qrCode($content, $ec, $size, $model)
|
||||
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 $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).
|
||||
|
||||
### 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()`.
|
||||
|
||||
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`
|
||||
|
||||
### setBarcodeHeight($height)
|
||||
Set barcode height.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `int $height`: Height in dots. If not specified, 8 will be used.
|
||||
|
||||
### setDoubleStrike($on)
|
||||
Turn double-strike mode on/off.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `boolean $on`: true for double strike, false for no double strike.
|
||||
|
||||
### setEmphasis($on)
|
||||
Turn emphasized mode on/off.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `boolean $on`: true for emphasis, false for no emphasis.
|
||||
|
||||
### setFont($font)
|
||||
Select font. Most printers have two fonts (Fonts A and B), and some have a third (Font C).
|
||||
|
||||
Parameters:
|
||||
|
||||
- `int $font`: The font to use. Must be either `Escpos::FONT_A`, `Escpos::FONT_B`, or `Escpos::FONT_C`.
|
||||
|
||||
### setJustification($justification)
|
||||
Select justification.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `int $justification`: One of `Escpos::JUSTIFY_LEFT`, `Escpos::JUSTIFY_CENTER`, or `Escpos::JUSTIFY_RIGHT`.
|
||||
|
||||
### setReverseColors($on)
|
||||
Set black/white reverse mode on or off. In this mode, text is printed white on a black background.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `boolean $on`: True to enable, false to disable.
|
||||
|
||||
### setTextSize($widthMultiplier, $heightMultiplier)
|
||||
Set the size of text, as a multiple of the normal size.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `int $widthMultiplier`: Multiple of the regular height to use (range 1 - 8).
|
||||
- `int $heightMultiplier`: Multiple of the regular height to use (range 1 - 8).
|
||||
|
||||
### setUnderline($underline)
|
||||
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`.
|
||||
|
||||
### text($str)
|
||||
Add text to the buffer. Text should either be followed by a line-break, or `feed()` should be called after this.
|
||||
|
||||
Parameters:
|
||||
|
||||
- `string $str`: The string to print.
|
||||
|
||||
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)
|
||||
|
||||
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:
|
||||
|
||||
- [wdoyle/EpsonESCPOS-PHP](https://github.com/wdoyle/EpsonESCPOS-PHP)
|
||||
- [ronisaha/php-esc-pos](https://github.com/ronisaha/php-esc-pos)
|
||||
|
||||
Vendor documentation
|
||||
--------------------
|
||||
Epson notes that not all of its printers support all ESC/POS features, and includes a table in their documentation:
|
||||
|
||||
* [FAQ about ESC/POS from Epson](http://content.epson.de/fileadmin/content/files/RSD/downloads/escpos.pdf)
|
||||
|
||||
Note that many printers produced by other vendors use the same standard, and are compatible by varying degrees.
|
||||
|
||||
36
htdocs/includes/escpos/composer.json
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"name": "mike42/escpos-php",
|
||||
"type": "library",
|
||||
"description": "Thermal receipt printer library, for use with ESC/POS compatible 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"
|
||||
},
|
||||
{
|
||||
"name": "Roni Saha",
|
||||
"email": "roni.cse@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Gergely Radics",
|
||||
"email": "gerifield@ustream.tv"
|
||||
},
|
||||
{
|
||||
"name": "Warren Doyle",
|
||||
"email": "w.doyle@fuelled.co"
|
||||
},
|
||||
{
|
||||
"name": "vharo",
|
||||
"email": "vharo@geepok.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.5.*"
|
||||
}
|
||||
}
|
||||
975
htdocs/includes/escpos/composer.lock
generated
Normal file
|
|
@ -0,0 +1,975 @@
|
|||
{
|
||||
"_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",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "fd25f2b816df83dabf03fe7259ad4018",
|
||||
"packages": [],
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
"version": "1.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/instantiator.git",
|
||||
"reference": "f976e5de371104877ebc89bd8fecb0019ed9c119"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119",
|
||||
"reference": "f976e5de371104877ebc89bd8fecb0019ed9c119",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3,<8.0-DEV"
|
||||
},
|
||||
"require-dev": {
|
||||
"athletic/athletic": "~0.1.8",
|
||||
"ext-pdo": "*",
|
||||
"ext-phar": "*",
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"squizlabs/php_codesniffer": "2.0.*@ALPHA"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Doctrine\\Instantiator\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marco Pivetta",
|
||||
"email": "ocramius@gmail.com",
|
||||
"homepage": "http://ocramius.github.com/"
|
||||
}
|
||||
],
|
||||
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
|
||||
"homepage": "https://github.com/doctrine/instantiator",
|
||||
"keywords": [
|
||||
"constructor",
|
||||
"instantiate"
|
||||
],
|
||||
"time": "2014-10-13 12:58:55"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-docblock",
|
||||
"version": "2.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
||||
"reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"dflydev/markdown": "~1.0",
|
||||
"erusev/parsedown": "~1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"phpDocumentor": [
|
||||
"src/"
|
||||
]
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mike van Riel",
|
||||
"email": "mike.vanriel@naenius.com"
|
||||
}
|
||||
],
|
||||
"time": "2015-02-03 12:10:50"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5",
|
||||
"reference": "8724cd239f8ef4c046f55a3b18b4d91cc7f3e4c5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.0.2",
|
||||
"phpdocumentor/reflection-docblock": "~2.0",
|
||||
"sebastian/comparator": "~1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "~2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Prophecy\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Konstantin Kudryashov",
|
||||
"email": "ever.zet@gmail.com",
|
||||
"homepage": "http://everzet.com"
|
||||
},
|
||||
{
|
||||
"name": "Marcello Duarte",
|
||||
"email": "marcello.duarte@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "Highly opinionated mocking framework for PHP 5.3+",
|
||||
"homepage": "https://github.com/phpspec/prophecy",
|
||||
"keywords": [
|
||||
"Double",
|
||||
"Dummy",
|
||||
"fake",
|
||||
"mock",
|
||||
"spy",
|
||||
"stub"
|
||||
],
|
||||
"time": "2015-03-27 19:31:25"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
"version": "2.0.15",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
|
||||
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/34cc484af1ca149188d0d9e91412191e398e0b67",
|
||||
"reference": "34cc484af1ca149188d0d9e91412191e398e0b67",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"phpunit/php-file-iterator": "~1.3",
|
||||
"phpunit/php-text-template": "~1.2",
|
||||
"phpunit/php-token-stream": "~1.3",
|
||||
"sebastian/environment": "~1.0",
|
||||
"sebastian/version": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-xdebug": ">=2.1.4",
|
||||
"phpunit/phpunit": "~4"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "*",
|
||||
"ext-xdebug": ">=2.2.1",
|
||||
"ext-xmlwriter": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sb@sebastian-bergmann.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
|
||||
"homepage": "https://github.com/sebastianbergmann/php-code-coverage",
|
||||
"keywords": [
|
||||
"coverage",
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-01-24 10:06:35"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-file-iterator",
|
||||
"version": "1.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
|
||||
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/acd690379117b042d1c8af1fafd61bde001bf6bb",
|
||||
"reference": "acd690379117b042d1c8af1fafd61bde001bf6bb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"File/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"include-path": [
|
||||
""
|
||||
],
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sb@sebastian-bergmann.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "FilterIterator implementation that filters files based on a list of suffixes.",
|
||||
"homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
|
||||
"keywords": [
|
||||
"filesystem",
|
||||
"iterator"
|
||||
],
|
||||
"time": "2013-10-10 15:34:57"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-text-template",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-text-template.git",
|
||||
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
|
||||
"reference": "206dfefc0ffe9cebf65c413e3d0e809c82fbf00a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"Text/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"include-path": [
|
||||
""
|
||||
],
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sb@sebastian-bergmann.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "Simple template engine.",
|
||||
"homepage": "https://github.com/sebastianbergmann/php-text-template/",
|
||||
"keywords": [
|
||||
"template"
|
||||
],
|
||||
"time": "2014-01-30 17:20:04"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-timer",
|
||||
"version": "1.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-timer.git",
|
||||
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
|
||||
"reference": "19689d4354b295ee3d8c54b4f42c3efb69cbc17c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"PHP/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"include-path": [
|
||||
""
|
||||
],
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sb@sebastian-bergmann.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "Utility class for timing",
|
||||
"homepage": "https://github.com/sebastianbergmann/php-timer/",
|
||||
"keywords": [
|
||||
"timer"
|
||||
],
|
||||
"time": "2013-08-02 07:42:54"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-token-stream",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
|
||||
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/db32c18eba00b121c145575fcbcd4d4d24e6db74",
|
||||
"reference": "db32c18eba00b121c145575fcbcd4d4d24e6db74",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-tokenizer": "*",
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.4-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de"
|
||||
}
|
||||
],
|
||||
"description": "Wrapper around PHP's tokenizer extension.",
|
||||
"homepage": "https://github.com/sebastianbergmann/php-token-stream/",
|
||||
"keywords": [
|
||||
"tokenizer"
|
||||
],
|
||||
"time": "2015-01-17 09:51:32"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "4.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d6429b0995b24a2d9dfe5587ee3a7071c1161af4",
|
||||
"reference": "d6429b0995b24a2d9dfe5587ee3a7071c1161af4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-dom": "*",
|
||||
"ext-json": "*",
|
||||
"ext-pcre": "*",
|
||||
"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",
|
||||
"phpunit/php-text-template": "~1.2",
|
||||
"phpunit/php-timer": "~1.0.2",
|
||||
"phpunit/phpunit-mock-objects": "~2.3",
|
||||
"sebastian/comparator": "~1.1",
|
||||
"sebastian/diff": "~1.1",
|
||||
"sebastian/environment": "~1.2",
|
||||
"sebastian/exporter": "~1.2",
|
||||
"sebastian/global-state": "~1.0",
|
||||
"sebastian/version": "~1.0",
|
||||
"symfony/yaml": "~2.0"
|
||||
},
|
||||
"suggest": {
|
||||
"phpunit/php-invoker": "~1.1"
|
||||
},
|
||||
"bin": [
|
||||
"phpunit"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.5.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "The PHP Unit Testing framework.",
|
||||
"homepage": "https://phpunit.de/",
|
||||
"keywords": [
|
||||
"phpunit",
|
||||
"testing",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-03-29 09:24:05"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/phpunit-mock-objects",
|
||||
"version": "2.3.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
|
||||
"reference": "74ffb87f527f24616f72460e54b595f508dccb5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/74ffb87f527f24616f72460e54b595f508dccb5c",
|
||||
"reference": "74ffb87f527f24616f72460e54b595f508dccb5c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "~1.0,>=1.0.2",
|
||||
"php": ">=5.3.3",
|
||||
"phpunit/php-text-template": "~1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.4"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-soap": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sb@sebastian-bergmann.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"description": "Mock Object library for PHPUnit",
|
||||
"homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
|
||||
"keywords": [
|
||||
"mock",
|
||||
"xunit"
|
||||
],
|
||||
"time": "2015-04-02 05:36:41"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/comparator",
|
||||
"version": "1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/comparator.git",
|
||||
"reference": "1dd8869519a225f7f2b9eb663e225298fade819e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dd8869519a225f7f2b9eb663e225298fade819e",
|
||||
"reference": "1dd8869519a225f7f2b9eb663e225298fade819e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"sebastian/diff": "~1.2",
|
||||
"sebastian/exporter": "~1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.1.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jeff Welch",
|
||||
"email": "whatthejeff@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Volker Dusch",
|
||||
"email": "github@wallbash.com"
|
||||
},
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@2bepublished.at"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de"
|
||||
}
|
||||
],
|
||||
"description": "Provides the functionality to compare PHP values for equality",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/comparator",
|
||||
"keywords": [
|
||||
"comparator",
|
||||
"compare",
|
||||
"equality"
|
||||
],
|
||||
"time": "2015-01-29 16:28:08"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/diff",
|
||||
"version": "1.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/diff.git",
|
||||
"reference": "863df9687835c62aa423a22412d26fa2ebde3fd3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3",
|
||||
"reference": "863df9687835c62aa423a22412d26fa2ebde3fd3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kore Nordmann",
|
||||
"email": "mail@kore-nordmann.de"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de"
|
||||
}
|
||||
],
|
||||
"description": "Diff implementation",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/diff",
|
||||
"keywords": [
|
||||
"diff"
|
||||
],
|
||||
"time": "2015-02-22 15:13:53"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/environment",
|
||||
"version": "1.2.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/environment.git",
|
||||
"reference": "5a8c7d31914337b69923db26c4221b81ff5a196e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5a8c7d31914337b69923db26c4221b81ff5a196e",
|
||||
"reference": "5a8c7d31914337b69923db26c4221b81ff5a196e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de"
|
||||
}
|
||||
],
|
||||
"description": "Provides functionality to handle HHVM/PHP environments",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/environment",
|
||||
"keywords": [
|
||||
"Xdebug",
|
||||
"environment",
|
||||
"hhvm"
|
||||
],
|
||||
"time": "2015-01-01 10:01:08"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/exporter",
|
||||
"version": "1.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/exporter.git",
|
||||
"reference": "84839970d05254c73cde183a721c7af13aede943"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/84839970d05254c73cde183a721c7af13aede943",
|
||||
"reference": "84839970d05254c73cde183a721c7af13aede943",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"sebastian/recursion-context": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jeff Welch",
|
||||
"email": "whatthejeff@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Volker Dusch",
|
||||
"email": "github@wallbash.com"
|
||||
},
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@2bepublished.at"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de"
|
||||
},
|
||||
{
|
||||
"name": "Adam Harvey",
|
||||
"email": "aharvey@php.net"
|
||||
}
|
||||
],
|
||||
"description": "Provides the functionality to export PHP variables for visualization",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/exporter",
|
||||
"keywords": [
|
||||
"export",
|
||||
"exporter"
|
||||
],
|
||||
"time": "2015-01-27 07:23:06"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/global-state",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/global-state.git",
|
||||
"reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
|
||||
"reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.2"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-uopz": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de"
|
||||
}
|
||||
],
|
||||
"description": "Snapshotting of global state",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/global-state",
|
||||
"keywords": [
|
||||
"global state"
|
||||
],
|
||||
"time": "2014-10-06 09:23:50"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/recursion-context",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/recursion-context.git",
|
||||
"reference": "3989662bbb30a29d20d9faa04a846af79b276252"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/3989662bbb30a29d20d9faa04a846af79b276252",
|
||||
"reference": "3989662bbb30a29d20d9faa04a846af79b276252",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.4"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jeff Welch",
|
||||
"email": "whatthejeff@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de"
|
||||
},
|
||||
{
|
||||
"name": "Adam Harvey",
|
||||
"email": "aharvey@php.net"
|
||||
}
|
||||
],
|
||||
"description": "Provides functionality to recursively process PHP variables",
|
||||
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
|
||||
"time": "2015-01-24 09:48:32"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/version",
|
||||
"version": "1.0.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/version.git",
|
||||
"reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/version/zipball/ab931d46cd0d3204a91e1b9a40c4bc13032b58e4",
|
||||
"reference": "ab931d46cd0d3204a91e1b9a40c4bc13032b58e4",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"src/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Sebastian Bergmann",
|
||||
"email": "sebastian@phpunit.de",
|
||||
"role": "lead"
|
||||
}
|
||||
],
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v2.6.6",
|
||||
"target-dir": "Symfony/Component/Yaml",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/Yaml.git",
|
||||
"reference": "174f009ed36379a801109955fc5a71a49fe62dd4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/Yaml/zipball/174f009ed36379a801109955fc5a71a49fe62dd4",
|
||||
"reference": "174f009ed36379a801109955fc5a71a49fe62dd4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/phpunit-bridge": "~2.7"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.6-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Symfony\\Component\\Yaml\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "http://symfony.com/contributors"
|
||||
},
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
}
|
||||
],
|
||||
"description": "Symfony Yaml Component",
|
||||
"homepage": "http://symfony.com",
|
||||
"time": "2015-03-30 15:54:10"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"platform-dev": []
|
||||
}
|
||||
9
htdocs/includes/escpos/doc/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
html: ../Escpos.php escpos.conf
|
||||
doxygen escpos.conf
|
||||
|
||||
latex: html
|
||||
# Do nothing
|
||||
|
||||
clean:
|
||||
rm --preserve-root -Rf html latex doxygen_sqlite3.db
|
||||
|
||||
2352
htdocs/includes/escpos/doc/escpos.conf
Normal file
26
htdocs/includes/escpos/example/README.md
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
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)
|
||||
|
||||
181
htdocs/includes/escpos/example/barcode.php
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
require_once (dirname ( __FILE__ ) . "/../Escpos.php");
|
||||
$printer = new Escpos ();
|
||||
$printer->setBarcodeHeight ( 40 );
|
||||
|
||||
/* Text position */
|
||||
$printer->selectPrintMode ( Escpos::MODE_DOUBLE_HEIGHT | Escpos::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"
|
||||
);
|
||||
foreach ( $hri as $position => $caption ) {
|
||||
$printer->text ( $caption . "\n" );
|
||||
$printer->setBarcodeTextPosition ( $position );
|
||||
$printer->barcode ( "012345678901", Escpos::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->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->cut ();
|
||||
$printer->close ();
|
||||
|
||||
32
htdocs/includes/escpos/example/bit-image.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/* Example print-outs using the older bit image print command */
|
||||
require_once(dirname(__FILE__) . "/../Escpos.php");
|
||||
$printer = new Escpos();
|
||||
|
||||
try {
|
||||
$tux = new EscposImage("resources/tux.png");
|
||||
|
||||
$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, 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 -> cut();
|
||||
$printer -> close();
|
||||
?>
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<?php
|
||||
/* Change to the correct path if you copy this example! */
|
||||
require_once(dirname(__FILE__) . "/../Escpos.php");
|
||||
|
||||
/**
|
||||
* This example builds on character-encodings.php, also providing an image-based rendering.
|
||||
* This is quite slow, since a) the buffers are changed dozens of
|
||||
* times in the example, and b) It involves sending very wide images, which printers don't like!
|
||||
*
|
||||
* There are currently no test cases around the image printing, since it is an experimental feature.
|
||||
*
|
||||
* It does, however, illustrate the way that more encodings are available when image output is used.
|
||||
*/
|
||||
include(dirname(__FILE__) . '/resources/character-encoding-test-strings.inc');
|
||||
|
||||
try {
|
||||
// Enter connector and capability profile
|
||||
$connector = new FilePrintConnector("php://stdout");
|
||||
$profile = DefaultCapabilityProfile::getInstance();
|
||||
$buffers = array(new EscposPrintBuffer(), new ImagePrintBuffer());
|
||||
|
||||
/* Print a series of receipts containing i18n example strings */
|
||||
$printer = new Escpos($connector, $profile);
|
||||
$printer -> 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();
|
||||
|
||||
/* Close printer */
|
||||
$printer -> close();
|
||||
} catch(Exception $e) {
|
||||
echo "Couldn't print to this printer: " . $e -> getMessage() . "\n";
|
||||
}
|
||||
|
||||
58
htdocs/includes/escpos/example/character-encodings.php
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
/* Change to the correct path if you copy this example! */
|
||||
require_once(dirname(__FILE__) . "/../Escpos.php");
|
||||
|
||||
/**
|
||||
* This demonstrates available character encodings. Escpos-php accepts UTF-8,
|
||||
* and converts this to lower-level data to the printer. This is a complex area, so be
|
||||
* prepared to code a model-specific hack ('CapabilityProfile') for your printer.
|
||||
*
|
||||
* If you run into trouble, please file an issue on GitHub, including at a minimum:
|
||||
* - A UTF-8 test string in the language you're working in, and
|
||||
* - A test print or link to a technical document which lists the available
|
||||
* code pages ('character code tables') for your printer.
|
||||
*
|
||||
* The DefaultCapabilityProfile works for Espson-branded printers. For other models, you
|
||||
* must use/create a PrinterCapabilityProfile for your printer containing a list of code
|
||||
* page numbers for your printer- otherwise you will get mojibake.
|
||||
*
|
||||
* If you do not intend to use non-English characters, then use SimpleCapabilityProfile,
|
||||
* which has only the default encoding, effectively disabling code page changes.
|
||||
*/
|
||||
|
||||
include(dirname(__FILE__) . '/resources/character-encoding-test-strings.inc');
|
||||
try {
|
||||
// Enter connector and capability profile (to match your printer)
|
||||
$connector = new FilePrintConnector("php://stdout");
|
||||
$profile = DefaultCapabilityProfile::getInstance();
|
||||
|
||||
/* Print a series of receipts containing i18n example strings */
|
||||
$printer = new Escpos($connector, $profile);
|
||||
$printer -> 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();
|
||||
|
||||
/* Close printer */
|
||||
$printer -> close();
|
||||
} catch(Exception $e) {
|
||||
echo "Couldn't print to this printer: " . $e -> getMessage() . "\n";
|
||||
}
|
||||
|
||||
71
htdocs/includes/escpos/example/character-tables.php
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
/**
|
||||
* This demo prints out supported code pages on your printer. This is intended
|
||||
* 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");
|
||||
|
||||
// Enter connector and capability profile (to match your printer)
|
||||
$connector = new FilePrintConnector("php://stdout");
|
||||
$profile = DefaultCapabilityProfile::getInstance();
|
||||
$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();
|
||||
$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);
|
||||
}
|
||||
}
|
||||
$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");
|
||||
}
|
||||
}
|
||||
167
htdocs/includes/escpos/example/demo.php
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
<?php
|
||||
/**
|
||||
* This is a demo script for the functions of the PHP ESC/POS print driver,
|
||||
* Escpos.php.
|
||||
*
|
||||
* Most printers implement only a subset of the functionality of the driver, so
|
||||
* will not render this output correctly in all cases.
|
||||
*
|
||||
* @author Michael Billington <michael.billington@gmail.com>
|
||||
*/
|
||||
require_once(dirname(__FILE__) . "/../Escpos.php");
|
||||
$printer = new Escpos();
|
||||
|
||||
/* 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(
|
||||
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 -> 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(Escpos::CUT_PARTIAL);
|
||||
$printer -> text("Full cut\n");
|
||||
$printer -> cut(Escpos::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(
|
||||
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 -> 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 -> setJustification(); // Reset
|
||||
$printer -> cut();
|
||||
|
||||
/* Barcodes - see barcode.php for more detail */
|
||||
$printer -> setBarcodeHeight(80);
|
||||
$printer->setBarcodeTextPosition ( Escpos::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");
|
||||
}
|
||||
$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");
|
||||
}
|
||||
$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 -> cut();
|
||||
|
||||
/* Pulse */
|
||||
$printer -> pulse();
|
||||
|
||||
/* Always close the printer! On some PrintConnectors, no actual
|
||||
* data is sent until the printer is closed. */
|
||||
$printer -> close();
|
||||
?>
|
||||
32
htdocs/includes/escpos/example/graphics.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/* Print-outs using the newer graphics print command */
|
||||
|
||||
require_once(dirname(__FILE__) . "/../Escpos.php");
|
||||
$printer = new Escpos();
|
||||
|
||||
try {
|
||||
$tux = new EscposImage("resources/tux.png");
|
||||
|
||||
$printer -> 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");
|
||||
}
|
||||
|
||||
$printer -> close();
|
||||
?>
|
||||
8
htdocs/includes/escpos/example/interface/README.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
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
|
||||
22
htdocs/includes/escpos/example/interface/ethernet.php
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
/* Change to the correct path if you copy this example! */
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
|
||||
/* Most printers are open on port 9100, so you just need to know the IP
|
||||
* address of your receipt printer, and then fsockopen() it on that port.
|
||||
*/
|
||||
try {
|
||||
$connector = null;
|
||||
//$connector = new NetworkPrintConnector("10.x.x.x", 9100);
|
||||
|
||||
/* 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";
|
||||
}
|
||||
|
||||
33
htdocs/includes/escpos/example/interface/linux-usb.php
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
/* Change to the correct path if you copy this example! */
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
|
||||
/**
|
||||
* On Linux, use the usblp module to make your printer available as a device
|
||||
* file. This is generally the default behaviour if you don't install any
|
||||
* vendor drivers.
|
||||
*
|
||||
* Once this is done, use a FilePrintConnector to open the device.
|
||||
*
|
||||
* Troubleshooting: On Debian, you must be in the lp group to access this file.
|
||||
* dmesg to see what happens when you plug in your printer to make sure no
|
||||
* other drivers are unloading the module.
|
||||
*/
|
||||
try {
|
||||
// Enter the device file for your USB printer here
|
||||
$connector = null;
|
||||
//$connector = new FilePrintConnector("/dev/usb/lp0");
|
||||
//$connector = new FilePrintConnector("/dev/usb/lp1");
|
||||
//$connector = new FilePrintConnector("/dev/usb/lp2");
|
||||
|
||||
/* 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";
|
||||
}
|
||||
|
||||
51
htdocs/includes/escpos/example/interface/smb.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/* Change to the correct path if you copy this example! */
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
|
||||
/**
|
||||
* Install the printer using USB printing support, and the "Generic / Text Only" driver,
|
||||
* then share it.
|
||||
*
|
||||
* Use a WindowsPrintConnector with the share name to print. This works on either
|
||||
* Windows or Linux.
|
||||
*
|
||||
* Troubleshooting: Fire up a command prompt/terminal, and ensure that (if your printer is
|
||||
* shared as "Receipt Printer"), the following commands work.
|
||||
*
|
||||
* Windows: (use an appropriate "net use" command if you need authentication)
|
||||
* 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
|
||||
*
|
||||
* 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 = 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";
|
||||
}
|
||||
30
htdocs/includes/escpos/example/interface/windows-lpt.php
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
/* Change to the correct path if you copy this example! */
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
|
||||
/**
|
||||
* Assuming your printer is available at LPT1,
|
||||
* simpy instantiate a WindowsPrintConnector to it.
|
||||
*
|
||||
* When troubleshooting, make sure you can send it
|
||||
* data from the command-line first:
|
||||
* 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");
|
||||
|
||||
/* 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";
|
||||
}
|
||||
32
htdocs/includes/escpos/example/interface/windows-usb.php
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
/* Change to the correct path if you copy this example! */
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
|
||||
/**
|
||||
* Install the printer using USB printing support, and the "Generic / Text Only" driver,
|
||||
* then share it (you can use a firewall so that it can only be seen locally).
|
||||
*
|
||||
* Use a WindowsPrintConnector with the share name to print.
|
||||
*
|
||||
* Troubleshooting: Fire up a command prompt, and ensure that (if your printer is shared as
|
||||
* "Receipt Printer), the following commands work:
|
||||
*
|
||||
* 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");
|
||||
|
||||
/* 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";
|
||||
}
|
||||
53
htdocs/includes/escpos/example/print-from-html.php
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__)."/../Escpos.php");
|
||||
/*
|
||||
* Due to its complxity, escpos-php does not support HTML input. To print HTML,
|
||||
* either convert it to calls on the Escpos() object, or rasterise the page with
|
||||
* wkhtmltopdf, an external package which is designed to handle HTML efficiently.
|
||||
*
|
||||
* This example is provided to get you started.
|
||||
*
|
||||
* Note: Depending on the height of your pages, it is suggested that you chop it
|
||||
* into smaller sections, as printers simply don't have the buffer capacity for
|
||||
* very large images.
|
||||
*
|
||||
* As always, you can trade off quality for capacity by halving the width
|
||||
* (550 -> 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");
|
||||
}
|
||||
|
||||
/* Load up the image */
|
||||
try {
|
||||
$img = new EscposImage($dest);
|
||||
} catch(Exception $e) {
|
||||
unlink($dest);
|
||||
throw $e;
|
||||
}
|
||||
unlink($dest);
|
||||
|
||||
/* 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();
|
||||
}
|
||||
|
||||
71
htdocs/includes/escpos/example/print-from-pdf.php
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . '/../Escpos.php');
|
||||
/*
|
||||
* This is three examples in one:
|
||||
* 1: Print an entire PDF, normal quality.
|
||||
* 2: Print at a lower quality for speed increase (CPU & transfer)
|
||||
* 3: Cache rendered documents for a speed increase (removes CPU image processing completely on subsequent prints)
|
||||
*/
|
||||
|
||||
/* 1: Print an entire PDF, start-to-finish (shorter form of the example) */
|
||||
$pdf = 'resources/document.pdf';
|
||||
try {
|
||||
$pages = EscposImage::loadPdf($pdf);
|
||||
$printer = new Escpos();
|
||||
foreach($pages as $page) {
|
||||
$printer -> graphics($page);
|
||||
}
|
||||
$printer -> cut();
|
||||
$printer -> close();
|
||||
} 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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
$printer = new Escpos();
|
||||
$pdf = 'resources/document.pdf';
|
||||
$pages = EscposImage::loadPdf($pdf, 260);
|
||||
foreach($pages as $page) {
|
||||
$printer -> graphics($page, Escpos::IMG_DOUBLE_HEIGHT | Escpos::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.
|
||||
*/
|
||||
$printer = new Escpos();
|
||||
$pdf = 'resources/document.pdf';
|
||||
$ser = 'resources/document.z';
|
||||
if(!file_exists($ser)) {
|
||||
$pages = EscposImage::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)));
|
||||
}
|
||||
81
htdocs/includes/escpos/example/qr-code.php
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
/* Demonstration of available options on the qrCode() command */
|
||||
require_once(dirname(__FILE__) . "/../Escpos.php");
|
||||
$printer = new Escpos();
|
||||
|
||||
// Most simple example
|
||||
title($printer, "QR code demo\n");
|
||||
$testStr = "Testing 123";
|
||||
$printer -> qrCode($testStr);
|
||||
$printer -> text("Most simple example\n");
|
||||
$printer -> feed();
|
||||
|
||||
// Demo that alignment is the same as text
|
||||
$printer -> setJustification(Escpos::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(
|
||||
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();
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
96
htdocs/includes/escpos/example/receipt-with-logo.php
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . "/../Escpos.php");
|
||||
|
||||
/* Information for the receipt */
|
||||
$items = array(
|
||||
new item("Example item #1", "4.00"),
|
||||
new item("Another thing", "3.50"),
|
||||
new item("Something else", "1.00"),
|
||||
new item("A final item", "4.45"),
|
||||
);
|
||||
$subtotal = new item('Subtotal', '12.95');
|
||||
$tax = new item('A local tax', '1.30');
|
||||
$total = new item('Total', '14.25', true);
|
||||
/* Date is kept the same for testing */
|
||||
// $date = date('l jS \of F Y h:i:s A');
|
||||
$date = "Monday 6th of April 2015 02:56:25 PM";
|
||||
|
||||
/* Start the printer */
|
||||
$logo = new EscposImage("resources/escpos-php.png");
|
||||
$printer = new Escpos();
|
||||
|
||||
/* Print top logo */
|
||||
$printer -> setJustification(Escpos::JUSTIFY_CENTER);
|
||||
$printer -> graphics($logo);
|
||||
|
||||
/* Name of shop */
|
||||
$printer -> selectPrintMode(Escpos::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(Escpos::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(Escpos::MODE_DOUBLE_WIDTH);
|
||||
$printer -> text($total);
|
||||
$printer -> selectPrintMode();
|
||||
|
||||
/* Footer */
|
||||
$printer -> feed(2);
|
||||
$printer -> setJustification(Escpos::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";
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
/* All strings from EscposPrintBufferTest are included below- These are fully supported
|
||||
* 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"
|
||||
);
|
||||
|
||||
/*
|
||||
* 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"
|
||||
);
|
||||
|
||||
BIN
htdocs/includes/escpos/example/resources/document.odt
Normal file
BIN
htdocs/includes/escpos/example/resources/document.pdf
Normal file
BIN
htdocs/includes/escpos/example/resources/document.z
Normal file
BIN
htdocs/includes/escpos/example/resources/escpos-php-small.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
htdocs/includes/escpos/example/resources/escpos-php.png
Normal file
|
After Width: | Height: | Size: 7.7 KiB |
BIN
htdocs/includes/escpos/example/resources/tux.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
|
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
/* This example shows the printing of Latvian text on the Star TUP 592 printer */
|
||||
$profile = StarCapabilityProfile::getInstance();
|
||||
|
||||
/* Option 1: Native character encoding */
|
||||
$connector = new FilePrintConnector("php://stdout");
|
||||
$printer = new Escpos($connector, $profile);
|
||||
$printer -> 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 Escpos($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();
|
||||
?>
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
/*
|
||||
* This example shows how tok send a custom command to the printer-
|
||||
* The use case here is an Epson TM-T20II and German text.
|
||||
*
|
||||
* Background: Not all ESC/POS features are available in the driver, so sometimes
|
||||
* you might want to send a custom commnad. This is useful for testing
|
||||
* new features.
|
||||
*
|
||||
* The Escpos::text() function removes non-printable characters as a precaution,
|
||||
* so that commands cannot be injected into user input. To send raw data to
|
||||
* the printer, you need to write bytes to the underlying PrintConnector.
|
||||
*
|
||||
* If you get a new command working, please file an issue on GitHub with a code
|
||||
* snippet so that it can be incorporated into escpos-php.
|
||||
*/
|
||||
|
||||
/* Set up profile & connector */
|
||||
$connector = new FilePrintConnector("php://output");
|
||||
$profile = DefaultCapabilityProfile::getInstance(); // Works for Epson printers
|
||||
|
||||
$printer = new Escpos($connector, $profile);
|
||||
$cmd = Escpos::ESC . "V" . chr(1); // Try out 90-degree rotation.
|
||||
$printer -> 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
|
||||
*/
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/*
|
||||
* Example of printing Spanish text on SEYPOS PRP-300 thermal line printer.
|
||||
* The characters in Spanish are available in code page 437, so no special
|
||||
* code pages are needed in this case (SimpleCapabilityProfile).
|
||||
*
|
||||
* Use the hardware switch to activate "Two-byte Character Code"
|
||||
*/
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
$connector = new FilePrintConnector("php://output");
|
||||
$profile = SimpleCapabilityProfile::getInstance();
|
||||
$printer = new Escpos($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();
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
$profile = DefaultCapabilityProfile::getInstance();
|
||||
// This is a quick demo of currency symbol issues in #39.
|
||||
|
||||
/* Option 1: Native ESC/POS characters, depends on printer and is buggy. */
|
||||
$connector = new FilePrintConnector("php://stdout");
|
||||
$printer = new Escpos($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();
|
||||
|
||||
/* 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 -> 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 SimpleCapabilityProfile {
|
||||
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 Escpos($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();
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
/* Example of printing the GBP pound symbol on a STAR TSP650
|
||||
*
|
||||
* In this example, it's shown how to check that your PHP files are actually being
|
||||
* saved in unicode. Sections B) and C) are identical in UTF-8, but different
|
||||
* if you are saving to a retro format like Windows-1252.
|
||||
*/
|
||||
|
||||
// Adjust these to your environment
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
$connector = new FilePrintConnector("php://stdout");
|
||||
|
||||
// Start printer
|
||||
$profile = SimpleCapabilityProfile::getInstance();
|
||||
$printer = new Escpos($connector, $profile);
|
||||
|
||||
// A) Raw pound symbol
|
||||
// This is the most likely thing to work, and bypasses all the fancy stuff.
|
||||
$printer -> 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();
|
||||
16
htdocs/includes/escpos/example/specific/50-P-822D-greek.php
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
/* Example of Greek text on the P-822D */
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
|
||||
// Setup the printer
|
||||
$connector = new FilePrintConnector("php://stdout");
|
||||
$profile = P822DCapabilityProfile::getInstance();
|
||||
$printer = new Escpos($connector, $profile);
|
||||
|
||||
// Print a Greek pangram
|
||||
$text = "Ξεσκεπάζω την ψυχοφθόρα βδελυγμία";
|
||||
$printer -> text($text . "\n");
|
||||
$printer -> cut();
|
||||
|
||||
// Close the connection
|
||||
$printer -> close();
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
/*
|
||||
* This example shows Arabic image-based output on the EPOS TEP 220m.
|
||||
*
|
||||
* Because escpos-php is not yet able to render Arabic correctly
|
||||
* on thermal line printers, small images are generated and sent
|
||||
* instead. This is a bit slower, and only limited formatting
|
||||
* is currently available in this mode.
|
||||
*
|
||||
* 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:
|
||||
*/
|
||||
require_once(dirname(__FILE__) . "/../../Escpos.php");
|
||||
require_once(dirname(__FILE__) . "/../../vendor/I18N/Arabic.php");
|
||||
|
||||
/*
|
||||
* First, convert the text into LTR byte order with joined letters,
|
||||
* Using the Ar-PHP library.
|
||||
*
|
||||
* The Ar-PHP library uses the default internal encoding, and can print
|
||||
* a lot of errors depending on the input, so be prepared to debug
|
||||
* the next four lines.
|
||||
*
|
||||
* Note that this output shows that numerals are converted to placeholder
|
||||
* characters, indicating that western numerals (123) have to be used instead.
|
||||
*/
|
||||
mb_internal_encoding("UTF-8");
|
||||
$Arabic = new I18N_Arabic('Glyphs');
|
||||
$text = "صِف خَلقَ خَودِ كَمِثلِ الشَمسِ إِذ بَزَغَت — يَحظى الضَجيعُ بِها نَجلاءَ مِعطارِ";
|
||||
$text = $Arabic -> utf8Glyphs($text);
|
||||
|
||||
/*
|
||||
* Set up and use the printer
|
||||
*/
|
||||
$buffer = new ImagePrintBuffer();
|
||||
$profile = EposTepCapabilityProfile::getInstance();
|
||||
$connector = new FilePrintConnector("php://output");
|
||||
// = WindowsPrintConnector("LPT2");
|
||||
// Windows LPT2 was used in the bug tracker
|
||||
|
||||
$printer = new Escpos($connector, $profile);
|
||||
$printer -> setPrintBuffer($buffer);
|
||||
$printer -> text($text . "\n");
|
||||
$printer -> close();
|
||||
7
htdocs/includes/escpos/example/specific/README.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
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.
|
||||
62
htdocs/includes/escpos/example/text-size.php
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
/**
|
||||
* This print-out shows how large the available font sizes are. It is included
|
||||
* separately due to the amount of text it prints.
|
||||
*
|
||||
* @author Michael Billington <michael.billington@gmail.com>
|
||||
*/
|
||||
require_once(dirname(__FILE__) . "/../Escpos.php");
|
||||
$printer = new Escpos();
|
||||
|
||||
/* 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(Escpos $printer, $text) {
|
||||
$printer -> selectPrintMode(Escpos::MODE_EMPHASIZED);
|
||||
$printer -> text("\n" . $text);
|
||||
$printer -> selectPrintMode(); // Reset
|
||||
}
|
||||
|
||||
?>
|
||||
61
htdocs/includes/escpos/src/AbstractCapabilityProfile.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<?php
|
||||
/**
|
||||
* Not all printers support the same subset of available Esc/POS commands. Profiles allow you to specify
|
||||
* which features are available on your printer, so that Escpos is less likely to send unsupported commands.
|
||||
*/
|
||||
abstract class AbstractCapabilityProfile {
|
||||
/**
|
||||
* Sub-classes must be retrieved via getInstance(), so that validation
|
||||
* can be attached to guarantee that dud profiles are not used on an Escpos object.
|
||||
*/
|
||||
protected final function __construct() {
|
||||
// This space intentionally left blank.
|
||||
}
|
||||
|
||||
/**
|
||||
* If getSupportedCodePages contains custom code pages, their character maps must be provided here.
|
||||
*/
|
||||
abstract function getCustomCodePages();
|
||||
|
||||
/**
|
||||
* Return a map of code page numbers to names for this printer. Names
|
||||
* should match iconv code page names where possible (non-matching names will not be used).
|
||||
*/
|
||||
abstract function getSupportedCodePages();
|
||||
|
||||
/**
|
||||
* True to support barcode "function b", false to use only function A.
|
||||
*/
|
||||
abstract function getSupportsBarcodeB();
|
||||
|
||||
/**
|
||||
* True for bitImage support, false for no bitImage support.
|
||||
*/
|
||||
abstract function getSupportsBitImage();
|
||||
|
||||
/**
|
||||
* True for graphics support, false for no graphics support.
|
||||
*/
|
||||
abstract function getSupportsGraphics();
|
||||
|
||||
/**
|
||||
* True for 'STAR original' commands, false for standard ESC/POS only.
|
||||
*/
|
||||
abstract function getSupportsStarCommands();
|
||||
|
||||
/**
|
||||
* True if the printer renders its own QR codes, false to send an image.
|
||||
*/
|
||||
abstract function getSupportsQrCode();
|
||||
|
||||
/**
|
||||
* @return AbstractCapabilityProfile Instance of sub-class.
|
||||
*/
|
||||
public static final function getInstance() {
|
||||
static $profile = null;
|
||||
if ($profile === null) {
|
||||
$profile = new static();
|
||||
}
|
||||
return $profile;
|
||||
}
|
||||
}
|
||||
181
htdocs/includes/escpos/src/CodePage.php
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
abstract class CodePage {
|
||||
/** Code page constants, exported from iconv -l. Can be cut down*/
|
||||
const CP037 = "CP037";
|
||||
const CP038 = "CP038";
|
||||
const CP273 = "CP273";
|
||||
const CP274 = "CP274";
|
||||
const CP275 = "CP275";
|
||||
const CP278 = "CP278";
|
||||
const CP280 = "CP280";
|
||||
const CP281 = "CP281";
|
||||
const CP282 = "CP282";
|
||||
const CP284 = "CP284";
|
||||
const CP285 = "CP285";
|
||||
const CP290 = "CP290";
|
||||
const CP297 = "CP297";
|
||||
const CP367 = "CP367";
|
||||
const CP420 = "CP420";
|
||||
const CP423 = "CP423";
|
||||
const CP424 = "CP424";
|
||||
const CP437 = "CP437";
|
||||
const CP500 = "CP500";
|
||||
const CP737 = "CP737";
|
||||
const CP770 = "CP770";
|
||||
const CP771 = "CP771";
|
||||
const CP772 = "CP772";
|
||||
const CP773 = "CP773";
|
||||
const CP774 = "CP774";
|
||||
const CP775 = "CP775";
|
||||
const CP803 = "CP803";
|
||||
const CP813 = "CP813";
|
||||
const CP819 = "CP819";
|
||||
const CP850 = "CP850";
|
||||
const CP851 = "CP851";
|
||||
const CP852 = "CP852";
|
||||
const CP855 = "CP855";
|
||||
const CP856 = "CP856";
|
||||
const CP857 = "CP857";
|
||||
const CP860 = "CP860";
|
||||
const CP861 = "CP861";
|
||||
const CP862 = "CP862";
|
||||
const CP863 = "CP863";
|
||||
const CP864 = "CP864";
|
||||
const CP865 = "CP865";
|
||||
const CP866 = "CP866";
|
||||
const CP866NAV = "CP866NAV";
|
||||
const CP868 = "CP868";
|
||||
const CP869 = "CP869";
|
||||
const CP870 = "CP870";
|
||||
const CP871 = "CP871";
|
||||
const CP874 = "CP874";
|
||||
const CP875 = "CP875";
|
||||
const CP880 = "CP880";
|
||||
const CP891 = "CP891";
|
||||
const CP901 = "CP901";
|
||||
const CP902 = "CP902";
|
||||
const CP903 = "CP903";
|
||||
const CP904 = "CP904";
|
||||
const CP905 = "CP905";
|
||||
const CP912 = "CP912";
|
||||
const CP915 = "CP915";
|
||||
const CP916 = "CP916";
|
||||
const CP918 = "CP918";
|
||||
const CP920 = "CP920";
|
||||
const CP921 = "CP921";
|
||||
const CP922 = "CP922";
|
||||
const CP930 = "CP930";
|
||||
const CP932 = "CP932";//
|
||||
const CP933 = "CP933";
|
||||
const CP935 = "CP935";
|
||||
const CP936 = "CP936";
|
||||
const CP937 = "CP937";
|
||||
const CP939 = "CP939";
|
||||
const CP949 = "CP949";
|
||||
const CP950 = "CP950";
|
||||
const CP1004 = "CP1004";
|
||||
const CP1008 = "CP1008";
|
||||
const CP1025 = "CP1025";
|
||||
const CP1026 = "CP1026";
|
||||
const CP1046 = "CP1046";
|
||||
const CP1047 = "CP1047";
|
||||
const CP1070 = "CP1070";
|
||||
const CP1079 = "CP1079";
|
||||
const CP1081 = "CP1081";
|
||||
const CP1084 = "CP1084";
|
||||
const CP1089 = "CP1089";
|
||||
const CP1097 = "CP1097";
|
||||
const CP1112 = "CP1112";
|
||||
const CP1122 = "CP1122";
|
||||
const CP1123 = "CP1123";
|
||||
const CP1124 = "CP1124";
|
||||
const CP1125 = "CP1125";
|
||||
const CP1129 = "CP1129";
|
||||
const CP1130 = "CP1130";
|
||||
const CP1132 = "CP1132";
|
||||
const CP1133 = "CP1133";
|
||||
const CP1137 = "CP1137";
|
||||
const CP1140 = "CP1140";
|
||||
const CP1141 = "CP1141";
|
||||
const CP1142 = "CP1142";
|
||||
const CP1143 = "CP1143";
|
||||
const CP1144 = "CP1144";
|
||||
const CP1145 = "CP1145";
|
||||
const CP1146 = "CP1146";
|
||||
const CP1147 = "CP1147";
|
||||
const CP1148 = "CP1148";
|
||||
const CP1149 = "CP1149";
|
||||
const CP1153 = "CP1153";
|
||||
const CP1154 = "CP1154";
|
||||
const CP1155 = "CP1155";
|
||||
const CP1156 = "CP1156";
|
||||
const CP1157 = "CP1157";
|
||||
const CP1158 = "CP1158";
|
||||
const CP1160 = "CP1160";
|
||||
const CP1161 = "CP1161";
|
||||
const CP1162 = "CP1162";
|
||||
const CP1163 = "CP1163";
|
||||
const CP1164 = "CP1164";
|
||||
const CP1166 = "CP1166";
|
||||
const CP1167 = "CP1167";
|
||||
const CP1250 = "CP1250";
|
||||
const CP1251 = "CP1251";
|
||||
const CP1252 = "CP1252";
|
||||
const CP1253 = "CP1253";
|
||||
const CP1254 = "CP1254";
|
||||
const CP1255 = "CP1255";
|
||||
const CP1256 = "CP1256";
|
||||
const CP1257 = "CP1257";
|
||||
const CP1258 = "CP1258";
|
||||
const CP1282 = "CP1282";
|
||||
const CP1361 = "CP1361";
|
||||
const CP1364 = "CP1364";
|
||||
const CP1371 = "CP1371";
|
||||
const CP1388 = "CP1388";
|
||||
const CP1390 = "CP1390";
|
||||
const CP1399 = "CP1399";
|
||||
const CP4517 = "CP4517";
|
||||
const CP4899 = "CP4899";
|
||||
const CP4909 = "CP4909";
|
||||
const CP4971 = "CP4971";
|
||||
const CP5347 = "CP5347";
|
||||
const CP9030 = "CP9030";
|
||||
const CP9066 = "CP9066";
|
||||
const CP9448 = "CP9448";
|
||||
const CP10007 = "CP10007";
|
||||
const CP12712 = "CP12712";
|
||||
const CP16804 = "CP16804";
|
||||
const ISO8859_7 = "ISO_8859-7";
|
||||
const ISO8859_2 = "ISO_8859-2";
|
||||
const ISO8859_15 = "ISO_8859-15";
|
||||
const RK1048 = "RK1048";
|
||||
// Code pages which are not built in
|
||||
// to default iconv on Debian.
|
||||
const CP720 = false;
|
||||
const CP853 = false;
|
||||
const CP858 = false;
|
||||
const CP928 = false;
|
||||
const CP1098 = false;
|
||||
const CP747 = false;
|
||||
|
||||
/*
|
||||
* Below code pages appear to be vendor-specific (Star), so iconv wont use them
|
||||
* They are being merged gradually into the StarCapabilityProfile.
|
||||
*/
|
||||
const CP3840 = false;
|
||||
const CP3841 = false;
|
||||
const CP3843 = false;
|
||||
const CP3844 = false;
|
||||
const CP3845 = false;
|
||||
const CP3847 = false;
|
||||
const CP3846 = false;
|
||||
const CP3848 = false;
|
||||
const CP1001 = false;
|
||||
const CP2001 = false;
|
||||
const CP3001 = false;
|
||||
const CP3002 = false;
|
||||
const CP3011 = false;
|
||||
const CP3012 = false;
|
||||
const CP3021 = false;
|
||||
const CP3041 = false;
|
||||
}
|
||||
103
htdocs/includes/escpos/src/DefaultCapabilityProfile.php
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<?php
|
||||
/**
|
||||
* This capability profile matches many recent Epson-branded thermal receipt printers.
|
||||
*
|
||||
* For non-Epson printers, try the SimpleCapabilityProfile.
|
||||
*/
|
||||
class DefaultCapabilityProfile extends AbstractCapabilityProfile {
|
||||
function getCustomCodePages() {
|
||||
return array();
|
||||
}
|
||||
|
||||
function getSupportedCodePages() {
|
||||
/* Character code tables which the printer understands, mapping to known encoding standards we may be able to encode to.
|
||||
*
|
||||
* See CodePage.php for the mapping of these standards to encoding names for use in the backing library.
|
||||
*
|
||||
* Any entry with 'false' means I haven't compared the print-out of the code page to a table.
|
||||
*/
|
||||
return array(
|
||||
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;
|
||||
}
|
||||
}
|
||||
78
htdocs/includes/escpos/src/DummyPrintConnector.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
4
htdocs/includes/escpos/src/EposTepCapabilityProfile.php
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
class EposTepCapabilityProfile extends DefaultCapabilityProfile {
|
||||
// TODO override list of code pages
|
||||
}
|
||||
405
htdocs/includes/escpos/src/EscposImage.php
Normal file
|
|
@ -0,0 +1,405 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
304
htdocs/includes/escpos/src/EscposPrintBuffer.php
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
80
htdocs/includes/escpos/src/FilePrintConnector.php
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
99
htdocs/includes/escpos/src/ImagePrintBuffer.php
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
39
htdocs/includes/escpos/src/NetworkPrintConnector.php
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
90
htdocs/includes/escpos/src/P822DCapabilityProfile.php
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
/**
|
||||
* This capability profile is designed for the P-822D.
|
||||
*
|
||||
* See
|
||||
* https://github.com/mike42/escpos-php/issues/50
|
||||
*/
|
||||
class P822DCapabilityProfile extends DefaultCapabilityProfile {
|
||||
function getSupportedCodePages() {
|
||||
return array(
|
||||
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;
|
||||
}
|
||||
}
|
||||
75
htdocs/includes/escpos/src/PrintBuffer.php
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
?>
|
||||
56
htdocs/includes/escpos/src/PrintConnector.php
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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);
|
||||
}
|
||||
17
htdocs/includes/escpos/src/SimpleCapabilityProfile.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* This capability profile is designed for non-Epson printers sold online. Without knowing
|
||||
* their character encoding table, only CP437 output is assumed, and graphics() calls will
|
||||
* be disabled, as it usually prints junk on these models.
|
||||
*/
|
||||
class SimpleCapabilityProfile extends DefaultCapabilityProfile {
|
||||
function getSupportedCodePages() {
|
||||
/* Use only CP437 output */
|
||||
return array(0 => CodePage::CP437);
|
||||
}
|
||||
|
||||
public function getSupportsGraphics() {
|
||||
/* Ask the driver to use bitImage wherever possible instead of graphics */
|
||||
return false;
|
||||
}
|
||||
}
|
||||
82
htdocs/includes/escpos/src/StarCapabilityProfile.php
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
class StarCapabilityProfile extends DefaultCapabilityProfile {
|
||||
function getCustomCodePages() {
|
||||
// Code table reference: http://www.starmicronics.com/support/mannualfolder/sp2000pm.pdf
|
||||
return array(
|
||||
'CP3011' => "ÇüéâäàåçêëèïîìÄÅ" .
|
||||
"ÉæÆôöòûùÿÖÜ¢£¥₧ƒ" .
|
||||
"áíóúñѪº¿⌐¬½¼¡«»" .
|
||||
"░▒▓│┤Ā╢ņ╕╣║╗╝╜╛┐" .
|
||||
"└┴┬├─┼ā╟╚╔╩╦╠═╬╧" .
|
||||
"Š╤čČ╘╒ģĪī┘┌█▄ūŪ▀" .
|
||||
"αßΓπΣσµτΦΘΩδ∞φε∩" .
|
||||
"ĒēĢķĶļĻžŽ∙·√Ņš■ ",
|
||||
'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;
|
||||
}
|
||||
}
|
||||
356
htdocs/includes/escpos/src/WindowsPrintConnector.php
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
<?php
|
||||
/**
|
||||
* escpos-php, a Thermal receipt printer library, for use with
|
||||
* ESC/POS compatible printers.
|
||||
*
|
||||
* Copyright (c) 2014-2015 Michael Billington <michael.billington@gmail.com>,
|
||||
* incorporating modifications by:
|
||||
* - Roni Saha <roni.cse@gmail.com>
|
||||
* - Gergely Radics <gerifield@ustream.tv>
|
||||
* - Warren Doyle <w.doyle@fuelled.co>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
BIN
htdocs/includes/escpos/src/cache/Characters-DefaultCapabilityProfile.ser.gz
vendored
Normal file
BIN
htdocs/includes/escpos/src/cache/Characters-SimpleCapabilityProfile.ser.gz
vendored
Normal file
BIN
htdocs/includes/escpos/src/cache/Characters-StarCapabilityProfile.ser.gz
vendored
Normal file
27
htdocs/includes/escpos/test/bootstrap.php
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
error_reporting(E_ALL);
|
||||
ini_set('display_errors', 1);
|
||||
|
||||
require_once(dirname(__FILE__) . "/../vendor/autoload.php");
|
||||
require_once(dirname(__FILE__) . "/../Escpos.php");
|
||||
require_once(dirname(__FILE__) . "/../src/DummyPrintConnector.php");
|
||||
|
||||
/**
|
||||
* Used in many of the tests to to output known-correct
|
||||
* strings for use in tests.
|
||||
*/
|
||||
function friendlyBinary($in) {
|
||||
if(strlen($in) == 0) {
|
||||
return $in;
|
||||
}
|
||||
/* Print out binary data with PHP \x00 escape codes,
|
||||
for builting test cases. */
|
||||
$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);
|
||||
}
|
||||
126
htdocs/includes/escpos/test/integration/ExampleTest.php
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
<?php
|
||||
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/";
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
}
|
||||
|
||||
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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
@Hello World!
|
||||
VA
|
||||
16
htdocs/includes/escpos/test/phpunit.xml
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<phpunit bootstrap="bootstrap.php"
|
||||
timeoutForSmallTests="1"
|
||||
timeoutForMediumTests="10"
|
||||
timeoutForLargeTests="60"
|
||||
verbose="true"
|
||||
strict="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="unit">
|
||||
<directory>unit</directory>
|
||||
</testsuite>
|
||||
<testsuite name="integration">
|
||||
<directory>integration</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<?php
|
||||
/**
|
||||
* Test that all sub-classes of AbstractCapabilityProfile
|
||||
* are creating data in the right format.
|
||||
*/
|
||||
class EscposCapabilityProfileTest extends PHPUnit_Framework_TestCase {
|
||||
private $profiles;
|
||||
private $checklist;
|
||||
|
||||
function setup() {
|
||||
$this -> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
235
htdocs/includes/escpos/test/unit/EscposImageTest.php
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
<?php
|
||||
class EscposImageTest extends PHPUnit_Framework_TestCase {
|
||||
/**
|
||||
* Checking loading of an empty image - requires no libraries
|
||||
*/
|
||||
public function testNoLibrariesBlank() {
|
||||
$this -> loadAndCheckImg(null, false, false, 0, 0, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
150
htdocs/includes/escpos/test/unit/EscposPrintBufferTest.php
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
<?php
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
protected function tearDown() {
|
||||
$this -> outputConnector -> finalize();
|
||||
}
|
||||
|
||||
public function testRawTextNonprintable() {
|
||||
$this -> buffer -> writeTextRaw("Test" . Escpos::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\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 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();
|
||||
}
|
||||
}
|
||||
|
||||
765
htdocs/includes/escpos/test/unit/EscposTest.php
Normal file
|
|
@ -0,0 +1,765 @@
|
|||
<?php
|
||||
class EscposTest extends PHPUnit_Framework_TestCase {
|
||||
protected $printer;
|
||||
protected $outputConnector;
|
||||
|
||||
protected function setup() {
|
||||
/* Print to nowhere- for testing which inputs are accepted */
|
||||
$this -> outputConnector = new DummyPrintConnector();
|
||||
$this -> printer = new Escpos($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 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(Escpos::UNDERLINE_NONE);
|
||||
$this -> checkOutput("\x1b@\x1b-\x00");
|
||||
}
|
||||
|
||||
public function testSetUnderlineOn() {
|
||||
$this -> printer -> setUnderline(Escpos::UNDERLINE_SINGLE);
|
||||
$this -> checkOutput("\x1b@\x1b-\x01");
|
||||
}
|
||||
|
||||
public function testSetUnderlineDbl() {
|
||||
$this -> printer -> setUnderline(Escpos::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(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<x");
|
||||
}
|
||||
|
||||
function testPulse1() {
|
||||
$this -> printer -> pulse(1);
|
||||
$this -> checkOutput("\x1b@\x1bp1<x");
|
||||
}
|
||||
|
||||
function testPulseEvenMs() {
|
||||
$this -> 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 = new EscposImage(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 = 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");
|
||||
}
|
||||
|
||||
/* 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");
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
?>
|
||||
252
htdocs/includes/escpos/test/unit/WindowsPrintConnectorTest.php
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
<?php
|
||||
class WindowsPrintConnectorTest extends PHPUnit_Framework_TestCase {
|
||||
private $connector;
|
||||
|
||||
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 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'));
|
||||
$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'));
|
||||
$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 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();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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");
|
||||
$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'.");
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
htdocs/includes/escpos/test/unit/resources/black_transparent.gif
Normal file
|
After Width: | Height: | Size: 65 B |
BIN
htdocs/includes/escpos/test/unit/resources/black_transparent.png
Normal file
|
After Width: | Height: | Size: 167 B |
BIN
htdocs/includes/escpos/test/unit/resources/black_white.bmp
Normal file
|
After Width: | Height: | Size: 138 B |
BIN
htdocs/includes/escpos/test/unit/resources/black_white.gif
Normal file
|
After Width: | Height: | Size: 65 B |
BIN
htdocs/includes/escpos/test/unit/resources/black_white.jpg
Normal file
|
After Width: | Height: | Size: 175 B |
BIN
htdocs/includes/escpos/test/unit/resources/black_white.png
Normal file
|
After Width: | Height: | Size: 156 B |
BIN
htdocs/includes/escpos/test/unit/resources/canvas_black.bmp
Normal file
|
After Width: | Height: | Size: 142 B |
BIN
htdocs/includes/escpos/test/unit/resources/canvas_black.gif
Normal file
|
After Width: | Height: | Size: 72 B |
BIN
htdocs/includes/escpos/test/unit/resources/canvas_black.jpg
Normal file
|
After Width: | Height: | Size: 160 B |
BIN
htdocs/includes/escpos/test/unit/resources/canvas_black.png
Normal file
|
After Width: | Height: | Size: 239 B |
BIN
htdocs/includes/escpos/test/unit/resources/canvas_white.bmp
Normal file
|
After Width: | Height: | Size: 142 B |
BIN
htdocs/includes/escpos/test/unit/resources/canvas_white.gif
Normal file
|
After Width: | Height: | Size: 72 B |
BIN
htdocs/includes/escpos/test/unit/resources/canvas_white.jpg
Normal file
|
After Width: | Height: | Size: 160 B |
BIN
htdocs/includes/escpos/test/unit/resources/canvas_white.png
Normal file
|
After Width: | Height: | Size: 239 B |