nacholibre/coffee-cups

A simple PHP library for CUPS IPP (Internet Printing Protocol) communication

Installs: 64

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/nacholibre/coffee-cups

v0.1.0 2025-11-27 09:58 UTC

This package is auto-updated.

Last update: 2025-11-27 10:12:58 UTC


README

A simple, modern PHP library for CUPS IPP (Internet Printing Protocol) communication with zero dependencies.

CI GitHub PHP Version License: MIT No Dependencies

Features

  • 🖨️ Print documents to CUPS printers using IPP protocol
  • 📋 Query printer status and capabilities
  • 📄 Manage print jobs (cancel, hold, release)
  • 🎯 Simple, fluent API for job configuration
  • 🔐 Basic and digest authentication support
  • 📦 Zero dependencies — only uses PHP's built-in cURL extension

Requirements

  • PHP 8.1 or higher
  • cURL extension
  • CUPS server

Installation

composer require nacholibre/coffee-cups

Quick Start

Print a File

use CoffeeCups\CupsClient;
use CoffeeCups\Job;

// Create a client (defaults to localhost:631)
$client = new CupsClient();

// Create and configure a print job
$job = new Job('My Document');
$job->setFile('/path/to/document.pdf')
    ->setCopies(2)
    ->setDuplex(true)
    ->setColor(true);

// Send to printer
$result = $client->print('HP_LaserJet', $job);

if ($result->isSuccessful()) {
    echo "Job ID: " . $result->getJobId();
}

Print Raw Content

use CoffeeCups\CupsClient;
use CoffeeCups\Job;

$client = new CupsClient();

$job = new Job('Receipt');
$job->setContent("Hello, World!\n\nThis is a test print.")
    ->setFormat('text/plain');

$result = $client->print('Receipt_Printer', $job);

Job Configuration

The Job class provides a fluent API for configuring print jobs:

Creating a Job

// With name
$job = new Job('My Document');

// Without name (set later)
$job = new Job();
$job->setName('My Document');

Document Source

// From file (auto-detects format from extension)
$job->setFile('/path/to/document.pdf');

// From raw content
$job->setContent($pdfContent);

Document Format

$job->setFormat('application/pdf');      // PDF
$job->setFormat('application/postscript'); // PostScript
$job->setFormat('text/plain');           // Plain text
$job->setFormat('image/png');            // PNG image

Copies

$job->setCopies(3);

Duplex (Two-Sided Printing)

$job->setDuplex(true);          // Two-sided, flip on long edge
$job->setDuplex(true, false);   // Two-sided, flip on short edge
$job->setDuplex(false);         // Single-sided

Orientation

$job->setOrientation('portrait');
$job->setOrientation('landscape');
$job->setOrientation('reverse-portrait');
$job->setOrientation('reverse-landscape');

Print Quality

$job->setQuality('draft');    // Draft quality
$job->setQuality('normal');   // Normal quality
$job->setQuality('high');     // High quality

Paper Size

// Common shortcuts
$job->setMediaSize('a4');      // A4 paper
$job->setMediaSize('letter');  // US Letter
$job->setMediaSize('legal');   // US Legal
$job->setMediaSize('a3');      // A3 paper

// Full IPP media size names also work
$job->setMediaSize('iso_a4_210x297mm');
$job->setMediaSize('na_letter_8.5x11in');

Media Type

$job->setMediaType('stationery');
$job->setMediaType('transparency');
$job->setMediaType('envelope');

Color Mode

$job->setColor(true);   // Color printing
$job->setColor(false);  // Monochrome/grayscale

Job Priority

$job->setPriority(75);  // 1-100, higher is more urgent

Hold Job

$job->setHold(true);   // Hold the job for later release
$job->setHold(false);  // Don't hold (default)

Custom Attributes

use CoffeeCups\Ipp\IppAttribute;

$job->addAttribute(IppAttribute::keyword('finishings', 'staple'));
$job->addAttribute(IppAttribute::integer('number-up', 4));

CupsClient API

Connecting to CUPS

use CoffeeCups\CupsClient;

// Local CUPS server
$client = new CupsClient();

// Remote server
$client = new CupsClient(
    host: 'print-server.local',
    port: 631,
    secure: false
);

// With authentication
$client = new CupsClient(
    host: 'print-server.local',
    username: 'admin',
    password: 'secret'
);

Printing

$result = $client->print('Printer_Name', $job);

if ($result->isSuccessful()) {
    echo "Job ID: " . $result->getJobId();
    echo "Job URI: " . $result->getJobUri();
} else {
    echo "Error: " . $result->getMessage();
}

Printer Operations

// Get all printers
$printers = $client->getPrinters();

// Get specific printer
$printer = $client->getPrinter('HP_LaserJet');

echo $printer->name;
echo $printer->state;  // 'idle', 'processing', 'stopped'
echo $printer->isAcceptingJobs;

// Check capabilities
if ($printer->supportsColor()) {
    echo "Color printing supported";
}

if ($printer->supportsDuplex()) {
    echo "Duplex printing supported";
}

// Get default printer
$default = $client->getDefaultPrinter();

Job Management

// Get jobs for a printer
$jobs = $client->getJobs('HP_LaserJet');

// Get only my jobs
$myJobs = $client->getJobs('HP_LaserJet', myJobs: true);

// Get completed jobs
$completed = $client->getJobs('HP_LaserJet', whichJobs: 'completed');

// Cancel a job
$client->cancelJob('HP_LaserJet', $jobId);

// Hold a job
$client->holdJob('HP_LaserJet', $jobId);

// Release a held job
$client->releaseJob('HP_LaserJet', $jobId);

Printer Control

// Pause printer
$client->pausePrinter('HP_LaserJet');

// Resume printer
$client->resumePrinter('HP_LaserJet');

Error Handling

use CoffeeCups\CupsClient;
use CoffeeCups\Job;
use CoffeeCups\Exceptions\ConnectionException;
use CoffeeCups\Exceptions\IppException;

try {
    $client = new CupsClient();
    
    $job = new Job('Test');
    $job->setFile('/path/to/file.pdf');
    
    $result = $client->print('Printer_Name', $job);
    
    if (!$result->isSuccessful()) {
        echo "Print failed: " . $result->getMessage();
    }
} catch (ConnectionException $e) {
    echo "Connection failed: {$e->getMessage()}";
} catch (IppException $e) {
    echo "IPP error ({$e->getStatusCode()}): {$e->getMessage()}";
}

Printer URI Format

CUPS uses URIs to identify printers:

  • ipp://localhost:631/printers/Printer_Name - IPP protocol
  • ipps://localhost:631/printers/Printer_Name - IPP over TLS

The library handles URI construction automatically when you provide a printer name.

Testing

Unit Tests

Run unit tests (no external dependencies required):

composer install
./vendor/bin/phpunit --testsuite unit

Integration Tests

Integration tests run against a real CUPS server via Docker:

# Start CUPS server and run integration tests
make test-integration

# Or run everything via Docker
make test-all

You can also start the CUPS server manually:

# Start CUPS server (available at localhost:6631)
make cups-up

# Run integration tests
CUPS_HOST=localhost CUPS_PORT=6631 ./vendor/bin/phpunit --testsuite integration --group integration

# Stop CUPS server
make cups-down

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request