<?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:hide@address.com
* 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:
*/
?>