Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Moodle/mod/print/BasicIPP.php
diff options
context:
space:
mode:
Diffstat (limited to 'Moodle/mod/print/BasicIPP.php')
-rwxr-xr-xMoodle/mod/print/BasicIPP.php1832
1 files changed, 1832 insertions, 0 deletions
diff --git a/Moodle/mod/print/BasicIPP.php b/Moodle/mod/print/BasicIPP.php
new file mode 100755
index 0000000..6537fd2
--- /dev/null
+++ b/Moodle/mod/print/BasicIPP.php
@@ -0,0 +1,1832 @@
+<?php
+/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
+ /* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/BasicIPP.php,v 1.1 2008/06/21 00:30:56 harding Exp $
+ *
+ * Class BasicIPP - Send Basic IPP requests, Get and parses IPP Responses.
+ *
+ * Copyright (C) 2005-2006 Thomas HARDING
+ * Parts Copyright (C) 2005-2006 Manuel Lemos
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * mailto:thomas.harding@laposte.net
+ * Thomas Harding, 56 rue de la bourie rouge, 45 000 ORLEANS -- FRANCE
+ *
+ */
+
+/*
+
+ This class is intended to implement Internet Printing Protocol on client side.
+
+ References needed to debug / add functionnalities:
+ - RFC 2910
+ - RFC 2911
+ - RFC 3380
+ - RFC 3382
+*/
+/*
+ TODO: beta tests on other servers than Cups
+*/
+
+
+ // {{{ required and included files
+
+ require_once("http_class.php");
+
+ // If you want http backend from http://www.phpclasses.org/browse/package/3.html
+ /*
+ require_once("HTTP/http.php");
+ include_once("SASL/sasl.php");
+ include_once("SASL/basic_sasl_client.php");
+ include_once("SASL/digest_sasl_client.php");
+ include_once("SASL/ntlm_sasl_client.php");
+ */
+ // }}}
+
+
+/***********************
+*
+* ippException class
+*
+************************/
+
+ // {{{ class ippException
+class ippException extends Exception {
+
+ protected $errno;
+
+ public function __construct($msg,$errno=null) {
+ parent :: __construct($msg);
+ $this->errno = $errno;
+ }
+
+ public function getErrorFormatted() {
+
+ $return = sprintf("[ipp]: %s -- "._(" file %s, line %s"),
+ $this->getMessage(),
+ $this->getFile(),
+ $this->getLine());
+
+ return $return;
+ }
+
+ public function getErrno() {
+
+ return $this->errno ;
+ }
+
+}
+ // }}}
+
+
+
+class BasicIPP {
+
+ // {{{ variables declaration
+ // setup variables
+ public $paths = array("root" => "/",
+ "admin" => "/admin/",
+ "printers" => "/printers/",
+ "jobs" => "/jobs/");
+ public $http_timeout = 0; // timeout at http connection (seconds) 0 => default => 30.
+ public $http_data_timeout = 0; // data reading timeout (milliseconds) 0 => default => 30.
+ public $ssl = false;
+ public $debug_level = 3; // max 3: almost silent
+ public $alert_on_end_tag;// debugging purpose: echo "END tag OK" if (1 and reads while end tag)
+ public $with_exceptions = 0; // compatibility mode for old scripts
+ public $handle_http_exceptions = 1;
+ // readables variables
+ public $jobs = array();
+ public $jobs_uri = array();
+ public $status = array();
+ public $response_completed = array();
+ public $last_job = "";
+ public $attributes; // object you can read: attributes after validateJob()
+ public $printer_attributes; // object you can read: printer's attributes after getPrinterAttributes()
+ public $job_attributes; // object you can read: last job attributes
+ public $jobs_attributes; // object you can read: jobs attributes after getJobs()
+ public $available_printers = array();
+ public $printers_uri = array();
+ public $debug = array();
+ public $response;
+
+ // {{{ protected variables;
+
+ protected $log_level = 2; // max 3: very verbose
+ protected $log_type = 3; // 3: file | 1: e-mail | 0: logger
+ protected $log_destination; // e-mail or file
+ protected $serveroutput;
+ protected $setup;
+ protected $stringjob;
+ protected $data;
+ protected $debug_count = 0;
+ protected $username;
+ protected $charset;
+ protected $password;
+ protected $requesring_user;
+ protected $client_hostname = "localhost";
+ protected $stream;
+ protected $host = "localhost";
+ protected $port = "631";
+ protected $printer_uri;
+ protected $timeout = "20"; //20 secs
+ protected $errNo;
+ protected $errStr;
+ protected $datatype;
+ protected $datahead;
+ protected $datatail;
+ public $meta;
+ protected $operation_id;
+ protected $delay;
+ protected $error_generation; //devel feature
+ protected $debug_http = 0;
+ protected $no_disconnect;
+ protected $job_tags;
+ protected $operation_tags;
+ protected $index;
+ protected $collection ; //RFC3382
+ protected $collection_index; //RFC3382
+ protected $collection_key = array(); //RFC3382
+ protected $collection_depth = -1; //RFC3382
+ protected $end_collection = false; //RFC3382
+ protected $collection_nbr = array(); //RFC3382
+ protected $unix = false; // true -> use unix sockets instead of http
+ // }}}
+ // }}}
+
+ // {{{ constructor
+ public function __construct() {
+ $tz = getenv("date.timezone");
+ if (!$tz)
+ $tz = date_default_timezone_get();
+ date_default_timezone_set($tz);
+
+ $this->meta = new stdClass();
+ $this->setup = new stdClass();
+ $this->values = new stdClass();
+ $this->serveroutput = new stdClass();
+ $this->error_generation = new stdClass();
+ $this->_parsing = new stdClass();
+
+ self::_initTags ();
+ }
+ // }}}
+
+/*****************
+*
+* PUBLIC FUNCTIONS
+*
+*******************/
+
+
+// SETUP
+
+ // {{{ setPort($port='631')
+ public function setPort($port='631'){
+ $this->port = $port;
+ self::_putDebug("Port is ".$this->port,2);
+ }
+ // }}}
+
+ // {{{ setUnix($socket='/var/run/cups/cups.sock')
+ public function setUnix($socket='/var/run/cups/cups.sock') {
+ $this->host = $socket;
+ $this->unix = true;
+ self::_putDebug("Host is ".$this->host,2);
+ }
+ // }}}
+
+ // {{{ setHost($host='localhost')
+ public function setHost($host='localhost'){
+ $this->host = $host;
+ $this->unix = false;
+ self::_putDebug("Host is ".$this->host,2);
+ }
+ // }}}
+
+ // {{{ setTimeout($timeout)
+ public function setTimeout($timeout){
+ $this->timeout = $timeout;
+ }
+ // }}}
+
+ // {{{ setPrinterURI ($uri)
+ public function setPrinterURI ($uri) {
+
+
+ $length = strlen ($uri);
+ $length = chr($length);
+
+ while (strlen($length) < 2)
+ $length = chr(0x00) . $length;
+
+ $this->meta->printer_uri = chr(0x45) // uri type | value-tag
+ . chr(0x00) . chr(0x0B) // name-length
+ . "printer-uri" // printer-uri | name
+ . $length
+ . $uri;
+
+ $this->printer_uri = $uri;
+
+ self::_putDebug(sprintf(_("Printer URI: %s"),$uri),2);
+
+ $this->setup->uri = 1;
+
+ }
+ // }}}
+
+ // {{{ setData($data)
+ public function setData($data){
+ //
+ $this->data = $data;
+ self::_putDebug("Data set",2);
+ }
+ // }}}
+
+ // {{{ setRawText ()
+ public function setRawText () {
+ $this->setup->datatype = 'TEXT';
+ $this->meta->mime_media_type = "";
+ $this->setup->mime_media_type = 1;
+ $this->datahead = chr(0x16);
+
+ if (is_readable($this->data)){
+ //It's a filename. Open and stream.
+ $data = fopen($this->data, "rb");
+ while(!feof($data))
+ $output = fread($data, 8192);
+ } else {
+ $output = $this->data;
+ }
+
+ if (substr($output,-1,1) != chr(0x0c))
+ if (!isset($this->setup->noFormFeed))
+ $this->datatail = chr(0x0c);
+
+ self::_putDebug(_("Forcing data to be interpreted as RAW TEXT"),2);
+ }
+ // }}}
+
+ // {{{ unsetRawText ()
+ public function unsetRawText () {
+
+ $this->setup->datatype = 'BINARY';
+ $this->datahead = '';
+ $this->datatail = '';
+ self::_putDebug(_("Unset forcing data to be interpreted as RAW TEXT"),2);
+
+ }
+ // }}}
+
+ // {{{ setBinary()
+ public function setBinary () {
+ self::unsetRawText();
+ }
+ // }}}
+
+ // {{{ setFormFeed ()
+ public function setFormFeed () {
+ $this->datatail = "\r\n".chr(0x0c);
+ unset($this->setup->noFormFeed);
+ }
+ // }}}
+
+ // {{{ unsetFormFeed ()
+ public function unsetFormFeed () {
+ $this->datatail = '';
+ $this->setup->noFormFeed = 1;
+ }
+ // }}}
+
+ // {{{ setCharset ($charset)
+ public function setCharset ($charset='us-ascii') {
+
+ $charset = strtolower($charset);
+ $this->charset = $charset;
+
+ $this->meta->charset = chr(0x47) // charset type | value-tag
+ . chr(0x00) . chr(0x12) // name-length
+ . "attributes-charset" // attributes-charset | name
+ . self::_giveMeStringLength($charset) // value-length
+ . $charset; // value
+
+ self::_putDebug(sprintf(_("Charset: %s"),$charset),2);
+
+ $this->setup->charset = 1;
+ }
+ // }}}
+
+ // {{{ setLanguage($language)
+ public function setLanguage($language='en_us') {
+
+ $language = strtolower($language);
+
+ $this->meta->language = chr(0x48) // natural-language type | value-tag
+ . chr(0x00) . chr(0x1B) // name-length
+ . "attributes-natural-language" //attributes-natural-language
+ . self::_giveMeStringLength($language) // value-length
+ . $language; // value
+
+ self::_putDebug(sprintf(_("Language: %s"),$language),2);
+
+ $this->setup->language = 1;
+ }
+ // }}}
+
+ // {{{ setMimeMediaType ($mime_media_type='application/octet-stream')
+ public function setMimeMediaType ($mime_media_type='') {
+
+ self::setBinary();
+
+ $length = strlen ($mime_media_type);
+ if ($length == 0)
+ {
+ $this->meta->mime_media_type = "";
+ }
+ else
+ {
+ $length = chr($length);
+
+ while (strlen($length) < 2)
+ $length = chr(0x00) . $length;
+
+
+ self::_putDebug( sprintf(_("mime type: %s"),$mime_media_type),2);
+
+ $this->meta->mime_media_type = chr(0x49) // document-format tag
+ . self::_giveMeStringLength('document-format')
+ . 'document-format' //
+ . self::_giveMeStringLength($mime_media_type)
+ . $mime_media_type; // value
+ }
+ $this->setup->mime_media_type = 1;
+ }
+ // }}}
+
+ // {{{ setDocumentFormat ($mime_media_type="application/octet-stream") // setMimeMediaType alias
+ public function setDocumentFormat ($mime_media_type="application/octet-stream") {
+ self::setMimeMediaType ($mime_media_type);
+ }
+ // }}}
+
+ // {{{ setCopies ($nbrcopies=1)
+ public function setCopies ($nbrcopies=1) {
+
+ $this->meta->copies = "";
+ if ($nbrcopies == 1 || !$nbrcopies)
+ return true;
+
+ $copies = self::_integerBuild($nbrcopies);
+
+ $this->meta->copies = chr(0x21) // integer type | value-tag
+ . chr(0x00) .chr(0x06) // name-length
+ . "copies" // copies | name
+ . self::_giveMeStringLength($copies) // value-length
+ . $copies;
+
+ self::_putDebug( sprintf(_("Copies: %s"),$nbrcopies),2);
+
+ $this->setup->copies = 1;
+
+ }
+ // }}}
+
+ // {{{ setDocumentName ($document_name)
+ public function setDocumentName ($document_name="") {
+
+ $this->meta->document_name = "";
+ if (!$document_name)
+ return true;
+
+ $document_name = substr($document_name,0,1023);
+
+ $length = strlen ($document_name);
+ $length = chr($length);
+
+ while (strlen($length) < 2)
+ $length = chr(0x00) . $length;
+
+
+ self::_putDebug( sprintf(_("document name: %s"),$document_name),2);
+
+ $this->meta->document_name = chr(0x41) // textWithoutLanguage tag
+ . chr(0x00) . chr(0x0d) // name-length
+ . "document-name" // mimeMediaType
+ . self::_giveMeStringLength($document_name)
+ . $document_name; // value
+
+ }
+ // }}}
+
+ // {{{ setJobName ($jobname='(PHP)',$absolute=false)
+ public function setJobName ($jobname='',$absolute=false) {
+
+ $this->meta->jobname = '';
+ if ($jobname=='')
+ {
+ $this->meta->jobname = '';
+ return true;
+ }
+ $postpend = date('-H:i:s-') . $this->_setJobId();
+
+ if ($absolute)
+ $postpend = '';
+
+ if (isset($this->values->jobname) && $jobname == '(PHP)')
+ $jobname = $this->values->jobname;
+
+ $this->values->jobname = $jobname;
+
+ $jobname .= $postpend;
+
+ $this->meta->jobname = chr(0x42) // nameWithoutLanguage type || value-tag
+ . chr(0x00) . chr(0x08) // name-length
+ . "job-name" // job-name || name
+ . self::_giveMeStringLength($jobname) // value-length
+ . $jobname ; // value
+
+ self::_putDebug( sprintf(_("Job name: %s"),$jobname),2);
+ $this->setup->jobname = 1;
+ }
+ // }}}
+
+ // {{{ setUserName ($username='PHP-SERVER')
+ public function setUserName ($username='PHP-SERVER') {
+
+ $this->requesting_user = $username;
+ $this->meta->username = '';
+ if (!$username)
+ return true;
+
+ if ($username == 'PHP-SERVER' && isset($this->meta->username))
+ return TRUE;
+
+ $value_length = 0x00;
+ for ($i = 0 ; $i < strlen($username) ; $i ++) {
+ $value_length += 0x01;
+ }
+ $value_length = chr($value_length);
+
+ while (strlen($value_length) < 2)
+ $value_length = chr(0x00) . $value_length;
+
+ $this->meta->username = chr(0x42) // keyword type || value-tag
+ . chr(0x00). chr(0x14) // name-length
+ . "requesting-user-name"
+ . $value_length
+ . $username;
+
+ self::_putDebug( sprintf(_("Username: %s"),$username),2);
+ $this->setup->username = 1;
+ }
+ // }}}
+
+ // {{{ setAuthentification ($username,$password)
+ public function setAuthentification ($username,$password) {
+ self::setAuthentication ($username,$password);
+ }
+ // }}}
+
+ // {{{ setAuthentication ($username,$password)
+ public function setAuthentication ($username,$password) {
+ $this->password = $password;
+ $this->username = $username;
+
+ self::_putDebug( _("Setting password"),2);
+ $this->setup->password = 1;
+ }
+ // }}}
+
+ // {{{ setSides ($sides=2)
+ public function setSides ($sides=2) {
+
+ $this->meta->sides = '';
+ if (!$sides)
+ return true;
+
+ switch ($sides) {
+ case 1:
+ $sides = "one-sided";
+ break;
+ case 2:
+ $sides = "two-sided-long-edge";
+ break;
+ case "2CE":
+ $sides = "two-sided-short-edge";
+ break;
+ default:
+ $sides = $sides; // yeah, what ?
+ break;
+ }
+
+
+ $this->meta->sides = chr(0x44) // keyword type | value-tag
+ . chr(0x00). chr(0x05) // name-length
+ . "sides" // sides | name
+ . self::_giveMeStringLength($sides) // value-length
+ . $sides ; // one-sided | value
+
+ self::_putDebug( sprintf(_("Sides value set to %s"), $sides),2);
+ }
+ // }}}
+
+ // {{{ setFidelity ()
+ public function setFidelity () {
+
+ // whether the server can't replace any attributes (eg, 2 sided print is not possible,
+ // so print one sided) and DO NOT THE JOB.
+ $this->meta->fidelity = chr(0x22) // boolean type | value-tag
+ . chr(0x00). chr(0x16) // name-length
+ . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name
+ . chr(0x00) . chr(0x01) // value-length
+ . chr(0x01); // true | value
+
+ self::_putDebug( _("Fidelity attribute is set (paranoid mode)"),3);
+
+ }
+ // }}}
+
+ // {{{ unsetFidelity ()
+ public function unsetFidelity () {
+
+ // whether the server can replace any attributes (eg, 2 sided print is not possible,
+ // so print one sided) and DO THE JOB.
+
+ $this->meta->fidelity = chr(0x22) // boolean type | value-tag
+ . chr(0x00). chr(0x16) // name-length
+ . "ipp-attribute-fidelity" // ipp-attribute-fidelity | name
+ . chr(0x00) . chr(0x01) // value-length
+ . chr(0x00); // false | value
+
+ self::_putDebug( _("Fidelity attribute is unset"),2);
+ }
+ // }}}
+
+ // {{{ setMessage()
+ public function setMessage ($message='') {
+
+ $this->meta->message = '';
+ if (!$message)
+ return true;
+
+ $this->meta->message = chr(0x41) // attribute type = textWithoutLanguage
+ . chr(0x00) . chr(0x07)
+ . "message"
+ . self::_giveMeStringLength(substr($message,0,127))
+ . substr($message,0,127);
+
+ self::_putDebug( sprintf(_('Setting message to "%s"'),$message),2);
+ }
+ // }}}
+
+ // {{{ setPageRanges($page_ranges)
+ public function setPageRanges($page_ranges) {
+
+ // $pages_ranges = string: "1:5 10:25 40:52 ..."
+ // to unset, specify an empty string.
+
+ $this->meta->page_range = '';
+
+ if (!$page_ranges)
+ return true;
+
+ $page_ranges = trim(str_replace("-",":",$page_ranges));
+
+ $first = true;
+ $page_ranges = split(' ',$page_ranges);
+ foreach ($page_ranges as $page_range) {
+ $value = self::_rangeOfIntegerBuild($page_range);
+
+ if ($first)
+ $this->meta->page_ranges .= $this->tags_types['rangeOfInteger']['tag']
+ . self::_giveMeStringLength('page-ranges')
+ . 'page-ranges'
+ . self::_giveMeStringLength($value)
+ . $value;
+ else
+ $this->meta->page_ranges .= $this->tags_types['rangeOfInteger']['tag']
+ . self::_giveMeStringLength('')
+ . self::_giveMeStringLength($value)
+ . $value;
+ $first = false;
+ }
+
+ }
+ // }}}
+
+ // {{{ setAttribute($attribute,$value)
+ public function setAttribute($attribute,$values) {
+
+ $operation_attributes_tags = array_keys($this->operation_tags);
+ $job_attributes_tags = array_keys($this->job_tags);
+ $printer_attributes_tags = array_keys($this->printer_tags);
+ self::unsetAttribute($attribute);
+
+ if (in_array($attribute,$operation_attributes_tags)) {
+ if (!is_array($values))
+ self::_setOperationAttribute ($attribute,$values);
+ else
+ foreach ($values as $value)
+ self::_setOperationAttribute ($attribute,$value);
+
+ } elseif (in_array($attribute,$job_attributes_tags)) {
+ if (!is_array($values))
+ self::_setJobAttribute ($attribute,$values);
+ else
+ foreach ($values as $value)
+ self::_setJobAttribute ($attribute,$value);
+ } elseif (in_array($attribute,$printer_attributes_tags)) {
+ if (!is_array($values))
+ self::_setPrinterAttribute ($attribute,$values);
+ else
+ foreach ($values as $value)
+ self::_setPrinterAttribute ($attribute,$value);
+
+ } else {
+ trigger_error(sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'),$attribute),E_USER_NOTICE);
+ self::_putDebug(sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'),$attribute),3);
+ self::_errorLog(sprintf(_('SetAttribute: Tag "%s" is not a printer or a job attribute'),$attribute),2);
+ return FALSE;
+ }
+
+ }
+ // }}}
+
+ // {{{ unsetAttribute($attribute)
+ public function unsetAttribute($attribute) {
+
+ $operation_attributes_tags = array_keys($this->operation_tags);
+ $job_attributes_tags = array_keys($this->job_tags);
+ $printer_attributes_tags = array_keys($this->printer_tags);
+
+ if (in_array($attribute,$operation_attributes_tags))
+ unset ($this->operation_tags[$attribute]['value'], $this->operation_tags[$attribute]['systag']);
+ elseif (in_array($attribute,$job_attributes_tags))
+ unset ($this->job_tags[$attribute]['value'], $this->job_tags[$attribute]['systag']);
+ elseif (in_array($attribute,$printer_attributes_tags))
+ unset ($this->printer_tags[$attribute]['value'], $this->printer_tags[$attribute]['systag']);
+ else {
+ trigger_error(sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'),$attribute),E_USER_NOTICE);
+ self::_putDebug(sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'),$attribute),3);
+ self::_errorLog(sprintf(_('unsetAttribute: Tag "%s" is not a printer or a job attribute'),$attribute),2);
+ return FALSE;
+ }
+
+ return true;
+ }
+ // }}}
+
+// LOGGING / DEBUGGING
+
+ // {{{ setLog ($log_destination,$destination_type='file',$level=2)
+ public function setLog ($log_destination,$destination_type='file',$level=2) {
+
+ if (is_string($log_destination) && !empty($log_destination))
+ $this->log_destination = $log_destination;
+
+ switch ($destination_type) {
+ case 'file':
+ case 3:
+ $this->log_destination = $log_destination;
+ $this->log_type = 3;
+ break;
+ case 'logger':
+ case 0:
+ $this->log_destination = '';
+ $this->log_type = 0;
+ break;
+ case 'e-mail':
+ case 1:
+ $this->log_destination = $log_destination;
+ $this->log_type = 1;
+ break;
+ }
+ $this->log_level = $level;
+
+ }
+ // }}}
+
+ // {{{ printDebug()
+ public function printDebug() {
+ for ($i = 0 ; $i < $this->debug_count ; $i++)
+ echo $this->debug[$i], "\n";
+ $this->debug = array();
+ $this->debug_count = 0;
+ }
+ // }}}
+
+ // {{{ getDebug()
+ public function getDebug() {
+ $debug = '';
+ for ($i = 0 ; $i < $this->debug_count ; $i++)
+ $debug .= $this->debug[$i];
+ $this->debug = array();
+ $this->debug_count = 0;
+ return $debug;
+ }
+ // }}}
+
+// OPERATIONS
+
+ // {{{ printJob()
+ public function printJob(){
+ // this version of printJob do not parse server output for job's attributes
+
+ self::_putDebug( sprintf("************** Date: %s ***********",
+ date('Y-m-d H:i:s')));
+
+ if (!$this->_stringJob())
+ return FALSE;
+
+ if (is_readable($this->data)){
+ self::_putDebug( _("Printing a FILE"));
+
+ $this->output = $this->stringjob;
+
+ if ($this->setup->datatype == "TEXT")
+ $this->output .= chr(0x16);
+
+
+ $post_values = array( "Content-Type" => "application/ipp",
+ "Data" => $this->output,
+ "File" => $this->data);
+
+ if ($this->setup->datatype == "TEXT" && !isset($this->setup->noFormFeed))
+ $post_values = array_merge($post_values,array("Filetype"=>"TEXT"));
+
+ } else {
+ self::_putDebug( _("Printing DATA"));
+
+ $this->output = $this->stringjob;
+ $this->output .= $this->datahead;
+ $this->output .= $this->data;
+ $this->output .= $this->datatail;
+
+ $post_values = array( "Content-Type" => "application/ipp",
+ "Data" => $this->output);
+
+
+ }
+
+ if (self::_sendHttp ($post_values,$this->paths["printers"]))
+ self::_parseServerOutput();
+
+ if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
+
+ $this->status = array_merge($this->status,array($this->serveroutput->status));
+
+ if ($this->serveroutput->status == "successfull-ok")
+ self::_errorLog(sprintf("printing job %s: ",$this->last_job) .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf("printing job: ",$this->last_job) .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ self::_errorLog("printing job : OPERATION FAILED",1);
+
+ return false;
+ }
+ // }}}
+
+
+/******************
+*
+* PROTECTED FUNCTIONS
+*
+*******************/
+
+// HTTP OUTPUT
+
+ // {{{ _sendHttp ($post_values,$uri)
+ protected function _sendHttp ($post_values,$uri) {
+ /*
+ This function Copyright (C) 2005-2006 Thomas Harding, Manuel Lemos
+ */
+
+ $this->response_completed[] = "no";
+ unset($this->serverouptut);
+
+ self::_putDebug( _("Processing HTTP request"),2);
+
+ $this->serveroutput->headers = array();
+ $this->serveroutput->body = "";
+
+ $http = new http_class;
+ if (!$this->unix)
+ $http->host = $this->host;
+ else
+ $http->host = "localhost";
+ $http->with_exceptions = $this->with_exceptions;
+
+
+ if ($this->debug_http) {
+ $http->debug = 1;
+ $http->html_debug=0;
+ } else {
+ $http->debug=0;
+ $http->html_debug=0;
+ }
+
+ $url="http://".$this->host;
+ if ($this->ssl)
+ $url="https://".$this->host;
+ if ($this->unix)
+ $url="unix://".$this->host;
+
+ $http->port = $this->port;
+ $http->timeout = $this->http_timeout;
+ $http->data_timeout= $this->http_data_timeout;
+
+ $http->force_multipart_form_post = false;
+
+ $http->user = $this->username;
+ $http->password = $this->password;
+
+ $error=$http->GetRequestArguments($url,$arguments);
+ $arguments["RequestMethod"]="POST";
+ $arguments["Headers"] = array("Content-Type" => "application/ipp");
+ $arguments["BodyStream"] = array( array("Data" => $post_values["Data"]) );
+
+ if (isset($post_values["File"]))
+ $arguments["BodyStream"][]=array("File"=>$post_values["File"]);
+ if (isset($post_values["FileType"])
+ && !strcmp($post_values["FileType"],"TEXT"))
+ $arguments["BodyStream"][]=array("Data"=>Chr(12));
+
+ $arguments["RequestURI"] = $uri;
+
+ if ($this->with_exceptions && $this->handle_http_exceptions)
+ {
+ try
+ {
+ $error=$http->Open($arguments);
+ }
+ catch (httpException $e)
+ {
+ throw new ippException(sprintf("http error: %s", $e->getMessage()),$e->getErrno());
+ }
+ }
+ else
+ {
+ $error=$http->Open($arguments);
+ }
+
+ if($error=="") {
+ $error=$http->SendRequest($arguments);
+
+ if($error=="") {
+
+ self::_putDebug( "H T T P R E Q U E S T :");
+ self::_putDebug("Request headers:");
+
+ for(Reset($http->request_headers),$header=0;$header<count($http->request_headers);Next($http->request_headers),$header++) {
+
+ $header_name=Key($http->request_headers);
+ if(GetType($http->request_headers[$header_name])=="array") {
+ for($header_value=0;$header_value<count($http->request_headers[$header_name]);$header_value++)
+ self::_putDebug( $header_name.": ".$http->request_headers[$header_name][$header_value]);
+ } else
+ self::_putDebug( $header_name.": ".$http->request_headers[$header_name]);
+
+ }
+ self::_putDebug( "Request body:");
+ self::_putDebug( htmlspecialchars($http->request_body)
+ ."*********** END REQUEST BODY *********");
+
+
+ $i = 0;
+ $headers=array();
+ unset($this->serveroutput->headers);
+ $error=$http->ReadReplyHeaders($headers);
+
+ self::_putDebug( "H T T P R E S P O N S E :");
+ if($error=="") {
+
+ self::_putDebug("Response headers:");
+ for(Reset($headers),$header=0;$header<count($headers);Next($headers),$header++) {
+ $header_name=Key($headers);
+ if(GetType($headers[$header_name])=="array") {
+ for($header_value=0;$header_value<count($headers[$header_name]);$header_value++) {
+ self::_putDebug( $header_name.": ".$headers[$header_name][$header_value]);
+ $this->serveroutput->headers[$i] = $header_name.": ".$headers[$header_name][$header_value];
+ $i++;
+ }
+ } else {
+ self::_putDebug( $header_name.": ".$headers[$header_name]);
+ $this->serveroutput->headers[$i] = $header_name.": ".$headers[$header_name];
+ $i++;
+ }
+ }
+
+ self::_putDebug( "\n\nResponse body:\n");
+ $this->serveroutput->body = "";
+ for(;;) {
+ $error=$http->ReadReplyBody($body,1024);
+ if($error!="" || strlen($body)==0)
+ break;
+ self::_putDebug(htmlentities($body));
+ $this->serveroutput->body .= $body;
+ }
+ }
+ self::_putDebug( "********* END RESPONSE BODY ********");
+ }
+ }
+ $http->Close();
+ if(strlen($error)) {
+ self::_putDebug($error,4);
+ if ($this->with_exceptions) {
+ $this->serveroutput->status = $error;
+ throw new ippException($error);
+ }
+ trigger_error($error,E_USER_WARNING);
+ $this->serveroutput->status = $error;
+ return FALSE;
+ }
+ return true;
+ }
+ // }}}
+
+// INIT
+
+ // {{{ _initTags ()
+ protected function _initTags () {
+
+ $this->tags_types = array ( "unsupported" => array ("tag" => chr(0x10),
+ "build" => ""),
+ "reserved" => array ("tag" => chr(0x11),
+ "build" => ""),
+ "unknown" => array ("tag" => chr(0x12),
+ "build" => ""),
+ "no-value" => array ("tag" => chr(0x13),
+ "build" => "no_value"),
+ "integer" => array ("tag" => chr(0x21),
+ "build" => "integer"),
+ "boolean" => array ("tag" => chr(0x22),
+ "build" => "boolean"),
+ "enum" => array ("tag" => chr(0x23),
+ "build" => "enum"),
+ "octetString" => array ("tag" => chr(0x30),
+ "build" => "octet_string"),
+ "datetime" => array ("tag" => chr(0x31),
+ "build" => "datetime"),
+ "resolution" => array ("tag" => chr(0x32),
+ "build" => "resolution"),
+ "rangeOfInteger" => array ("tag" => chr(0x33),
+ "build" => "range_of_integers"),
+ "textWithLanguage" => array ("tag" => chr(0x35),
+ "build" => "string"),
+ "nameWithLanguage" => array ("tag" => chr(0x36),
+ "build" => "string"),
+ /*
+ "text" => array ("tag" => chr(0x40),
+ "build" => "string"),
+ "text string" => array ("tag" => chr(0x40),
+ "build" => "string"),
+ */
+ "textWithoutLanguage" => array ("tag" => chr(0x41),
+ "build" => "string"),
+ "nameWithoutLanguage" => array ("tag" => chr(0x42),
+ "buid" => "string"),
+ "keyword" => array ("tag" => chr(0x44),
+ "build" => "string"),
+ "uri" => array ("tag" => chr(0x45),
+ "build" => "string"),
+ "uriScheme" => array ("tag" => chr(0x46),
+ "build" => "string"),
+ "charset" => array ("tag" => chr(0x47),
+ "build" => "string"),
+ "naturalLanguage" => array ("tag" => chr(0x48),
+ "build" => "string"),
+ "mimeMediaType" => array ("tag" => chr(0x49),
+ "build" => "string"),
+ "extendedAttributes" => array ("tag" => chr(0x7F),
+ "build" => "extended"),
+ );
+
+
+ $this->operation_tags = array ("compression" => array("tag" => "keyword"),
+ "document-natural-language" => array("tag" => "naturalLanguage"),
+ "job-k-octets" => array("tag" => "integer"),
+ "job-impressions" => array("tag" => "integer"),
+ "job-media-sheets" => array("tag" => "integer"),
+ );
+
+ $this->job_tags = array ( "job-priority" => array("tag" => "integer"),
+ "job-hold-until" => array("tag" => "keyword"),
+ "job-sheets" => array("tag" => "keyword"), //banner page
+ "multiple-document-handling" => array("tag" => "keyword"),
+ //"copies" => array("tag" => "integer"),
+ "finishings" => array("tag" => "enum"),
+ //"page-ranges" => array("tag" => "rangeOfInteger"), // has its own function
+ //"sides" => array("tag" => "keyword"), // has its own function
+ "number-up" => array("tag" => "integer"),
+ "orientation-requested" => array("tag" => "enum"),
+ "media" => array("tag" => "keyword"),
+ "printer-resolution" => array("tag" => "resolution"),
+ "print-quality" => array("tag" => "enum"),
+ "job-message-from-operator" => array("tag" => "textWithoutLanguage"),
+ );
+
+ $this->printer_tags = array ( "requested-attributes" => array("tag" => "keyword"));
+ }
+ // }}}
+
+// SETUP
+
+ // {{{ _setOperationId ()
+ protected function _setOperationId () {
+ $prepend = '';
+ $this->operation_id += 1;
+ $this->meta->operation_id = self::_integerBuild($this->operation_id);
+ self::_putDebug( "operation id is: ".$this->operation_id,2);
+ }
+ // }}}
+
+ // {{{ _setJobId()
+ protected function _setJobId() {
+
+ $this->meta->jobid +=1;
+ $prepend = '';
+ $prepend_length = 4 - strlen($this->meta->jobid);
+ for ($i = 0; $i < $prepend_length ; $i++ )
+ $prepend .= '0';
+
+ return $prepend.$this->meta->jobid;
+ }
+ // }}}
+
+ // {{{ _setJobUri ($job_uri)
+ protected function _setJobUri ($job_uri) {
+
+ $this->meta->job_uri = chr(0x45) // type uri
+ . chr(0x00).chr(0x07) // name-length
+ . "job-uri"
+ //. chr(0x00).chr(strlen($job_uri))
+ . self::_giveMeStringLength($job_uri)
+ . $job_uri;
+
+ self::_putDebug( "job-uri is: ".$job_uri,2);
+ }
+ // }}}
+
+// RESPONSE PARSING
+
+ // {{{ _parseServerOutput ()
+ protected function _parseServerOutput () {
+
+ $this->serveroutput->response = array();
+
+ if (!self::_parseHttpHeaders ()) return FALSE;
+
+ $this->_parsing->offset = 0;
+
+ self::_parseIppVersion ();
+ self::_parseStatusCode ();
+ self::_parseRequestID ();
+ $this->_parseResponse ();
+
+ //devel
+ self::_putDebug( sprintf("***** IPP STATUS: %s ******",$this->serveroutput->status),4);
+ self::_putDebug( "****** END OF OPERATION ****");
+
+ return true;
+ }
+ // }}}
+
+ // {{{ _parseHttpHeaders
+ protected function _parseHttpHeaders () {
+
+ $response = "";
+
+ switch ($this->serveroutput->headers[0]) {
+
+ case "http/1.1 200 ok: ":
+ $this->serveroutput->httpstatus = "HTTP/1.1 200 OK";
+ $response = "OK";
+ break;
+ case "http/1.1 100 continue: ":
+ $this->serveroutput->httpstatus = "HTTP/1.1 100 CONTINUE";
+ $response = "OK";
+ break;
+ case "":
+ $this->serveroutput->httpstatus = "HTTP/1.1 000 No Response From Server";
+ $this->serveroutput->status = "HTTP-ERROR-000_NO_RESPONSE_FROM_SERVER";
+ trigger_error("No Response From Server",E_USER_WARNING);
+ self::_errorLog("No Response From Server",1);
+ $this->disconnected = 1;
+ return FALSE;
+ break;
+ default:
+ $server_response = preg_replace("/: $/",'',$this->serveroutput->headers[0]);
+ $strings = split(' ',$server_response,3);
+ $errno = $strings[1];
+ $string = strtoupper(str_replace(' ','_',$strings[2]));
+ trigger_error(sprintf(_("server responds %s"),$server_response),E_USER_WARNING);
+ self::_errorLog("server responds ".$server_response,1);
+ $this->serveroutput->httpstatus = strtoupper($strings[0])." ".$errno." ".ucfirst($strings[2]);
+ $this->serveroutput->status = "HTTP-ERROR-".$errno."-".$string;
+ $this->disconnected = 1;
+ return FALSE;
+ break;
+ }
+
+ unset ($this->serveroutput->headers);
+
+ return TRUE;
+ }
+ // }}}
+
+ // {{{ _parseIppVersion ()
+ protected function _parseIppVersion () {
+
+ $ippversion = (ord($this->serveroutput->body[ $this->_parsing->offset]) * 256)
+ + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+
+ switch($ippversion) {
+ case 0x0101:
+ $this->serveroutput->ipp_version = "1.1";
+ break;
+ default:
+ $this->serveroutput->ipp_version = sprintf("%u.%u (Unknown)",ord($this->serveroutput->body[ $this->_parsing->offset]) * 256,ord($this->serveroutput->body[$this->_parsing->offset + 1]));
+ break;
+ }
+
+ self::_putDebug( "I P P R E S P O N S E :\n\n");
+ self::_putDebug( sprintf("IPP version %s%s: %s",
+ ord($this->serveroutput->body[ $this->_parsing->offset]),
+ ord($this->serveroutput->body[$this->_parsing->offset + 1]),
+ $this->serveroutput->ipp_version));
+
+ $this->_parsing->offset += 2;
+ return;
+ }
+ // }}}
+
+ // {{{ _parseStatusCode ()
+ protected function _parseStatusCode () {
+ $status_code = (ord($this->serveroutput->body[$this->_parsing->offset]) * 256)
+ + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+
+
+ $this->serveroutput->status ="NOT PARSED";
+
+ $this->_parsing->offset += 2;
+
+ if (strlen($this->serveroutput->body) < $this->_parsing->offset)
+ return false;
+
+
+ if ($status_code < 0x00FF) {
+ $this->serveroutput->status = "successfull";
+ } elseif ($status_code < 0x01FF) {
+ $this->serveroutput->status = "informational";
+ } elseif ($status_code < 0x02FF) {
+ $this->serveroutput->status = "redirection";
+ } elseif ($status_code < 0x04FF) {
+ $this->serveroutput->status = "client-error";
+ } elseif ($status_code < 0x05FF) {
+ $this->serveroutput->status = "server-error";
+ }
+
+ switch ($status_code) {
+ case 0x0000:
+ $this->serveroutput->status = "successfull-ok";
+ break;
+ case 0x0001:
+ $this->serveroutput->status = "successful-ok-ignored-or-substituted-attributes";
+ break;
+ case 0x002:
+ $this->serveroutput->status = "successful-ok-conflicting-attributes";
+ break;
+ case 0x0400:
+ $this->serveroutput->status = "client-error-bad-request";
+ break;
+ case 0x0401:
+ $this->serveroutput->status = "client-error-forbidden";
+ break;
+ case 0x0402:
+ $this->serveroutput->status = "client-error-not-authenticated";
+ break;
+ case 0x0403:
+ $this->serveroutput->status = "client-error-not-authorized";
+ break;
+ case 0x0404:
+ $this->serveroutput->status = "client-error-not-possible";
+ break;
+ case 0x0405:
+ $this->serveroutput->status = "client-error-timeout";
+ break;
+ case 0x0406:
+ $this->serveroutput->status = "client-error-not-found";
+ break;
+ case 0x0407:
+ $this->serveroutput->status = "client-error-gone";
+ break;
+ case 0x0408:
+ $this->serveroutput->status = "client-error-request-entity-too-large";
+ break;
+ case 0x0409:
+ $this->serveroutput->status = "client-error-request-value-too-long";
+ break;
+ case 0x040A:
+ $this->serveroutput->status = "client-error-document-format-not-supported";
+ break;
+ case 0x040B:
+ $this->serveroutput->status = "client-error-attributes-or-values-not-supported";
+ break;
+ case 0x040C:
+ $this->serveroutput->status = "client-error-uri-scheme-not-supported";
+ break;
+ case 0x040D:
+ $this->serveroutput->status = "client-error-charset-not-supported";
+ break;
+ case 0x040E:
+ $this->serveroutput->status = "client-error-conflicting-attributes";
+ break;
+ case 0x040F:
+ $this->serveroutput->status = "client-error-compression-not-supported";
+ break;
+ case 0x0410:
+ $this->serveroutput->status = "client-error-compression-error";
+ break;
+ case 0x0411:
+ $this->serveroutput->status = "client-error-document-format-error";
+ break;
+ case 0x0412:
+ $this->serveroutput->status = "client-error-document-access-error";
+ break;
+ case 0x0413: // RFC3380
+ $this->serveroutput->status = "client-error-attributes-not-settable";
+ break;
+ case 0x0500:
+ $this->serveroutput->status = "server-error-internal-error";
+ break;
+ case 0x0501:
+ $this->serveroutput->status = "server-error-operation-not-supported";
+ break;
+ case 0x0502:
+ $this->serveroutput->status = "server-error-service-unavailable";
+ break;
+ case 0x0503:
+ $this->serveroutput->status = "server-error-version-not-supported";
+ break;
+ case 0x0504:
+ $this->serveroutput->status = "server-error-device-error";
+ break;
+ case 0x0505:
+ $this->serveroutput->status = "server-error-temporary-error";
+ break;
+ case 0x0506:
+ $this->serveroutput->status = "server-error-not-accepting-jobs";
+ break;
+ case 0x0507:
+ $this->serveroutput->status = "server-error-busy";
+ break;
+ case 0x0508:
+ $this->serveroutput->status = "server-error-job-canceled";
+ break;
+ case 0x0509:
+ $this->serveroutput->status = "server-error-multiple-document-jobs-not-supported";
+ break;
+ default:
+ break;
+ }
+
+
+ self::_putDebug( sprintf("status-code: %s%s: %s ",$this->serveroutput->body[$this->_parsing->offset],
+ $this->serveroutput->body[$this->_parsing->offset + 1],
+ $this->serveroutput->status),4);
+
+ return;
+ }
+ // }}}
+
+ // {{{ _parseRequestID ()
+ protected function _parseRequestID () {
+
+ $this->serveroutput->request_id = self::_interpretInteger(substr($this->serveroutput->body,$this->_parsing->offset,4));
+ self::_putDebug( "request-id ". $this->serveroutput->request_id,2);
+ $this->_parsing->offset += 4;
+
+ return;
+ }
+ // }}}
+
+ // {{{ _interpretInteger($value)
+ protected function _interpretInteger($value) {
+
+ // they are _signed_ integers
+ $value_parsed = 0;
+
+ for ($i = strlen($value) ; $i > 0 ; $i --)
+ $value_parsed += (1 << (($i - 1)*8)) * ord($value[strlen($value) - $i]);
+ if ($value_parsed >= 2147483648)
+ $value_parsed -= 4294967296;
+ return $value_parsed;
+ }
+ // }}}
+
+ // {{{ _parseResponse () {}
+ protected function _parseResponse () {}
+ // }}}
+// REQUEST BUILDING
+
+ // {{{ _stringJob ()
+ protected function _stringJob () {
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+ if (!isset($this->setup->datatype))
+ self::setBinary();
+
+ if (!isset($this->setup->uri)) {
+ $this->getPrinters();
+ unset($this->jobs[count($this->jobs) - 1]);
+ unset($this->jobs_uri[count($this->jobs_uri) - 1]);
+ unset($this->status[count($this->status) - 1]);
+
+ if (array_key_exists(0,$this->available_printers))
+ self::setPrinterURI($this->available_printers[0]);
+ else {
+ trigger_error(_("_stringJob: Printer URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("_stringJob: Printer URI is not set: die"),4);
+ self::_errorLog(" Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->copies))
+ self::setCopies(1);
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->setup->mime_media_type))
+ self::setMimeMediaType();
+ if ($this->setup->datatype != "TEXT")
+ unset ($this->setup->mime_media_type);
+
+ if (!isset($this->setup->jobname))
+ self::setJobName();
+ unset($this->setup->jobname);
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ if (!isset($this->meta->fidelity))
+ $this->meta->fidelity = '';
+
+ if (!isset($this->meta->document_name))
+ $this->meta->document_name = '';
+
+ if (!isset($this->meta->sides))
+ $this->meta->sides = '';
+
+ if (!isset($this->meta->page_ranges))
+ $this->meta->page_ranges = '';
+
+ $jobattributes = '';
+ $operationattributes = '';
+ $printerattributes = '';
+ $this->_buildValues($operationattributes,$jobattributes,$printerattributes);
+ self::_setOperationId();
+
+ if (!isset($this->error_generation->request_body_malformed))
+ $this->error_generation->request_body_malformed = "";
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x02) // Print-Job | operation-id
+ . $this->meta->operation_id // request-id
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . $this->meta->printer_uri
+ . $this->meta->username
+ . $this->meta->jobname
+ . $this->meta->fidelity
+ . $this->meta->document_name
+ . $this->meta->mime_media_type
+ . $operationattributes;
+ if ($this->meta->copies
+ || $this->meta->sides
+ || $this->meta->page_ranges
+ || !empty($jobattributes))
+ {
+ $this->stringjob .= chr(0x02) // start job-attributes | job-attributes-tag
+ . $this->meta->copies
+ . $this->meta->sides
+ . $this->meta->page_ranges
+ . $jobattributes;
+ }
+ $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug( sprintf(_("String sent to the server is: %s"), $this->stringjob));
+ return TRUE;
+ }
+ // }}}
+
+ // {{{ _buildValues (&$operationattributes,&$jobattributes);
+ protected function _buildValues (&$operationattributes,&$jobattributes,&$printerattributes) {
+
+ $operationattributes = '';
+ foreach ($this->operation_tags as $key => $values) {
+ $item = 0;
+ if (array_key_exists('value',$values))
+ foreach ($values['value'] as $item_value) {
+ if ($item == 0)
+ $operationattributes .= $values['systag']
+ . self::_giveMeStringLength($key)
+ . $key
+ . self::_giveMeStringLength($item_value)
+ . $item_value;
+ else
+ $operationattributes .= $values['systag']
+ . self::_giveMeStringLength('')
+ . self::_giveMeStringLength($item_value)
+ . $item_value;
+
+ $item++;
+ }
+ }
+
+ $jobattributes = '';
+ foreach ($this->job_tags as $key => $values)
+ {
+ $item = 0;
+ if (array_key_exists('value',$values))
+ {
+ foreach ($values['value'] as $item_value) {
+ if ($item == 0)
+ $jobattributes .= $values['systag']
+ . self::_giveMeStringLength($key)
+ . $key
+ . self::_giveMeStringLength($item_value)
+ . $item_value;
+ else
+ $jobattributes .= $values['systag']
+ . self::_giveMeStringLength('')
+ . self::_giveMeStringLength($item_value)
+ . $item_value;
+
+ $item++;
+ }
+ }
+ }
+
+ $printerattributes = '';
+ foreach ($this->printer_tags as $key => $values) {
+ $item = 0;
+ if (array_key_exists('value',$values))
+ foreach ($values['value'] as $item_value) {
+ if ($item == 0)
+ $printerattributes .= $values['systag']
+ . self::_giveMeStringLength($key)
+ . $key
+ . self::_giveMeStringLength($item_value)
+ . $item_value;
+ else
+ $printerattributes .= $values['systag']
+ . self::_giveMeStringLength('')
+ . self::_giveMeStringLength($item_value)
+ . $item_value;
+
+ $item++;
+ }
+ }
+
+ reset ($this->job_tags);
+ reset ($this->operation_tags);
+ reset ($this->printer_tags);
+ return true;
+ }
+ // }}}
+
+ // {{{ _giveMeStringLength ($string)
+ protected function _giveMeStringLength ($string) {
+
+ $prepend = '';
+ $length = strlen($string);
+ $lengthlength = strlen(chr($length));
+ while ($lengthlength < 2) {
+ $prepend .= chr(0x00);
+ $lengthlength += 1;
+ }
+ $length = $prepend . chr($length);
+
+ return $length;
+ }
+ // }}}
+
+ // {{{ _enumBuild ($tag,$value)
+ protected function _enumBuild ($tag,$value) {
+
+ switch ($tag) {
+ case "orientation-requested":
+ switch ($value) {
+ case 'portrait':
+ $value = chr(3);
+ break;
+ case 'landscape':
+ $value = chr(4);
+ break;
+ case 'reverse-landscape':
+ $value = chr(5);
+ break;
+ case 'reverse-portrait':
+ $value = chr(6);
+ break;
+ }
+ break;
+ case "print-quality":
+ switch($value) {
+ case 'draft':
+ $value = chr(3);
+ break;
+ case 'normal':
+ $value = chr(4);
+ break;
+ case 'high':
+ $value = chr(5);
+ break;
+ }
+ break;
+ case "finishing":
+ switch ($value) {
+ case 'none':
+ $value = chr(3);
+ break;
+ case 'staple':
+ $value = chr(4);
+ break;
+ case 'punch':
+ $value = chr(5);
+ break;
+ case 'cover':
+ $value = chr(6);
+ break;
+ case 'bind':
+ $value = chr(7);
+ break;
+ case 'saddle-stitch':
+ $value = chr(8);
+ break;
+ case 'edge-stitch':
+ $value = chr(9);
+ break;
+ case 'staple-top-left':
+ $value = chr(20);
+ break;
+ case 'staple-bottom-left':
+ $value = chr(21);
+ break;
+ case 'staple-top-right':
+ $value = chr(22);
+ break;
+ case 'staple-bottom-right':
+ $value = chr(23);
+ break;
+ case 'edge-stitch-left':
+ $value = chr(24);
+ break;
+ case 'edge-stitch-top':
+ $value = chr(25);
+ break;
+ case 'edge-stitch-right':
+ $value = chr(26);
+ break;
+ case 'edge-stitch-bottom':
+ $value = chr(27);
+ break;
+ case 'staple-dual-left':
+ $value = chr(28);
+ break;
+ case 'staple-dual-top':
+ $value = chr(29);
+ break;
+ case 'staple-dual-right':
+ $value = chr(30);
+ break;
+ case 'staple-dual-bottom':
+ $value = chr(31);
+ break;
+ }
+ break;
+ }
+
+ $prepend = '';
+ while ((strlen($value) + strlen($prepend)) < 4)
+ $prepend .= chr(0);
+
+ return $prepend.$value;
+ }
+ // }}}
+
+ // {{{ _integerBuild ($integer)
+ protected function _integerBuild ($value) {
+
+ if ($value >= 2147483647 || $value < -2147483648) {
+ trigger_error(_("Values must be between -2147483648 and 2147483647: assuming '0'"),E_USER_WARNING);
+ return chr(0x00).chr(0x00).chr(0x00).chr(0x00);
+ }
+
+ $initial_value = $value;
+
+ $int1 = $value & 0xFF;
+ $value -= $int1;
+ $value = $value >> 8;
+ $int2 = $value & 0xFF;
+ $value -= $int2;
+ $value = $value >> 8;
+ $int3 = $value & 0xFF;
+ $value -= $int3;
+ $value = $value >> 8;
+ $int4 = $value & 0xFF; //64bits
+
+ if ($initial_value < 0)
+ $int4 = chr($int4) | chr(0x80);
+ else
+ $int4 = chr($int4);
+
+ $value = $int4.chr($int3).chr($int2).chr($int1);
+
+ return $value;
+ }
+ // }}}
+
+ // {{{ _rangeOfIntegerBuild ($integers)
+ protected function _rangeOfIntegerBuild ($integers) {
+
+ $integers = split(":",$integers);
+
+ for ($i = 0 ; $i < 2 ; $i++)
+ $outvalue[$i] = self::_integerBuild($integers[$i]);
+
+ return $outvalue[0].$outvalue[1];
+ }
+ // }}}
+
+ // {{{ _setJobAttribute ($attribute,$value)
+ protected function _setJobAttribute ($attribute,$value) {
+ //used by setAttribute
+
+ $tag_type = $this->job_tags[$attribute]['tag'];
+ switch ($tag_type) {
+ case 'integer':
+ $this->job_tags[$attribute]['value'][] = self::_integerBuild($value);
+ break;
+ case 'nameWithoutLanguage':
+ case 'nameWithLanguage':
+ case 'textWithoutLanguage':
+ case 'textWithLanguage':
+ case 'keyword':
+ case 'naturalLanguage':
+ $this->job_tags[$attribute]['value'][] = $value;
+ break;
+ case 'enum':
+ $value = $this->_enumBuild($attribute,$value); // may be overwritten by children
+ $this->job_tags[$attribute]['value'][] = $value;
+ break;
+ case 'rangeOfInteger':
+ // $value have to be: INT1:INT2 , eg 100:1000
+ $this->job_tags[$attribute]['value'][] = self::_rangeOfIntegerBuild($value);
+ break;
+ case 'resolution':
+ if (preg_match("#dpi#",$value)) $unit = chr(0x3);
+ if (preg_match("#dpc#",$value)) $unit = chr(0x4);
+ $search = array("#(dpi|dpc)#",'#(x|-)#');
+ $replace = array("",":");
+ $value = self::_rangeOfIntegerBuild(preg_replace($search,$replace,$value)).$unit;
+ $this->job_tags[$attribute]['value'][] = $value;
+ break;
+ default:
+ trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute'),$attribute),E_USER_NOTICE);
+ self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute'),$attribute),2);
+ self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute'),$attribute),2);
+ return FALSE;
+ break;
+ }
+ $this->job_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag'];
+
+ }
+ // }}}
+
+ // {{{ _setOperationAttribute ($attribute,$value)
+ protected function _setOperationAttribute ($attribute,$value) {
+ //used by setAttribute
+ $tag_type = $this->operation_tags[$attribute]['tag'];
+ switch ($tag_type) {
+ case 'integer':
+ $this->operation_tags[$attribute]['value'][] = self::_integerBuild($value);
+ break;
+ case 'keyword':
+ case 'naturalLanguage':
+ $this->operation_tags[$attribute]['value'][] = $value;
+ break;
+ default:
+ trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute'),$attribute),E_USER_NOTICE);
+ self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute'),$attribute),2);
+ self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute'),$attribute),2);
+ return FALSE;
+ break;
+ }
+ $this->operation_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag'];
+
+ }
+ // }}}
+
+ // {{{ _setPrinterAttribute ($attribute,$value)
+ protected function _setPrinterAttribute ($attribute,$value) {
+ //used by setAttribute
+ $tag_type = $this->printer_tags[$attribute]['tag'];
+ switch ($tag_type) {
+ case 'integer':
+ $this->printer_tags[$attribute]['value'][] = self::_integerBuild($value);
+ break;
+ case 'keyword':
+ case 'naturalLanguage':
+ $this->printer_tags[$attribute]['value'][] = $value;
+ break;
+ default:
+ trigger_error(sprintf(_('SetAttribute: Tag "%s": cannot set attribute'),$attribute),E_USER_NOTICE);
+ self::_putDebug(sprintf(_('SetAttribute: Tag "%s": cannot set attribute'),$attribute),2);
+ self::_errorLog(sprintf(_('SetAttribute: Tag "%s": cannot set attribute'),$attribute),2);
+ return FALSE;
+ break;
+ }
+ $this->printer_tags[$attribute]['systag'] = $this->tags_types[$tag_type]['tag'];
+
+ }
+ // }}}
+// DEBUGGING
+
+ // {{{ _putDebug($string,$level)
+ protected function _putDebug($string,$level=1) {
+ if ($level === false)
+ return;
+ if ($level < $this->debug_level)
+ return;
+ $this->debug[$this->debug_count] = substr($string,0,1024);
+ $this->debug_count ++;
+ //$this->debug .= substr($string,0,1024);
+ }
+ // }}}
+
+// LOGGING
+
+ // {{{ _errorLog($log,$level)
+ protected function _errorLog($string_to_log,$level) {
+
+ if ($level < $this->log_level)
+ return;
+
+ $string = sprintf('%s : %s:%s user %s : %s',
+ basename($_SERVER['PHP_SELF']),
+ $this->host,
+ $this->port,
+ $this->requesting_user,
+ $string_to_log);
+
+ if ($this->log_type == 0) {
+ error_log($string);
+ return;
+ }
+
+ $string = sprintf("%s %s Host %s:%s user %s : %s\n",
+ date('M d H:i:s'),
+ basename($_SERVER['PHP_SELF']),
+ $this->host,
+ $this->port,
+ $this->requesting_user,
+ $string_to_log);
+ error_log($string,$this->log_type,$this->log_destination);
+
+ return;
+ }
+ // }}}
+
+};
+
+/*
+ * Local variables:
+ * mode: php
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
+?>