This sample shows a PHP implementation of Ethernet POS Cloud connection. In this mode, print jobs are rendered and stored on the web server. Through a special page request, those print jobs are downloaded by Ethernet POS and transmitted to the printer.
This sample contains three important files:
To test this code, you must copy the 3 .php files on a web server, in the same folder. Then, in the Ethernet POS configuration tool, enable the HTTP(S) polling feature, and enter the URL corresponding to the server.php file. Finally, to test this Cloud printing feature, open a web browser, and enter the URL corresponding to the client.php file.
<?php // This file implements a printer virtual queue. It exposes an object that // allows to either append a printing job, or retreive and flush the whole jobs // queue. To simplify security setup for this sample, queue persistance is done // in a temporary file. class PrintQueue { private $name; private $file; private $lock; private $last_error; public function __construct($name = "default") { $this->name = $name; $this->file = false; $this->last_error = ''; } public function open() { if ($this->file !== false) return true; $path = sprintf("%s/ethpos_%s.queue", sys_get_temp_dir(), $this->name); // File must be opened read/write. $file = @fopen($path, 'a+'); if ($file === false) { $this->fillLastError(); return false; } // And we serialize its access through an exclusive lock. if (!@flock($file, LOCK_EX)) { $this->fillLastError(); return false; } $this->file = $file; return true; } public function close() { if ($this->file !== false) { flock($this->file, LOCK_UN); fclose($this->file); $this->file = false; } } public function write($data) { if (@fwrite($this->file, $data) === false) { $this->fillLastError(); return false; } return true; } public function read() { $data = ''; if (@fseek($this->file, 0) < 0) { $this->fillLastError(); return false; } for (;;) { // Read by chunck of 4 KB. $r = @fread($this->file, 4096); if ($r === false) { $this->fillLastError(); return false; } // Stop if there is no more data to read. if (strlen($r) == 0) break; $data .= $r; } return $data; } public function truncate() { if (!@ftruncate($this->file, 0)) { $this->fillLastError(); return false; } return true; } public function lastError() { return $this->last_error; } private function fillLastError() { $err = error_get_last(); $err_msg = $err['message']; // Remove function prefix if any, to report just the error // message. $pos = strpos($err_msg, "): "); if ($pos !== false) $err_msg = substr($err_msg, $pos + 3); $this->last_error = $err_msg; } }
Download print_queue.php
<?php // This file implements a simple page that allows to add a print job to the // print queue, in response to a click to the Print button. include 'print_queue.php'; // Helper function function post($key, $default = '') { return isset($_POST[$key]) ? $_POST[$key] : $default; } // Initializations $def_text = "This is a PHP client/server Ethernet POS\nsample.\n\n" . "Regards\nThe Active+ Software Team"; $text = post('text', $def_text); $qrcode = post('qrcode') == 'yes'; $cut = post('cut', 'yes') == 'yes'; $error = ''; if (post('print') != '') { // Prepare data to print $url = "https://www.activeplus.com"; $data = "\x1b@"; // Align center $data .= "\x1ba\x01"; // Set bold $data .= "\x1bE\x01"; // Write header $data .= "Ethernet POS sample.\n$url\n\n"; // Align left $data .= "\x1ba\x00"; // Remove bold $data .= "\x1bE\x00"; if ($text != '') { // Add Raw text $data .= trim($text) . "\n\n"; } if ($qrcode) { // Align center $data .= "\x1ba\x01"; // Set QR code size 4 $data .= sprintf("\x1d(k\x03\x00\x31%c%c", 67, 4); // Set QR code data $len = strlen($url) + 3; $data .= sprintf("\x1d(k%c%c\x31%c\x30%s", $len & 0xff, $len >> 8, 80, $url); // Add QR code print command $data .= sprintf("\x1d(k\x03\x00\x31%c%c", 81, 48); $data .= "\n\n"; } if ($cut) { // Add paper cut command $data .= "\x1dV\x41\x03"; } $queue = new PrintQueue(); if (!$queue->open() || !$queue->write($data)) $error = $queue->lastError(); $queue->close(); } ?> <!doctype html> <html> <head> <meta charset="utf-8" /> <title>Ethernet POS sample of a PHP client/server implementation</title> </head> <body> <form action="<?= htmlspecialchars($_SERVER['REQUEST_URI']) ?>" method="post"> <h3>Ethernet POS sample of PHP client/server implementation</h3> <p> This page contains the client side implementation of this sample. Each click on Print button will generate a print job according to the following inputs. </p> <table> <tr> <td>Text to print:</td> <td> <textarea name="text" cols="43" rows="10"><?= htmlspecialchars($text) ?></textarea> </td> </tr> <tr> <td colspan="2"> <input type="checkbox" name="qrcode" value="yes"<? if ($qrcode) echo ' checked="checked"'; ?> /> Print a QR code </td> </tr> <tr> <td colspan="2"> <input type="checkbox" name="cut" value="yes"<? if ($cut) echo ' checked="checked"'; ?> /> Add a cut paper command </td> </tr> <tr> <td colspan="2"> <input type="submit" name="print" value="Print" /> </td> </tr> </table> </form> </body> </html>
Download client.php
<?php // This page just returns the whole contents of the print queue, or a server // error if something wrong occured. No security mechanism is provided for this // sample, but an authentication mechanism should be setup for a production // system. include 'print_queue.php'; $queue = new PrintQueue(); if (!$queue->open()) { header('HTTP/1.0 500 ' . $queue->lastError()); die(); } $data = $queue->read(); if ($data === false) { header('HTTP/1.0 500 ' . $queue->lastError()); die(); } // Ethernet POS requires application/octet-stream content type. header('Content-Type: application/octet-stream'); header('Content-Length: ' . strlen($data)); echo $data; // Once data has been sent, reset queue file contents. $queue->truncate(); // And cleanup. $queue->close(); ?>
Download server.php