PHP PrintIPP usage

Introduction

PHP PrintIPP is a PHP5 class library. It is designed to easier usage of Internet Printing Protocol.

It makes easy simple actions like print and cancel a document, and not difficult complex tasks as print a text document on 2 pages per sheet, dual sided, with staples on center (provided your printer and print server does).

Basic usage

As we said, simple things are simple:

                <?php
                
                    require_once(PrintIPP.php);
                    
                    $ipp = new PrintIPP();
                    
                    $ipp->setHost("localhost");
                    $ipp->setPrinterURI("/printers/epson");
                    $ipp->setData("./testfiles/test-utf8.txt"); // Path to file.
                    $ipp->printJob();

                ?>
            

You can replace filename by a string.

                 <?php
                    
                    $ipp->setAuthentication("test","test"); // system username & password, need to be lpadmin
                    
                    $job = $ipp->last_job; // getting job uri
                    
                    $ipp->cancelJob($job); // cancelling job

                 ?>
            

A little more

Now, we making little more complex tasks:


                <?php
                /* printing an utf-8 file, two-sided, two pages per sheet */   

                    
                    require_once(PrintIPP.php);

                    $ipp = new PrintIPP();
                    $ipp->setHost("localhost");
                    $ipp->setPrinterURI("/printers/epson");
                    
                    $ipp->debug_level = 3; // Debugging very verbose
                    $ipp->setLog('/tmp/printipp','file',3); // logging very verbose
                    $ipp->setUserName("foo bar"); // setting user name for server
                    $ipp->setDocumentName("testfile with UTF-8 characters");
                    $ipp->setCharset('utf-8');

                    
                    $ipp->setAttribute('number-up',2);
                    $ipp->setSides(); //     by default:  2 = two-sided-long-edge
                                        //  other choices:  1 = one-sided
                                        //                  2CE = two-sided-short-edge
                    
                    $ipp->setData("./testfiles/test-utf8.txt");//Path to file.
                    printf(_("Job status: %s"), $ipp->printJob()); // Print job, display job status

                    $ipp->printDebug(); // display debugging output
                
                ?>
                
            

                <?php
                /* printing selected pages from document */   

                    
                    $ipp->setDocumentName("Selected parts of GNU FDL");
                    
                    $ipp->setAttribute('number-up',4); // 4 pages per sheet
                    $ipp->setAttribute('media','A7'); // very little pages
                    $ipp->setPageRanges('1:2 5:6'); // print only pages 1 to 2 and 5 to 6
                    
                    $ipp->setData("./documentation/COPYING");//Path to file.
                    
                    $ipp->printJob();
                
                    $ipp->setPageRanges(''); // reset page ranges
                    
                ?>
                 
            
                <?php
                
                /* printing strings, no form feed */

                    $ipp->setRawText();
                    $ipp->unsetFormFeed();

                    $ipp->setData("This is a line\n");
                    $ipp->printJob();

                    $ipp->setData("This is half a line ");
                    $ipp->printJob();

                    $ipp->setData("This is a end of line\n");
                    $ipp->printJob("epson");

                    // set copies to 2 (same sheet of paper: form feed is unset)
                    $ipp->setData("This lines must appeared twice\r\n");
                    $ipp->setCopies(2);
                    $ipp->printJob();
                    
                    $ipp->setCopies(1);

                    // printing string, then form feed
                    $ipp->setFormFeed();
                    $ipp->setData("End of test");
                    $ipp->printJob();

                    $ipp->setBinary(); // reset to normal use
                    
                    echo "Jobs URIs:"; // display jobs uris
                    echo "<pre>\n";
                    print_r($ipp-<jobs_uri);
                    echo "</pre>";


                ?>
            

Raw text is not usable for laser printers.

Problems and solutions

My script fails with "_(): function unknown"

OK: you do not have gettext (gettext is an I-18n (internationalization) system).
Solutions:
Install gettext part of PHP
The simpler one if you have your own server
Create a fake gettext
in your code:
                                        if (!function_exists('_'))
                                           require_once ('gettext.php');
                                    
File gettext.php:
                                        <?php
                                            function _($text) {
                                                return $text;
                                            }
                                        >
                                    
That's all!

Public variables

Setup

$ssl

Set it to 1 for tls connections between web server and IPP server.

With CUPS1.1, you need to setup "SSLPort" in "cupsd.conf" on wanted port for secure connections

$paths

array
keys = root,admin,printers,jobs
Set paths to whatever needed for the operations. By default, CUPS server settings (values = "/","/admin/","/printers/","/jobs/").

$http_timeout

timeout at http connection (seconds) 0 ⇒ default ⇒ 30.

$http_data_timeout

data reading timeout (milliseconds) 0 ⇒ default ⇒ 30.

$debug_level

0 to 4 (4 = quiet). Debugging purpose, set the amount of data you want for get/printDebug().

$alert_on_end_tag

debugging purpose: echo "END tag OK" if (1 and reads while end tag). If you experience problems with incomplete responses from server, you can use it to setup $http_data_timeout.

$with_exceptions

Set it to true to activate exceptions (backward compatibility).

$handle_http_exceptions

Set it to true to activate handling of http exceptions through ippException.

Readable public variables

$jobs

array()
contains job ids from operations (filled with non null value if such a job is returned by server, eg. after "PrintJob()").

$jobs_uri

array()
contains job URIs from operations. What you must read if you want to cancel job or make other operations on it.

$status

array()
exit status from each operation.

$response_completed

array()
If you suspect incomplete responses from server, contains information about it ("no" or "complete" for each operation).

$last_job

string
contains last job's URI. Useful for CancelJob().

$printer_attributes

object you can read: printer's attributes after getPrinterAttributes().

$job_attributes

object you can read: last job attributes.

$jobs_attributes

object you can read: jobs attributes after getJobs().

$available_printers

array
printers URIS after getPrinters() if such getPrinters operation is implemented for your vendor (Currently: CUPS).

$printers_uri

array
printers URIs for each job, if returned by server (not with CUPS).

$debug

array
debugging information, 1 line per event logged.

$attributes

object you can read: attributes after any operation.

Response parsing

Operation's status

Returned by operations functions.
Can also be found in array $ipp->status (1 key by operation).

Operations functions returns false in case of HTTP error,

Job's uri

Needed to CancelJob($job_uri).
Last job uri is in string $ipp->last_job
Can also be found in array $ipp->jobs_uri (1 key by operation);

Available printer's uris

Found in array $ipp->available_printers, after a call to getPrinters().

getPrinters() is not part of IPP standard, thus it is implemented in (NameOfVendor)PrintIPP.

Printer's attributes

After a call to getPrinterAttributes(), founds in $ipp->printer_attributes.
example:
                <?php

                    $ipp = new PrintIPP();
                    $ipp->setHost("localhost");
                    $ipp->setPort();
                    $ipp->setPrinterURI("/printers/epson");
                    
                    $ipp->getPrinterAttributes();
                    
                    echo "Printer attributes for printer $i:
                    <pre>\n"; print_r($ipp->printer_attributes); echo "</pre>";
                    
                    /* Cups defines an attribute "printer -type" */
                        if (isset($ipp->printer_attributes->printer_type->_value2)
                        && ($ipp->printer_attributes->printer_type->_value2) == 'print-black')
                        echo "The printer can print black<br />\n";
                        
                        if (isset($ipp->printer_attributes->printer_type->_value3)
                        && ($ipp->printer_attributes->printer_type->_value3) == 'print-color')
                        echo "The printer can print color<br />\n";
                    
                    /* other attributes */
                        echo "Printer State: ".$ipp->printer_attributes->printer_state->_value0."<br />\n";
                        echo "Printer State message: ".$ipp->printer_attributes->printer_state_message->_value0."<br />";
                        
                        echo "Document formats supported:<br /><pre>";
                        $pointer = "_value0";
                        for ($i = 0 ; isset($ipp->printer_attributes->document_format_supported->$pointer); $i++) {
                            echo $ipp->printer_attributes->document_format_supported->$pointer . "\n";
                            $pointer = "_value" . ($i + 1);
                            }
                        echo "</pre>";

 
                ?>
                    

Job's attributes

After a call to *Job() (except "validateJob"), founds in $ipp->job_attributes.
Parsing: same method than Printer's attributes. see getJobAttributes() operation;

Job's attributes

After a call to getJobs(), founds in $ipp->jobs_attributes.
Parsing: same method than Printer's attributes, except that jobs are objects. See "getJobs()" operation for an example.

Functions reference

Setup

setPort($port='631')

Select port which IPP server listen. By default port is set to IANA assigned port (631).

setHost($host='localhost')

Select host which is located IPP server (IP or resolvable hostname/FQDN). (! → disable setUnix() ). Mandatory if you dont use UNIX sockets.

setUnix($socket='/var/run/cups/cups.sock')

Set UNIX socket name (! → disable setHost()). Mandatory if you don't use http/https.

setPrinterUri($uri)

Select printer.
                    /* examples */
                    
                    $ipp->setPrinterUri('/printers/epson');
                    $ipp->setPrinterUri('ipp://localhost:631/printers/epson')
                    
Mandatory, automatically done by CupsPrintIPP if not set.

setData($data)

string to be printed or file name of a readable file. Mandatory for printing operations PrintJob() & sendDocument().

setRawText()

Force data to be interpreted as raw text, and be sent directly to printer. It prepends a "SYN" and postpend a "Form Feed" characters to the data or file.

Can be used only on dot-matrix and ink-jet printers.

unsetRawText()

Unset previous operation (setRawText()).

setBinary()

Alias for unsetRawText().

setFormFeed()

When rawText is set, forces a form feed after printing. Automatically set at setRawText() call.

unsetFormFeed()

Causes not form feed in RawText mode.

Must be called after each occurrence of setRawText.

setCharset($charset)

Set requests charset. Automatically set to "us-ascii" if not set.

setLanguage($language)

Set requests natural language. Automatically set to "en_us" if not set.

setMimeMediaType($mime_media_type='application/octet-stream')

Set type of document. By default: application/octet-stream ⇒ auto detection.

setCopies($nbrcopies=1)

Set number of copies.

setDocumentName($document_name)

Set document name (as for title page).

setJobName($jobname='(PHP)',$absolute=false)

Set job name. If $absolute is not 'true' (default), a count is automatically appended (MMDDHHMMSScount).

setUserName($username='PHP-SERVER')

Set user name as displayed on server and title pages. Automatically set to "PHP-SERVER" if not.

setAuthentication($username,$password)

Set system user name and password when server needs authentication for operation. (e.g. cancelJob() on CUPS with standard settings).

If the server do not support Basic nor Digest authentication, you need to install SASL to use authentication. See INSTALL

setSides($sides=2)

Set sides on printed document.
Possibles values are:
1: one-sided
2: two-sided-long-edge
2CE: two-sided-short-edge

setFidelity()

If printer can't respect all attributes, do not print.

unsetFidelity()

Print anyway (replace attributes as needed), after a call to setFidelity ().

setMessage($message)

Set message given to user, especially with CancelJob().

Cups does not reply this message

setPageRanges($page_ranges)

Set ranges of pages to be printed. $page_ranges == string, e.g.:" 1-2 5-6 8-14".

an empty string resets page-ranges.

setAttribute($attribute,$value)

For attributes which have not dedicated function. $attribute and $value are the correspondent text strings in RFC2911. Returns false on failure.
Examples:
                    
                    /* standard */
                    
                    $ipp->setAttribute("job-billing", "Thomas");
                    
                    /* with 1 set of xxx */
                   
                     // add a start banner "confidential" and a end banner "secret"
                     // I know, this example is unusual
                    $ipp->setAttribute("job-sheets", array("confidential","secret"));
                    
                    /* special case for resolution: */
                    
                        // dpi: dot per inch
                    $ipp->setAttribute("printer-resolution","1440x720dpi");
                    
                        // dpc: dot per centimeter
                    $ipp->setAttribute("printer-resolution","320x200dpc");
                    
                    
setAttributes takes care of attribute-type: you have to enter the text string, comprised 'enum' types.
Will add a separate page to list attributes and parameters, but for starting you cant get most of them by "getPrinterAttributes()" and "getJobAttributes()" :)

unsetAttribute($attribute)

Unset given attribute for next jobs, for attributes which have not dedicated function.

Operations

printJob()

Print a single string or document, previously set by setdata($data).

cancelJob($job_uri)

cancel job which have uri $uri, as which is given in $ipp->last_job or in array $ipp->jobs_uri ⇒ (one key by operation).

getPrinterAttributes()

Get printer's attributes of printer set by setPrinterUri($uri), fill object $ipp->printer_attributes. see response parsing.

validateJob()

Verify if the job can be printed with it's attributes before sending document.
Example:
                    
                    <?php
                    
                    [...]
                    $ipp->setMimeMediaType("application/x-foobar");
                    
                    echo "Validate-Job: ".$ipp->validateJob()."<br />";

                    foreach ($ipp->attributes as $name => $attribute)
                        if ($attribute->_range == 'unsupported-attributes')
                            printf('%s "%s": unsupported attribute<br />',$name,$attribute->_value0);
                        
                    reset($ipp->attributes);
                    
                    ?>
                    
                    Displays:
                    Validate-Job: client-error-document-format-not-supported
                    document_format "application/x-foobar": unsupported attribute
                    
                    

getJobAttributes($job_uri,subset="false",$attributes_group="all")

Get attributes from the job $job_uri. If (!$subset), gives $attributes_group="all" by default, or attributes_group = 'job-template' or 'job-description' if you fills third argument. if ($subset), gives only useful subset of attributes.
Example:
                    <?php
                    
                    [...]
                    echo "Printing Job: ".$ipp->printJob()."<br />";
                    $ipp->getJobAttributes($ipp->last_job,false,'job-template');
                    
                    $job_state = $ipp->job_attributes->job_state->_value0;
                    echo "Job-State: $job_state<br />";

                    $job_state_reasons = $ipp->job_attributes->job_state_reasons->_value0;
                    echo "Job-State-Reasons: $job_state_reasons<br />";
                    
                    echo "<pre>";print_r($ipp->job_attributes); echo "</pre>";
                    
                    ?>
                    
                    displays:
                    Job-State: processing
                    Job-State-Reasons: job-printing
                        (or whatever is the job's status)
                   stdClass Object
                   (
                       [attributes_charset] => stdClass Object
                               (
                                [_type] => charset
                                [_range] => start operation-attributes
                                [_value0] => utf-8
                                )

                       [attributes_natural_language] => stdClass Object
                               (
                                [_type] => naturalLanguage
                                [_range] => start operation-attributes
                                [_value0] => fr-fr
                               )
 
                       [job_uri] => stdClass Object
                               (
                                [_type] => uri
                                [_range] => start job-attributes
                                [_value0] => http://geekette:631/jobs/202
                                )
                       [...]
                    

getJobs($my_jobs=true,$limit=0,$which_jobs="",$subset='true')

get Jobs attributes, by default only your jobs, except if you set first argument to "false", by default with no limit, except if you gives an integer (0 < x < 65535) in second argument, by default not-completed, except if you gives 'completed' as third argument, by default only a useful subset of attributes, except if you gives 'false' as fourth argument.
Example:
                    <?php
                    
                    echo "Getting Jobs: ".$ipp->getJobs($my_jobs=true,$limit=0,"completed",true)."<br />";
                    echo "Job 0 state: ".$ipp->jobs_attributes->job_0->job_state->_value0."<br />";
                    echo "Job 0 state-reasons: ".$ipp->jobs_attributes->job_0->job_state_reasons->_value0."<br />";
                    
                    echo "<pre>";print_r($ipp->jobs_attributes); echo "</pre>";
                    
                    ?>

                    Displays:
                    Getting Jobs: successful-ok-ignored-or-substituted-attributes
                    Job 0 state: processing
                    Job 0 state-reasons: job-printing
                    
                    stdClass Object
                                    (
                                     [job_0] => stdClass Object
                                            (
                                             [job_more_info] => stdClass Object
                                                (
                                                 [_type] => uri
                                                 [_range] => start job-attributes
                                                 [_value0] => http://geekette:631/jobs/205
                                                 )
                                             [job_uri] => stdClass Object
                                                (
                                                 [_type] => uri
                                                 [_range] => start job-attributes
                                                 [_value0] => http://geekette:631/jobs/205
                                                )
                                             [job_printer_up_time] => stdClass Object
                                                (
                                                 [_type] => integer
                                                 [_range] => start job-attributes
                                                 [_value0] => 1136224652
                                                )
                                             [job_name] => stdClass Object
                                               (
                                                [_type] => nameWithoutLanguage
                                                [_range] => start job-attributes
                                                [_value0] => test-utf8.txt
                                               )
                                             [job_state] => stdClass Object
                                               (
                                                [_type] => enum
                                                [_range] => start job-attributes
                                                [_value0] => processing
                                               )
                                             [job_state_reasons] => stdClass Object
                                               (
                                                [_type] => keyword
                                                [_range] => start job-attributes
                                                [_value0] => job-printing
                                               )
                                            )
                                     [job_1] => stdClass Object
                                        [...]
                                    )
                    

printURI($uri)

Implemented in ExtendedPrintIPP.

Print a single document, which uri is given in argument.

Not implemented in Cups server (OPTIONAL operation).

purgeJobs()

Function implemented in ExtendedPrintIPP

Purge jobs for printer designed by setPrinterUri($uri), for all printers if $uri is "/printers/".
Example:
                    
                    <?php
                    
                    /* purging jobs for a printer */

                    $IPP = new ExtendedPrintIPP();
                    
                    $ipp->setUserName("test");
                    $ipp->setAuthentication("test","test"); // username & password 
                    $ipp->setPrinterURI("ipp://localhost:631/printers/epson"); // Set printer URI here
                    echo "Purge-Jobs: ". $ipp->purgeJobs() ."<br />";

                    /* purging jobs for all printers */
                    $ipp->setPrinterURI("ipp://localhost:631/printers/"); // => all printers
                    echo "Purge-Jobs: ". $ipp->purgeJobs() ."<br />";

                    ?>
                    

createJob()

Function implemented in ExtendedPrintIPP.

IPP Create-Job operation, before sending multi-documents with sendDocument($job); or sendURI($job,$uri).
See sendDocument example.

sendDocument($job_uri,$is_last=false)

Function implemented in ExtendedPrintIPP.

Send a document after a job has been created.
Example:
                    <?php
                    
                    function __autoload($class_name) {
                        require_once $class_name . '.php';
                        }
 
                    $IPP = new ExtendedPrintIPP();
                    
                    $ipp->debug_level = 3;
                    $ipp->setUserName("test");
                    $ipp->setCopies(2);
                    
                    $ipp->setAuthentication("test","test"); // username & password. MANDATORY
                    
                    echo "Create-Job: ".$ipp->createJob(). "<br />";
                    printf("Job is: %s<br />",$job = $ipp->last_job);
                    echo "<pre>";print_r($ipp->job_attributes);echo "</pre>\n";

                    $ipp->setDocumentName("test-utf8.txt");
                    $ipp->setData("./testfiles/test-utf8.txt");
                    echo "Sending document: " . $ipp->sendDocument($job) . "<br />\n";

                    $ipp->setDocumentName("text string");
                    $ipp->setData("This is the string of second document");
                    echo "Sending document: " . $ipp->sendDocument($job,$last=true) . "<br />\n";

                    // must be refused. Hem: CUPS is very smart, it accepts :)
                    echo "Sending document: " . $ipp->sendDocument($job,$last=true) . "<br />\n";

                    ?>
                    

sendURI($uri,$job_uri,$is_last=false)

Function implemented in ExtendedPrintIPP.

Send a document after a job has been created.
Example:
                    <?php
                    
                    $uri = "http://localhost/";
                    
                    echo "Create-Job: ".$ipp->createJob(). "<br />";
                    printf("Job is: %s<br />",$job = $ipp->last_job);
 
                    echo "Sending URI: " . $ipp->sendURI($uri,$job,$last=true) . "<br />\n";

                    ?>
                    

pausePrinter()

Function implemented in ExtendedPrintIPP.

Pause printer setted by setPrinterURI($uri).

resumePrinter()

Function implemented in ExtendedPrintIPP.

resume (restart) printer set by setPrinterURI($uri).

holdJob($job_uri,$until='indefinite')

Function implemented in ExtendedPrintIPP.

Holds a job.
$until can be'no-hold','day-time','evening','night','weekend','second-shift','third-shift'.
Example:
                    <?php
                    
                    echo "printing document: " . $ipp->printJob("test"). "<br />\n";

                    echo "Holding Job: " .$ipp->holdJob($job,'night');
                    
                    $ipp->getJobAttributes($ipp->last_job,false,'job-template');
                    
                    $job_state = $ipp->job_attributes->job_state->_value0;
                    echo "Job-State: $job_state<br />";

                    $job_state_reasons = $ipp->job_attributes->job_state_reasons->_value0;
                    echo "Job-State-Reasons: $job_state_reasons<br />";
                     
                    ?>
                    

releaseJob($job_uri)

Function implemented in ExtendedPrintIPP.

Release a pending or holded job.

restartJob($job_uri)

Function implemented in ExtendedPrintIPP.

Restarts a completed job.
Example:
                    <?php
                    
                    echo "printing document: " . $ipp->printJob("test"). "<br />\n";
                    
                    sleep (10);
                    
                    $ipp->setAttribute('job-hold-until','weekend');
                    
                    $ipp->restartJob($ipp->last_job);
                    
                     
                    ?>
                    
                    Will re-print the job in the week-end.
                    

setJobAttributes($job_uri,array($deleted_attributes))

Function implemented in ExtendedPrintIPP.

Modify an existing job's attributes with values previously set by various setXXX operations.
Delete attributes which are in array of second argument.
Example:
                        
                        /* setting copies to 2 */
                    
                    $ipp->setCopies(2);
                    
                        /* no idea for what to delete :) */

                    $unset_attributes = array();

                        /* commit changes */

                    $ipp->setJobAttributes($ipp->last_job,$unset_attributes); 
                    
                    

getPrinters()

Function implemented in (NameOfVendor)PrintIPP.

Get availables printers, fill array $ipp->available_printers with printer's uris.
Example:
                    
                    <?php
                       
                        function __autoload($class_name) {
                            require_once $class_name . '.php';
                        }
                        
                        $ipp = new CupsPrintIPP;
                        
                        $ipp->getPrinters();
                        
                        $uri = $ipp->available_printers[0];
                        
                        $ipp->setPrinterUri($uri);
                        
                    ?>
                    
                    

Logging / debugging

setLog($log_destination,$destination_type='file',$level=2)

$destination_type can be "file", "logger", "e-mail".
$log_destination is a (new) writable file in a writable directory, or e-mail.
$level is
0 ⇒ quiet;
1 to 3 ⇒ less to more verbose.

printDebug()

Display debugging information.
Verbosity set from 0 to 4 (=silent) in $ipp->debug_level.

getDebug()

Returns debugging information.
Verbosity set from 0 to 4 (=silent) in $ipp->debug_level.

Exceptions

httpException

public function getErrorFormatted()
public function getErrno()
public function getMessage()
public function getLine()
public function getFile()
public function getTrace()
public function getTraceAsString()

ippException

public function getErrorFormatted()
public function getErrno()
public function getMessage()
public function getLine()
public function getFile()
public function getTrace()
public function getTraceAsString()

writable attributes

See file attributes.html

Readable attributes

See file readable-attributes.html

Cups specific operations and parsing

See file CupsPrintIPP-usage.html

phpprintipp command line tool

See file phpprintipp.html