From 414d7ace219f9f721294c99bdd30567e8121aa04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Preu=C3=9F?= Date: Sun, 5 Apr 2026 14:27:50 +0200 Subject: [PATCH] Enhance printer handling by merging existing ESC/POS printers with new configurations and adding support for ESC/POS job processing --- app/Commands/Autowire.php | 9 +++++++- app/Commands/Serve.php | 43 +++++++++++++++++++++++++++++++------ composer.json | 7 +++--- composer.lock | 45 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 92 insertions(+), 12 deletions(-) diff --git a/app/Commands/Autowire.php b/app/Commands/Autowire.php index 8a102fe..dd37858 100644 --- a/app/Commands/Autowire.php +++ b/app/Commands/Autowire.php @@ -64,6 +64,13 @@ class Autowire extends Command if ($response->successful()) { $newPrinters = $response->json('printers', []); + // Keep all escpos printers from the old config + $existingPrinters = $contig->get('printers', []); + $escposPrinters = array_filter($existingPrinters, function ($printer) { + return isset($printer['driver']) && strtolower($printer['driver']) === 'escpos'; + }); + // Merge escpos printers with new printers, allow duplicates + $allPrinters = array_merge($newPrinters, $escposPrinters); if (empty($newPrinters)) { $this->info('No new printers found to autowire.'); } else { @@ -73,7 +80,7 @@ class Autowire extends Command } $this->setConfig([ ...$contig->toArray(), - 'printers' => $newPrinters, + 'printers' => $allPrinters, ]); } else { throw new Exception('Failed to autowire printers: ' . $response->body()); diff --git a/app/Commands/Serve.php b/app/Commands/Serve.php index eba42e6..7a702c1 100644 --- a/app/Commands/Serve.php +++ b/app/Commands/Serve.php @@ -10,6 +10,8 @@ use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; use LaravelZero\Framework\Commands\Command; +use Nyra\EscPos\JobRunner; +use Nyra\EscPos\Printer; use Smalot\Cups\Builder\Builder; use Smalot\Cups\Manager\JobManager; use Smalot\Cups\Manager\PrinterManager; @@ -36,7 +38,7 @@ class Serve extends Command */ protected $description = 'Command description'; - private $counter = 0; + private int $counter = 0; /** * Execute the console command. @@ -108,7 +110,13 @@ class Serve extends Command foreach ($jobs as $job) { try { - $this->handleJob($config, $job); + /** @var array $printer */ + $printer = $config->getPrinters()->firstWhere('id', $job['printer_id']); + match ($printer['driver']) { + 'cups' => $this->handleCupsJob($config, $job, $printer), + 'escpos' => $this->handleEscposJob($config, $job, $printer), + default => $this->error(sprintf('Unsupported driver %s for job %s', $job['driver'], $job['id'])), + }; } catch (Throwable $e) { $this->error($e->getMessage()); } @@ -119,9 +127,8 @@ class Serve extends Command * @throws RequestException * @throws ConnectionException */ - private function handleJob(Config $config, array $job): void + private function handleCupsJob(Config $config, array $job, array $printer): void { - $printer = $config->getPrinters()->firstWhere('id', $job['printer_id']); [$username, $password] = $this->getConfig()->getPrinterCredentials($printer); if (!empty($job['data']['preview'])) { @@ -149,14 +156,14 @@ class Serve extends Command $jobManager = new JobManager($builder, $client, $responseParser); $content = file_get_contents($job['file_url']); - Storage::put($filename = sprintf('pdfs/%s.pdf', Str::random(16)), $content); + Storage::put($filename = sprintf('pdfs/%s.pdf', Str::random()), $content); $printerJob = new Job(); $printerJob->setName(sprintf('job-%s', $job['id'])); $printerJob->setCopies(1); $printerJob->setPageRanges('1'); $printerJob->addFile(Storage::path($filename)); - $printerJob->addAttribute('media', "Custom.{$pointWidth}x{$pointHeight}"); + $printerJob->addAttribute('media', "Custom.{$pointWidth}x$pointHeight"); $printerJob->addAttribute('fit-to-page', true); if (!$jobManager->send($printer, $printerJob)) { @@ -170,6 +177,30 @@ class Serve extends Command $this->info(sprintf('Job %s completed as %s', $job['id'], $printerJob->getId())); } + /** + * @throws RequestException + * @throws ConnectionException + */ + private function handleEscposJob(Config $config, array $job, array $printer): void + { + try { + $uri = parse_url($printer['uri']); + $host = $uri['host'] ?? 'localhost'; + $post = $uri['port'] ?? 9100; + $printer = (new Printer($host, $post, 48))->connect(); + + $runner = new JobRunner(); + $content = file_get_contents($job['file_url']); + $runner->run($printer, $content); + + $this->markCompleted($config, $job, 0); + $this->info(sprintf('ESC/POS job %s completed', $job['id'])); + } catch (Throwable $e) { + $this->markFailed($config, $job, 'Failed to print ESC/POS job: ' . $e->getMessage()); + $this->error(sprintf('Failed to print ESC/POS job %s: %s', $job['id'], $e->getMessage())); + } + } + /** * @throws RequestException * @throws ConnectionException diff --git a/composer.json b/composer.json index 6334ab1..ad10ff2 100644 --- a/composer.json +++ b/composer.json @@ -17,12 +17,13 @@ ], "require": { "php": "^8.2.0", + "ext-posix": "*", + "ghostzero/cups-ipp": "^1.0", "guzzlehttp/guzzle": "^7.8", "illuminate/http": "^11.5", "laravel-zero/framework": "^11.0.0", - "ghostzero/cups-ipp": "^1.0", - "symfony/yaml": "^7.1", - "ext-posix": "*" + "nyra/escpos": "^1.0", + "symfony/yaml": "^7.1" }, "require-dev": { "laravel/pint": "^1.15.2", diff --git a/composer.lock b/composer.lock index 955bf4f..d07a544 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "36c4d46c04feaba7c665341994dbc8cb", + "content-hash": "e9b2399bae4e78613e1d65e4756bc174", "packages": [ { "name": "brick/math", @@ -3127,6 +3127,46 @@ ], "time": "2024-09-09T07:06:30+00:00" }, + { + "name": "nyra/escpos", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/nyra-dev/escpos.git", + "reference": "97a01457cec80eb57e9d31662f3a94d35c2d0a94" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nyra-dev/escpos/zipball/97a01457cec80eb57e9d31662f3a94d35c2d0a94", + "reference": "97a01457cec80eb57e9d31662f3a94d35c2d0a94", + "shasum": "" + }, + "require": { + "php": "^8.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nyra\\EscPos\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "René Preuß", + "email": "rene@preuss.io" + } + ], + "description": "Print Drivers for ESC/POS", + "support": { + "issues": "https://github.com/nyra-dev/escpos/issues", + "source": "https://github.com/nyra-dev/escpos/tree/1.0.0" + }, + "time": "2026-04-05T12:22:00+00:00" + }, { "name": "php-http/client-common", "version": "2.7.2", @@ -8956,7 +8996,8 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^8.2.0" + "php": "^8.2.0", + "ext-posix": "*" }, "platform-dev": {}, "plugin-api-version": "2.6.0"