diff options
Diffstat (limited to 'Moodle/mod/print/BasicIPP.php')
-rwxr-xr-x | Moodle/mod/print/BasicIPP.php | 1832 |
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: + */ +?> |