diff --git a/htdocs/commande/fiche.php b/htdocs/commande/fiche.php
index 0fe21564346..52b7761adbe 100644
--- a/htdocs/commande/fiche.php
+++ b/htdocs/commande/fiche.php
@@ -1102,6 +1102,14 @@ else if ($action == 'remove_file')
}
}
+// Print file
+else if ($action == 'print_file' AND $user->rights->printipp->use)
+{
+ require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php';
+ $printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD);
+ $printer->print_file(GETPOST('file',alpha),GETPOST('printer',alpha));
+}
+
/*
* Add file in email form
*/
@@ -2354,8 +2362,9 @@ if ($action == 'send' && ! GETPOST('addfile') && ! GETPOST('removedfile') && ! G
$urlsource=$_SERVER["PHP_SELF"]."?id=".$object->id;
$genallowed=$user->rights->commande->creer;
$delallowed=$user->rights->commande->supprimer;
-
- $somethingshown=$formfile->show_documents('commande',$comref,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang);
+ $printer = false;
+ if ($user->rights->printipp->use AND $conf->printipp->enabled) $printer = true;
+ $somethingshown=$formfile->show_documents('commande',$comref,$filedir,$urlsource,$genallowed,$delallowed,$object->modelpdf,1,0,0,28,0,'','','',$soc->default_lang,$printer);
/*
* Linked object block
diff --git a/htdocs/core/class/dolprintipp.class.php b/htdocs/core/class/dolprintipp.class.php
new file mode 100644
index 00000000000..30ddbfe254a
--- /dev/null
+++ b/htdocs/core/class/dolprintipp.class.php
@@ -0,0 +1,147 @@
+.
+ * or see http://www.gnu.org/
+ */
+
+/**
+ * \file htdocs/core/class/dolprintipp.class.php
+ * \brief A set of functions for using printIPP
+ */
+
+/**
+ * Class to manage printIPP
+ */
+class dolprintIPP
+{
+ var $host;
+ var $port;
+ var $userid;
+ var $user;
+ var $password;
+ var $error;
+ var $db;
+
+
+
+ /**
+ * Constructor
+ *
+ * @param DoliDB $db database
+ * @param string $host host of Cups
+ * @param string $port port
+ * @return printIPP
+ */
+ function __construct($db,$host,$port,$userid,$user,$password)
+ {
+ $this->db=$db;
+ $this->host=$host;
+ $this->port=$port;
+ $this->userid=$userid;
+ $this->user=$user;
+ $this->password=$password;
+ }
+
+
+ /**
+ * Return list of available printers
+ *
+ * @return array list of printers
+ */
+ function getlist_available_printers()
+ {
+ global $conf,$db;
+ include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php';
+ $ipp = new CupsPrintIPP();
+ $ipp->setLog(DOL_DATA_ROOT.'/printipp.log','file',3); // logging very verbose
+ $ipp->setHost($this->host);
+ $ipp->setPort($this->port);
+ $ipp->setUserName($this->userid);
+ //$ipp->setAuthentication($this->user,$this->password);
+ $ipp->getPrinters();
+ return $ipp->available_printers;
+ }
+
+ /**
+ * Print selected file
+ *
+ */
+ function print_file($file,$module)
+ {
+ global $conf,$db;
+ include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php';
+ $ipp = new CupsPrintIPP();
+ $ipp->setLog(DOL_DATA_ROOT.'/printipp.log','file',3); // logging very verbose
+ $ipp->setHost($this->host);
+ $ipp->setPort($this->port);
+ $ipp->setJobName($file,true);
+ $ipp->setUserName($this->userid);
+ //$ipp->setAuthentication($this->user,$this->password);
+ // select printer uri for module order, propal,...
+ $sql = 'SELECT rowid,printer_uri,copy FROM '.MAIN_DB_PREFIX.'printer_ipp WHERE module="'.$module.'"';
+ $result = $this->db->query($sql);
+ if ($result)
+ {
+ $obj = $this->db->fetch_object($result);
+ if ($obj)
+ {
+ $ipp->setPrinterURI($obj->printer_uri);
+ }
+ else
+ {
+ $ipp->setPrinterURI($conf->global->PRINTIPP_URI_DEFAULT);
+ }
+ }
+ $ipp->setCopies($obj->copy);
+ $ipp->setData(DOL_DATA_ROOT.'/'.$module.'/'.$file);
+ $ipp->printJob();
+ }
+
+ /**
+ * List jobs print
+ *
+ */
+ function list_jobs($module)
+ {
+ global $conf,$db;
+ include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php';
+ $ipp = new CupsPrintIPP();
+ $ipp->setLog(DOL_DATA_ROOT.'/printipp.log','file',3); // logging very verbose
+ $ipp->setHost($this->host);
+ $ipp->setPort($this->port);
+ $ipp->setUserName($this->userid);
+ // select printer uri for module order, propal,...
+ $sql = 'SELECT rowid,printer_uri,printer_name FROM '.MAIN_DB_PREFIX.'printer_ipp WHERE module="'.$module.'"';
+ $result = $this->db->query($sql);
+ if ($result)
+ {
+ $obj = $this->db->fetch_object($result);
+ if ($obj)
+ {
+ $ipp->setPrinterURI($obj->printer_uri);
+ }
+ else
+ {
+ // All printers
+ $ipp->setPrinterURI("ipp://localhost:631/printers/");
+ }
+ }
+ echo 'Jobs for : '.$this->userid.' module : '.$module.' Printer : '.$obj->printer_name.'
';
+ echo "Getting Jobs: ".$ipp->getJobs(true,3,"completed",true)."
";
+
+ echo "
";print_r($ipp->jobs_attributes); echo "
";
+ }
+}
+?>
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index 16db9b693a5..eb34a3913ce 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -161,12 +161,13 @@ class FormFile
* @param string $title Title to show on top of form
* @param string $buttonlabel Label on submit button
* @param string $codelang Default language code to use on lang combo box if multilang is enabled
+ * @param boolean $printer Printer Icon
* @return int <0 if KO, number of shown files if OK
*/
- function show_documents($modulepart,$filename,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$maxfilenamelength=28,$noform=0,$param='',$title='',$buttonlabel='',$codelang='')
+ function show_documents($modulepart,$filename,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$maxfilenamelength=28,$noform=0,$param='',$title='',$buttonlabel='',$codelang='',$printer=false)
{
$this->numoffiles=0;
- print $this->showdocuments($modulepart,$filename,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$maxfilenamelength,$noform,$param,$title,$buttonlabel,$codelang);
+ print $this->showdocuments($modulepart,$filename,$filedir,$urlsource,$genallowed,$delallowed,$modelselected,$allowgenifempty,$forcenomultilang,$iconPDF,$maxfilenamelength,$noform,$param,$title,$buttonlabel,$codelang,$printer);
return $this->numoffiles;
}
@@ -190,9 +191,10 @@ class FormFile
* @param string $title Title to show on top of form
* @param string $buttonlabel Label on submit button
* @param string $codelang Default language code to use on lang combo box if multilang is enabled
+ * @param boolean $printer Printer Icon
* @return string Output string with HTML array of documents (might be empty string)
*/
- function showdocuments($modulepart,$filename,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$maxfilenamelength=28,$noform=0,$param='',$title='',$buttonlabel='',$codelang='')
+ function showdocuments($modulepart,$filename,$filedir,$urlsource,$genallowed,$delallowed=0,$modelselected='',$allowgenifempty=1,$forcenomultilang=0,$iconPDF=0,$maxfilenamelength=28,$noform=0,$param='',$title='',$buttonlabel='',$codelang='',$printer)
{
// filedir = conf->...dir_ouput."/".get_exdir(id)
include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
@@ -436,6 +438,8 @@ class FormFile
}
$out.= '';
+ if ($printer) $out.= ' | ';
+
$out.= '';
// Execute hooks
@@ -499,6 +503,14 @@ class FormFile
//$out.= '&urlsource='.urlencode($urlsource); // TODO obsolete ?
$out.= '">'.img_delete().'';
}
+ // Printer Icon
+ if ($printer)
+ {
+ $out.= '';
+ $out.= ' '.img_printer().' | ';
+ }
}
$out.= '';
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index f69d7e25e47..bd61e245715 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -1847,6 +1847,20 @@ function img_delete($alt = 'default', $other = '')
return img_picto($alt, 'delete.png', $other);
}
+/**
+ * Show printer logo
+ *
+ * @param string $alt Text on alt image
+ * @param string $other Add more attributes on img
+ * @return string Retourne tag img
+ */
+function img_printer($alt = "default", $other='')
+{
+ global $conf,$langs;
+ if ($alt=="default") $alt=$langs->trans("Print");
+ return img_picto($alt,'printer.png',$other);
+}
+
/**
* Show help logo with cursor "?"
*
diff --git a/htdocs/core/modules/modPrintIPP.class.php b/htdocs/core/modules/modPrintIPP.class.php
new file mode 100644
index 00000000000..53cadf53699
--- /dev/null
+++ b/htdocs/core/modules/modPrintIPP.class.php
@@ -0,0 +1,145 @@
+.
+ */
+
+/** \defgroup printipp Module printipp
+ * \brief Module pour imprimer via CUPS
+ */
+
+/**
+ * \file htdocs/core/modules/modPrintIPP.class.php
+ * \ingroup printipp
+ * \brief Fichier de description et activation du module OSCommerce2
+ */
+include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php");
+
+
+
+/**
+ * \class modPrintIPP
+ * \brief Classe de description et activation du module PrintIPP
+ */
+class modPrintIPP extends DolibarrModules
+{
+
+ /**
+ * \brief Constructeur. Definit les noms, constantes et boites
+ * \param DB handler d'acces base
+ */
+ function __construct($db)
+ {
+ $this->db = $db ;
+ $this->numero = 54000;
+ // Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
+ // It is used to group modules in module setup page
+ $this->family = "other";
+ // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
+ $this->name = preg_replace('/^mod/i','',get_class($this));
+ $this->description = "Print via Cups IPP Printer.";
+ $this->version = 'experimental'; // 'development' or 'experimental' or 'dolibarr' or version
+ $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
+ // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific)
+ $this->special = 1;
+ // Name of image file used for this module.
+ // If file is in theme/yourtheme/img directory under name object_pictovalue.png, use this->picto='pictovalue'
+ // If file is in module/img directory under name object_pictovalue.png, use this->picto='pictovalue@module'
+ $this->picto = 'technic';
+
+ // Data directories to create when module is enabled.
+ $this->dirs = array();
+
+ // Config pages
+ $this->config_page_url = array("printipp.php@printipp");
+
+ // Dependances
+ $this->depends = array();
+ $this->requiredby = array();
+ $this->phpmin = array(5,1); // Minimum version of PHP required by module
+ $this->need_dolibarr_version = array(3,2); // Minimum version of Dolibarr required by module
+ $this->conflictwith = array();
+ $this->langfiles = array("printipp");
+
+ // Constantes
+ $this->const = array();
+
+ // Boxes
+ $this->boxes = array();
+
+ // Permissions
+ $this->rights = array();
+ $this->rights_class = 'printipp';
+
+ $r=0;
+ // $this->rights[$r][0] Id permission (unique tous modules confondus)
+ // $this->rights[$r][1] Libelle par defaut si traduction de cle "PermissionXXX" non trouvee (XXX = Id permission)
+ // $this->rights[$r][2] Non utilise
+ // $this->rights[$r][3] 1=Permis par defaut, 0=Non permis par defaut
+ // $this->rights[$r][4] Niveau 1 pour nommer permission dans code
+ // $this->rights[$r][5] Niveau 2 pour nommer permission dans code
+
+ $r++;
+ $this->rights[$r][0] = 54001;
+ $this->rights[$r][1] = 'Printer';
+ $this->rights[$r][2] = 'r';
+ $this->rights[$r][3] = 1;
+ $this->rights[$r][4] = 'use';
+
+ // Main menu entries
+ $this->menus = array(); // List of menus to add
+ $r=0;
+
+ // This is to declare the Top Menu entry:
+ $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home', // Put 0 if this is a top menu
+ 'type'=>'left', // This is a Top menu entry
+ 'titre'=>'Printer',
+ 'mainmenu'=>'printer',
+ 'url'=>'/printipp/index.php',
+ 'langs'=>'printipp', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory.
+ 'position'=>100,
+ 'enabled'=>'$conf->printipp->enabled',
+ 'perms'=>'$user->rights->printipp->use', // Use 'perms'=>'1' if you want your menu with no permission rules
+ 'target'=>'',
+ 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both
+
+ $r++;
+
+
+ }
+
+ /**
+ * \brief Fonction appelee lors de l'activation du module. Insere en base les constantes, boites, permissions du module.
+ * Definit egalement les repertoires de donnees a creer pour ce module.
+ */
+ function init()
+ {
+ $sql = array("CREATE TABLE IF NOT EXISTS llx_printer_ipp (rowid int(11) NOT NULL AUTO_INCREMENT,printer_name text NOT NULL, printer_location text NOT NULL,printer_uri varchar(256) NOT NULL,copy int(11) NOT NULL DEFAULT '1',module varchar(16) NOT NULL,login varchar(32) NOT NULL,PRIMARY KEY (rowid)) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;");
+
+ return $this->_init($sql);
+ }
+
+ /**
+ * \brief Fonction appelee lors de la desactivation d'un module.
+ * Supprime de la base les constantes, boites et permissions du module.
+ */
+ function remove()
+ {
+ $sql = array();
+
+ return $this->_remove($sql);
+ }
+
+}
+?>
diff --git a/htdocs/includes/printipp/BasicIPP.php b/htdocs/includes/printipp/BasicIPP.php
new file mode 100644
index 00000000000..3869c75bc06
--- /dev/null
+++ b/htdocs/includes/printipp/BasicIPP.php
@@ -0,0 +1,2000 @@
+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 = 30; // timeout at http connection (seconds) 0 => default => 30.
+ public $http_data_timeout = 30; // 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
+ //
+
+ public function setPort($port = '631')
+ {
+ $this->port = $port;
+ self::_putDebug("Port is " . $this->port, 2);
+ }
+
+ public function setUnix($socket = '/var/run/cups/cups.sock')
+ {
+ $this->host = $socket;
+ $this->unix = true;
+ self::_putDebug("Host is " . $this->host, 2);
+ }
+
+ public function setHost($host = 'localhost')
+ {
+ $this->host = $host;
+ $this->unix = false;
+ self::_putDebug("Host is " . $this->host, 2);
+ }
+
+ public function setTimeout($timeout)
+ {
+ $this->timeout = $timeout;
+ }
+
+ 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;
+ }
+
+ public function setData($data)
+ {
+ $this->data = $data;
+ self::_putDebug("Data set", 2);
+ }
+
+ 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);
+ }
+
+ public function unsetRawText()
+ {
+ $this->setup->datatype = 'BINARY';
+ $this->datahead = '';
+ $this->datatail = '';
+ self::_putDebug(_("Unset forcing data to be interpreted as RAW TEXT") , 2);
+ }
+
+ public function setBinary()
+ {
+ self::unsetRawText();
+ }
+
+ public function setFormFeed()
+ {
+ $this->datatail = "\r\n" . chr(0x0c);
+ unset($this->setup->noFormFeed);
+ }
+
+ public function unsetFormFeed()
+ {
+ $this->datatail = '';
+ $this->setup->noFormFeed = 1;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ public function setDocumentFormat($mime_media_type = 'application/octet-stream')
+ {
+ self::setBinary();
+ $length = chr(strlen($mime_media_type));
+ 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 alias for backward compatibility
+ public function setMimeMediaType($mime_media_type = "application/octet-stream")
+ {
+ self::setDocumentFormat($mime_media_type);
+ }
+
+ 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;
+ }
+
+ 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
+
+ }
+
+ 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;
+ }
+
+ 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"
+ . self::_giveMeStringLength($username) // value-length
+ . $username;
+ self::_putDebug(sprintf(_("Username: %s") , $username) , 2);
+ $this->setup->username = 1;
+ }
+
+ public function setAuthentification($username, $password)
+ {
+ self::setAuthentication($username, $password);
+ }
+
+ public function setAuthentication($username, $password)
+ {
+ $this->password = $password;
+ $this->username = $username;
+ self::_putDebug(_("Setting password") , 2);
+ $this->setup->password = 1;
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+ }
+
+ 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);
+ $page_ranges = preg_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;
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+
+ 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
+ //
+
+ 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;
+ }
+
+ public function printDebug()
+ {
+ for ($i = 0; $i < $this->debug_count; $i++)
+ {
+ echo $this->debug[$i], "\n";
+ }
+ $this->debug = array();
+ $this->debug_count = 0;
+ }
+
+ 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
+ //
+
+ public function printJob()
+ {
+ // this BASIC 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->datahead
+ . $this->data
+ . $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
+ //
+
+ 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
+ {
+ $success = $http->Open($arguments);
+ }
+ catch(httpException $e)
+ {
+ throw new ippException(
+ sprintf("http error: %s", $e->getMessage()),
+ $e->getErrno());
+ }
+ }
+ else
+ {
+ $success = $http->Open($arguments);
+ }
+ if ($success[0] == true)
+ {
+ $success = $http->SendRequest($arguments);
+ if ($success[0] == true)
+ {
+ 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);
+ $http->ReadReplyHeaders($headers);
+ self::_putDebug("H T T P R E S P O N S E :");
+ 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 (;;)
+ {
+ $http->ReadReplyBody($body, 1024);
+ if (strlen($body) == 0) break;
+
+ self::_putDebug(htmlentities($body));
+ $this->serveroutput->body.= $body;
+ }
+ self::_putDebug("********* END RESPONSE BODY ********");
+ }
+ }
+ $http->Close();
+ return true;
+ }
+
+ //
+ // INIT
+ //
+
+ 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
+ //
+
+ 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);
+ }
+
+ 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;
+ }
+
+ 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
+ //
+
+ 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;
+ }
+
+ 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;
+
+ // primitive http/1.0 for Lexmark printers (from Rick Baril)
+ case "http/1.0 200 ok: ":
+ $this->serveroutput->httpstatus = "HTTP/1.0 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);
+ $strings = preg_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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ protected function _parseResponse()
+ {
+ }
+
+ //
+ // REQUEST BUILDING
+ //
+
+ 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 (!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;
+ }
+
+ 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;
+ }
+
+ protected function _giveMeStringLength($string)
+ {
+ $length = strlen($string);
+ if ($length > ((0xFF << 8) + 0xFF) )
+ {
+ $errmsg = sprintf (
+ _('max string length for an ipp meta-information = %d, while here %d'),
+ ((0xFF << 8) + 0xFF), $length);
+
+ if ($this->with_exceptions)
+ {
+ throw new ippException($errmsg);
+ }
+ else
+ {
+ trigger_error ($errmsg, E_USER_ERROR);
+ }
+ }
+ $int1 = $length & 0xFF;
+ $length -= $int1;
+ $length = $length >> 8;
+ $int2 = $length & 0xFF;
+ return chr($int2) . chr($int1);
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ protected function _rangeOfIntegerBuild($integers)
+ {
+ #$integers = split(":", $integers);
+ $integers = preg_split("#:#", $integers);
+ for ($i = 0; $i < 2; $i++) $outvalue[$i] = self::_integerBuild($integers[$i]);
+ return $outvalue[0] . $outvalue[1];
+ }
+
+ 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'];
+ }
+
+ 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'];
+ }
+
+ 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
+ //
+ 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
+ //
+ 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:
+ */
+?>
diff --git a/htdocs/includes/printipp/CupsPrintIPP.php b/htdocs/includes/printipp/CupsPrintIPP.php
new file mode 100644
index 00000000000..a7e5a305da5
--- /dev/null
+++ b/htdocs/includes/printipp/CupsPrintIPP.php
@@ -0,0 +1,671 @@
+jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en');
+
+ self::_setOperationId();
+
+ for($i = 0 ; $i < count($attributes) ; $i++)
+ if ($i == 0)
+ $this->meta->attributes = chr(0x44) // Keyword
+ . self::_giveMeStringLength('requested-attributes')
+ . 'requested-attributes'
+ . self::_giveMeStringLength($attributes[0])
+ . $attributes[0];
+ else
+ $this->meta->attributes .= chr(0x44) // Keyword
+ . chr(0x0).chr(0x0) // zero-length name
+ . self::_giveMeStringLength($attributes[$i])
+ . $attributes[$i];
+
+ $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1
+ . chr(0x40). chr(0x01) // operation: cups vendor extension: get defaults
+ . $this->meta->operation_id // request-id
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . $this->meta->attributes
+ . chr(0x03); // end operations attribute
+
+ $this->output = $this->stringjob;
+
+ self::_putDebug("Request: ".$this->output);
+
+ $post_values = array( "Content-Type" => "application/ipp",
+ "Data" => $this->output);
+
+ if (self::_sendHttp ($post_values,'/')) {
+
+ if(self::_parseServerOutput())
+ self::_parsePrinterAttributes();
+ }
+
+ $this->attributes = &$this->printer_attributes;
+
+ if (isset($this->printer_attributes->printer_type)) {
+ $printer_type = $this->printer_attributes->printer_type->_value0;
+ $table = self::_interpretPrinterType($printer_type);
+
+ for($i = 0 ; $i < count($table) ; $i++ ) {
+ $index = '_value'.$i;
+ $this->printer_attributes->printer_type->$index = $table[$i];
+ }
+
+ }
+
+ 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("getting defaults: ".$this->serveroutput->status,3);
+ else
+ self::_errorLog("getting defaults: ".$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+
+ } else {
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog("getting defaults : OPERATION FAILED",1);
+ }
+ return false;
+ }
+ // }}}
+
+ // {{{ cupsAcceptJobs ($printer_uri)
+ public function cupsAcceptJobs($printer_uri) {
+ //The CUPS-Get-Default operation returns the default printer URI and attributes
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en');
+
+ self::_setOperationId();
+
+ $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1
+ . chr(0x40). chr(0x08) // operation: cups vendor extension: Accept-Jobs
+ . $this->meta->operation_id // request-id
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . chr(0x45) // uri
+ . self::_giveMeStringLength('printer-uri')
+ . 'printer-uri'
+ . self::_giveMeStringLength($printer_uri)
+ . $printer_uri
+ . chr(0x03); // end operations attribute
+
+ $this->output = $this->stringjob;
+
+ self::_putDebug("Request: ".$this->output);
+
+ $post_values = array( "Content-Type" => "application/ipp",
+ "Data" => $this->output);
+
+ if (self::_sendHttp ($post_values,'/admin/')) {
+
+ if(self::_parseServerOutput())
+ self::_parseAttributes();
+ }
+
+ 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("getting defaults: ".$this->serveroutput->status,3);
+ else
+ self::_errorLog("getting defaults: ".$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+
+ } else {
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog("getting defaults : OPERATION FAILED",1);
+ }
+ return false;
+ }
+ // }}}
+
+ // {{{ cupsRejectJobs ($printer_uri,$printer_state_message=false)
+ public function cupsRejectJobs($printer_uri,$printer_state_message) {
+ //The CUPS-Get-Default operation returns the default printer URI and attributes
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ $this->parsed = array();
+ unset($this->attributes);
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en');
+
+ self::_setOperationId();
+
+ $message = "";
+ if ($printer_state_message)
+ $message = chr(0x04) // start printer-attributes
+ . chr(0x41) // textWithoutLanguage
+ . self::_giveMeStringLength("printer-state-message")
+ . "printer-state-message"
+ . self::_giveMeStringLength($printer_state_message)
+ . $printer_state_message;
+
+ $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1
+ . chr(0x40). chr(0x09) // operation: cups vendor extension: Reject-Jobs
+ . $this->meta->operation_id // request-id
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . chr(0x45) // uri
+ . self::_giveMeStringLength('printer-uri')
+ . 'printer-uri'
+ . self::_giveMeStringLength($printer_uri)
+ . $printer_uri
+ . $message
+ . chr(0x03); // end operations attribute
+
+ $this->output = $this->stringjob;
+
+ self::_putDebug("Request: ".$this->output);
+
+ $post_values = array( "Content-Type" => "application/ipp",
+ "Data" => $this->output);
+
+ if (self::_sendHttp ($post_values,'/admin/')) {
+
+ if(self::_parseServerOutput())
+ self::_parseAttributes();
+ }
+
+ 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("getting defaults: ".$this->serveroutput->status,3);
+ else
+ self::_errorLog("getting defaults: ".$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+
+ } else {
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog("getting defaults : OPERATION FAILED",1);
+ }
+ return false;
+ }
+ // }}}
+
+ // {{{ getPrinters()
+ public function getPrinters($printer_location=false,$printer_info=false,$attributes=array()) {
+
+ if (count($attributes) == 0)
+ true;
+ $attributes=array('printer-uri-supported','printer-location','printer-info','printer-type','color-supported');
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+
+ unset ($this->printers_attributes);
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en-us');
+
+ self::_setOperationId();
+
+ $this->meta->attributes='';
+
+ if ($printer_location)
+ $this->meta->attributes .= chr(0x41) // textWithoutLanguage
+ . self::_giveMeStringLength('printer-location')
+ . 'printer-location'
+ . self::_giveMeStringLength($printer_location)
+ . $printer_location;
+
+
+ if ($printer_info)
+ $this->meta->attributes .= chr(0x41) // textWithoutLanguage
+ . self::_giveMeStringLength('printer-info')
+ . 'printer-info'
+ . self::_giveMeStringLength($printer_info)
+ . $printer_info;
+
+ for($i = 0 ; $i < count($attributes) ; $i++)
+ if ($i == 0)
+ $this->meta->attributes .= chr(0x44) // Keyword
+ . self::_giveMeStringLength('requested-attributes')
+ . 'requested-attributes'
+ . self::_giveMeStringLength($attributes[0])
+ . $attributes[0];
+ else
+ $this->meta->attributes .= chr(0x44) // Keyword
+ . chr(0x0).chr(0x0) // zero-length name
+ . self::_giveMeStringLength($attributes[$i])
+ . $attributes[$i];
+
+
+ $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1
+ . chr(0x40). chr(0x02) // operation: cups vendor extension: get printers
+ . $this->meta->operation_id // request-id
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . $this->meta->attributes
+ . chr(0x03); // end operations attribute
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type" => "application/ipp",
+ "Data" => $this->output);
+
+ if (self::_sendHttp ($post_values,'/')) {
+
+ if(self::_parseServerOutput())
+ $this->_getAvailablePrinters();
+
+ }
+
+ 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("getting printers: ".$this->serveroutput->status,3);
+ else
+ self::_errorLog("getting printers: ".$this->serveroutput->status,1);
+ return $this->serveroutput->status;
+
+ } else {
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog("getting printers : OPERATION FAILED",1);
+ }
+ return false;
+ }
+ // }}}
+
+ // {{{ cupsGetPrinters ()
+ public function cupsGetPrinters () {
+ // alias for getPrinters();
+ self::getPrinters();
+ }
+ // }}}
+
+ // {{{ getPrinterAttributes()
+ public function getPrinterAttributes() {
+ // complete informations from parent with Cups-specific stuff
+
+ if(!$result = parent::getPrinterAttributes())
+ return FALSE;
+ if(!isset($this->printer_attributes))
+ return FALSE;
+
+ if (isset ($this->printer_attributes->printer_type)) {
+ $printer_type = $this->printer_attributes->printer_type->_value0;
+ $table = self::_interpretPrinterType($printer_type);
+
+ for($i = 0 ; $i < count($table) ; $i++ ) {
+ $index = '_value'.$i;
+ $this->printer_attributes->printer_type->$index = $table[$i];
+ }
+ }
+
+ return $result;
+ }
+ // }}}
+
+//
+// SETUP
+//
+
+ // {{{ _initTags ()
+ protected function _initTags () {
+
+ // override parent with specific cups attributes
+
+ $operation_tags = array ();
+ $this->operation_tags = array_merge ($this->operation_tags, $operation_tags);
+
+ $job_tags = array ( "job-billing" => array("tag" => "textWithoutLanguage"),
+ "blackplot" => array("tag" => "boolean"),
+ "brightness" => array("tag" => "integer"),
+ "columns" => array("tag" => "integer"),
+ "cpi" => array("tag" => "enum"),
+ "fitplot" => array("tag" => "boolean"),
+ "gamma" => array("tag" => "integer"),
+ "hue" => array("tag" => "integer"),
+ "lpi" => array("tag" => "enum"),
+ "mirror" => array("tag","boolean"),
+ "natural-scaling" => array("tag" => "integer"),
+ "number-up-layout" => array("tag" => "keyword"),
+ "page-border" => array("tag" => "keyword"),
+ "page-bottom" => array("tag" => "integer"),
+ "page-label" => array("tag" => "textWithoutLanguage"),
+ "page-left" => array("tag" => "integer"),
+ "page-right" => array("tag" => "integer"),
+ "page-set" => array("tag" => "keyword"),
+ "page-top" => array("tag" => "integer"),
+ "penwidth" => array("tag" => "integer"),
+ "position" => array("tag" => "keyword"),
+ "ppi" => array("tag" => "integer"),
+ "prettyprint" => array("tag","boolean"),
+ "saturation" => array("tag" => "integer"),
+ "scaling" => array("tag" => "integer"),
+ "wrap" => array("tag","boolean"),
+
+ );
+ $this->job_tags = array_merge ($this->job_tags, $job_tags);
+ }
+ // }}}
+
+//
+// REQUEST BUILDING
+//
+
+ // {{{ _enumBuild ($tag,$value)
+ protected function _enumBuild ($tag,$value) {
+
+ $value_built = parent::_enumBuild($tag,$value);
+
+
+ switch ($tag) {
+ case "cpi":
+ switch ($value) {
+ case '10':
+ $value_built = chr(10);
+ break;
+ case '12':
+ $value_built = chr(12);
+ break;
+ case '17':
+ $value_built = chr(17);
+ break;
+ default:
+ $value_built = chr(10);
+ }
+ break;
+ case "lpi":
+ switch ($value) {
+ case '6':
+ $value_built = chr(6);
+ break;
+ case '8':
+ $value_built = chr(8);
+ break;
+ default:
+ $value_built = chr(6);
+ }
+ break;
+ }
+
+ $prepend = '';
+ while ((strlen($value_built) + strlen($prepend)) < 4)
+ $prepend .= chr(0);
+ return $prepend.$value_built;
+ }
+ // }}}
+
+//
+// RESPONSE PARSING
+//
+
+ // {{{ _getAvailablePrinters ()
+ private function _getAvailablePrinters () {
+
+ $this->available_printers = array();
+ $k = 0;
+ $this->printers_attributes = new stdClass();
+
+ for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++)
+ if (($this->serveroutput->response[$i]['attributes']) == "printer-attributes") {
+ $phpname = "_printer".$k;
+ $this->printers_attributes->$phpname = new stdClass();
+ for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) {
+
+ $value = $this->serveroutput->response[$i][$j]['value'];
+ $name = str_replace("-","_",$this->serveroutput->response[$i][$j]['name']);
+
+ switch ($name) {
+ case "printer_uri_supported":
+ $this->available_printers = array_merge($this->available_printers,array($value));
+ break;
+ case "printer_type":
+ $table = self::_interpretPrinterType($value);
+ $this->printers_attributes->$phpname->$name = new stdClass();
+
+ for($l = 0 ; $l < count($table) ; $l++ ) {
+ $index = '_value'.$l;
+ $this->printers_attributes->$phpname->$name->$index = $table[$l];
+ }
+
+ break;
+ case '':
+ break;
+ default:
+ $this->printers_attributes->$phpname->$name = $value;
+ break;
+ }
+
+ }
+ $k ++;
+ }
+ }
+ // }}}
+
+ // {{{ _getEnumVendorExtensions
+ protected function _getEnumVendorExtensions ($value_parsed) {
+ switch ($value_parsed) {
+ case 0x4002:
+ $value = 'Get-Availables-Printers';
+ break;
+ default:
+ $value = sprintf('Unknown(Cups extension for operations): 0x%x',$value_parsed);
+ break;
+ }
+
+ if (isset($value))
+ return ($value);
+
+ return sprintf('Unknown: 0x%x',$value_parsed);
+ }
+ // }}}
+
+ // {{{ _interpretPrinterType($type)
+ private function _interpretPrinterType($value) {
+ $value_parsed = 0;
+ for ($i = strlen($value) ; $i > 0 ; $i --)
+ $value_parsed += pow(256,($i - 1)) * ord($value[strlen($value) - $i]);
+
+ $type[0] = $type[1] = $type[2] = $type[3] = $type[4] = $type[5] = '';
+ $type[6] = $type[7] = $type[8] = $type[9] = $type[10] = '';
+ $type[11] = $type[12] = $type[13] = $type[14] = $type[15] = '';
+ $type[16] = $type[17] = $type[18] = $type[19] = '';
+
+ if ($value_parsed %2 == 1) {
+ $type[0] = 'printer-class';
+ $value_parsed -= 1;
+ }
+ if ($value_parsed %4 == 2 ) {
+ $type[1] = 'remote-destination';
+ $value_parsed -= 2;
+ }
+ if ($value_parsed %8 == 4 ) {
+ $type[2] = 'print-black';
+ $value_parsed -= 4;
+ }
+ if ($value_parsed %16 == 8 ) {
+ $type[3] = 'print-color';
+ $value_parsed -= 8;
+ }
+ if ($value_parsed %32 == 16) {
+ $type[4] = 'hardware-print-on-both-sides';
+ $value_parsed -= 16;
+ }
+ if ($value_parsed %64 == 32) {
+ $type[5] = 'hardware-staple-output';
+ $value_parsed -= 32;
+ }
+ if ($value_parsed %128 == 64) {
+ $type[6] = 'hardware-fast-copies';
+ $value_parsed -= 64;
+ }
+ if ($value_parsed %256 == 128) {
+ $type[7] = 'hardware-fast-copy-collation';
+ $value_parsed -= 128;
+ }
+ if ($value_parsed %512 == 256) {
+ $type[8] = 'punch-output';
+ $value_parsed -= 256;
+ }
+ if ($value_parsed %1024 == 512) {
+ $type[9] = 'cover-output';
+ $value_parsed -= 512;
+ }
+ if ($value_parsed %2048 == 1024) {
+ $type[10] = 'bind-output';
+ $value_parsed -= 1024;
+ }
+ if ($value_parsed %4096 == 2048) {
+ $type[11] = 'sort-output';
+ $value_parsed -= 2048;
+ }
+ if ($value_parsed %8192 == 4096) {
+ $type[12] = 'handle-media-up-to-US-Legal-A4';
+ $value_parsed -= 4096;
+ }
+ if ($value_parsed %16384 == 8192) {
+ $type[13] = 'handle-media-between-US-Legal-A4-and-ISO_C-A2';
+ $value_parsed -= 8192;
+ }
+ if ($value_parsed %32768 == 16384) {
+ $type[14] = 'handle-media-larger-than-ISO_C-A2';
+ $value_parsed -= 16384;
+ }
+ if ($value_parsed %65536 == 32768) {
+ $type[15] = 'handle-user-defined-media-sizes';
+ $value_parsed -= 32768;
+ }
+ if ($value_parsed %131072 == 65536) {
+ $type[16] = 'implicit-server-generated-class';
+ $value_parsed -= 65536;
+ }
+ if ($value_parsed %262144 == 131072) {
+ $type[17] = 'network-default-printer';
+ $value_parsed -= 131072;
+ }
+ if ($value_parsed %524288 == 262144) {
+ $type[18] = 'fax-device';
+ $value_parsed -= 262144;
+ }
+ return $type;
+ }
+ // }}}
+
+ // {{{ _interpretEnum()
+ protected function _interpretEnum($attribute_name,$value) {
+
+ $value_parsed = self::_interpretInteger($value);
+
+ switch ($attribute_name) {
+ case 'cpi':
+ case 'lpi':
+ $value = $value_parsed;
+ break;
+ default:
+ $value = parent::_interpretEnum($attribute_name,$value);
+ break;
+ }
+
+
+ return $value;
+ }
+ // }}}
+
+};
+
+/*
+ * Local variables:
+ * mode: php
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
+?>
diff --git a/htdocs/includes/printipp/ExtendedPrintIPP.php b/htdocs/includes/printipp/ExtendedPrintIPP.php
new file mode 100644
index 00000000000..e736f4bd972
--- /dev/null
+++ b/htdocs/includes/printipp/ExtendedPrintIPP.php
@@ -0,0 +1,1441 @@
+document_uri = $uri;
+ $this->setup->uri = 1;
+ }
+
+ if(!$this->_stringUri())
+ return FALSE;
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type" => "application/ipp",
+ "Data" => $this->output);
+
+
+ if (self::_sendHttp ($post_values,$this->paths['printers'])) {
+
+ if(self::_parseServerOutput()) {
+ $this->_parseJobAttributes();
+ $this->_getJobId();
+ //$this->_getPrinterUri();
+ $this->_getJobUri();
+ }
+ }
+
+ $this->attributes = &$this->job_attributes;
+
+ 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 uri %s, job %s: ",$uri,$this->last_job)
+ .$this->serveroutput->status,3);
+ else {
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ self::_errorLog(sprintf("printing uri %s: ",$uri,$this->last_job)
+ .$this->serveroutput->status,1);
+ }
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog("printing uri $uri : OPERATION FAILED",1);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ purgeJobs()
+ public function purgeJobs() {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ 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(_("purgeJobs: Printer URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("purgeJobs: Printer URI is not set: die\n"));
+ self::_errorLog("purgeJobs: Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x12) // purge-Jobs | 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
+ . chr(0x22)
+ . self::_giveMeStringLength("purge-jobs")
+ . "purge-jobs"
+ . self::_giveMeStringLength(chr(0x01))
+ . chr(0x01)
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("purging jobs of %s\n"),$this->printer_uri));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['admin'])) {
+ self::_parseServerOutput();
+ self::_parseAttributes();
+ }
+
+
+ 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(_("purging jobs of %s: "),$this->printer_uri)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("purging jobs of %s: "),$this->printer_uri)
+ .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("purging jobs of %s : OPERATION FAILED"),
+ $this->printer_uri),3);
+
+ return false;
+ }
+
+ // }}}
+
+ // {{{ createJob()
+ public function createJob() {
+
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ 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(_("createJob: Printer URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("createJob: Printer URI is not set: die\n"));
+ self::_errorLog("createJob: Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ if (!isset($this->setup->copies))
+ self::setCopies(1);
+
+ if (!isset($this->meta->fidelity))
+ $this->meta->fidelity = '';
+
+ if (!isset($this->meta->sides))
+ $this->meta->sides = '';
+
+ if (!isset($this->meta->page_ranges))
+ $this->meta->page_ranges = '';
+
+ if (!isset($this->setup->jobname))
+ if (is_readable($this->data))
+ self::setJobName(basename($this->data),true);
+ else
+ self::setJobName();
+ unset($this->setup->jobname);
+
+ if (!isset($this->timeout))
+ $this->timeout = 60;
+
+ $timeout = self::_integerBuild($this->timeout);
+
+
+ $this->meta->timeout = chr(0x21) // integer
+ . self::_giveMeStringLength("multiple-operation-time-out")
+ . "multiple-operation-time-out"
+ . self::_giveMeStringLength($timeout)
+ . $timeout;
+
+ $jobattributes = '';
+ $operationattributes = '';
+ $printerattributes = '';
+ self::_buildValues($operationattributes,$jobattributes,$printerattributes);
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x05) // Create-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->timeout
+ . $operationattributes
+ . chr(0x02) // start job-attributes | job-attributes-tag
+ . $this->meta->copies
+ . $this->meta->sides
+ . $this->meta->page_ranges
+ . $jobattributes
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ unset ($this->meta->copies,$this->meta->sides,$this->meta->page_ranges);
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("creating job %s, printer %s\n"),$this->last_job,$this->printer_uri));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['printers']))
+ if(self::_parseServerOutput()) {
+ $this->_getJobId();
+ $this->_getJobUri();
+ $this->_parseJobAttributes();
+ } else {
+ $this->jobs = array_merge($this->jobs,array(''));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(''));
+ }
+
+
+
+
+
+ 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(_("Create job: job %s"),$this->last_job)
+ .$this->serveroutput->status,3);
+ else {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ self::_errorLog(sprintf(_("Create-Job: %s"),$this->serveroutput->status),1);
+ }
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("Creating job on %s : OPERATION FAILED"),
+ $this->printer_uri),3);
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ return false;
+ }
+
+ // }}}
+
+ // {{{ sendDocument($job)
+ public function sendDocument($job,$is_last=false){
+
+ self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
+
+ if (!$this->_stringDocument($job,$is_last))
+ return FALSE;
+
+ if (is_readable($this->data)){
+ self::_putDebug( _("sending Document\n"));
+
+ $this->output = $this->stringjob;
+
+ if ($this->setup->datatype == "TEXT")
+ $this->output .= chr(0x16); // ASCII "SYN"
+
+
+ $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( _("sending DATA as document\n"));
+
+ $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'])) {
+
+ if(self::_parseServerOutput()) {
+ $this->_getJobId();
+ //$this->_getPrinterUri();
+ $this->_getJobUri();
+ $this->_parseJobAttributes();
+ } else {
+ $this->jobs = array_merge($this->jobs,array($job));
+ $this->jobs_uri = array_merge($this->jobs_uri,array($job));
+ }
+
+ }
+
+ 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("sending document, job %s: %s",$job,$this->serveroutput->status),3);
+ else {
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ self::_errorLog(sprintf("sending document, job %s: %s",$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($job));
+ $this->jobs_uri = array_merge($this->jobs_uri,array($job));
+ self::_errorLog(sprintf("sending document, job %s : OPERATION FAILED",$job),1);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ sendURI ($uri,$job,$is_last=false)
+ public function sendURI ($uri,$job,$is_last=false){
+
+ self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
+
+ if (!$this->_stringSendUri($uri,$job,$is_last))
+ return FALSE;
+
+ self::_putDebug( _("sending URI $uri\n"));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type" => "application/ipp",
+ "Data" => $this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['printers'])) {
+
+ if(self::_parseServerOutput()) {
+ $this->_getJobId();
+ //$this->_getPrinterUri();
+ $this->_getJobUri();
+ $this->_parseJobAttributes();
+ } else {
+ $this->jobs = array_merge($this->jobs,array($job));
+ $this->jobs_uri = array_merge($this->jobs_uri,array($job));
+ }
+
+ }
+
+ $this->attributes = &$this->job_attributes;
+
+ 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("sending uri %s, job %s: %s",$uri,$job,$this->serveroutput->status),3);
+ else {
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ self::_errorLog(sprintf("sending uri, job %s: %s",$uri,$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($job));
+ $this->jobs_uri = array_merge($this->jobs_uri,array($job));
+ self::_errorLog(sprintf("sending uri %s, job %s : OPERATION FAILED",$uri,$job),1);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ pausePrinter ()
+ public function pausePrinter() {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ 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(_("pausePrinter: Printer URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("pausePrinter: Printer URI is not set: die\n"));
+ self::_errorLog("pausePrinter: Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x10) // Pause-Printer | 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
+ /* . chr(0x22)
+ . self::_giveMeStringLength("purge-jobs")
+ . "purge-jobs"
+ . self::_giveMeStringLength(chr(0x01))
+ . chr(0x01) */
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("pause printer %s\n"),$this->printer_uri));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['admin'])) {
+ self::_parseServerOutput();
+ self::_parseAttributes();
+ }
+
+
+ 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(_("Pause printer %s: "),$this->printer_uri)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("pause printer %s: "),$this->printer_uri)
+ .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("pause printer %s : OPERATION FAILED"),
+ $this->printer_uri),3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ resumePrinter ()
+ public function resumePrinter() {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ 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(_("resumePrinter: Printer URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("resumePrinter: Printer URI is not set: die\n"));
+ self::_errorLog(" Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x11) // suse-Printer | 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
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("resume printer %s\n"),$this->printer_uri));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['admin'])) {
+ self::_parseServerOutput();
+ self::_parseAttributes();
+ }
+
+
+ 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(_("resume printer %s: "),$this->printer_uri)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("resume printer %s: "),$this->printer_uri)
+ .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("resume printer %s : OPERATION FAILED"),
+ $this->printer_uri),3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ holdJob ($job_uri)
+ public function holdJob ($job_uri,$until='indefinite') {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri)));
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ if (!isset($this->meta->message))
+ $this->meta->message = '';
+
+ self::_setJobUri($job_uri);
+
+ $until_strings = array('no-hold','day-time','evening','night','weekend','second-shift','third-shift');
+ if (in_array($until,$until_strings))
+ true;
+ else
+ $until = 'indefinite';
+
+ $this->meta->job_hold_until = chr(0x42) // keyword
+ . self::_giveMeStringLength('job-hold-until')
+ . 'job-hold-until'
+ . self::_giveMeStringLength($until)
+ . $until;
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x0C) // Hold-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->username
+ . $this->meta->job_uri
+ . $this->meta->message
+ . $this->meta->job_hold_until
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("hold job %s until %s\n"),$job_uri,$until));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['jobs'])) {
+ self::_parseServerOutput();
+ self::_parseAttributes();
+ }
+ 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(_("hold job %s until %s: "),$job_uri,$until)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("hold job %s until %s: "),$job_uri,$until)
+ .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("hold job %s until %s : OPERATION FAILED"),
+ $job_uri,$until),3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ releaseJob ($job_uri)
+ public function releaseJob ($job_uri) {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri)));
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ if (!isset($this->meta->message))
+ $this->meta->message = '';
+
+ self::_setJobUri($job_uri);
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x0D) // Hold-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->job_uri
+ . $this->meta->username
+ . $this->meta->message
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("release job %s\n"),$job_uri));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['jobs'])) {
+ self::_parseServerOutput();
+ self::_parseAttributes();
+ }
+ 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(_("release job %s: "),$job_uri)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("release job %s: "),$job_uri)
+ .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("release job %s: OPERATION FAILED"),
+ $job_uri),3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ restartJob ($job_uri)
+ public function restartJob ($job_uri) {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri)));
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ if (!isset($this->meta->message))
+ $this->meta->message = '';
+
+ self::_setJobUri($job_uri);
+
+
+ $jobattributes = '';
+ $operationattributes = '';
+ $printerattributes = '';
+ self::_buildValues ($operationattributes,$jobattributes,$printerattributes);
+
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x0E) // Hold-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->job_uri
+ . $this->meta->username
+ . $this->meta->message
+ . $jobattributes // job-hold-until is set by setAttribute($attribute,$value)
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("release job %s\n"),$job_uri));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['jobs'])) {
+ self::_parseServerOutput();
+ self::_parseAttributes();
+ }
+
+ 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(_("release job %s: "),$job_uri)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("release job %s: "),$job_uri)
+ .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("release job %s: OPERATION FAILED"),
+ $job_uri),3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ setJobAttributes ($job_uri,$deleted_attributes=array())
+ public function setJobAttributes ($job_uri,$deleted_attributes=array()) {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(trim($job_uri)));
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset ($this->attributes);
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ if (!isset($this->meta->message))
+ $this->meta->message = '';
+
+
+ if (!isset($this->meta->copies))
+ $this->meta->copies = '';
+
+ if (!isset($this->meta->sides))
+ $this->meta->sides = '';
+
+ if (!isset($this->meta->page_ranges))
+ $this->meta->page_ranges = '';
+
+ self::_setJobUri($job_uri);
+
+ $operationattributes = '';
+ $jobattributes = '';
+ $printerattributes = '';
+ self::_buildValues ($operationattributes,$jobattributes,$printerattributes);
+
+ $this->meta->deleted_attributes = "";
+ for ($i = 0 ; $i < count($deleted_attributes) ; $i++)
+ $this->meta->deleted_attributes .= chr(0x16) // out-of-band value
+ . self::_giveMeStringLength($deleted_attributes[$i])
+ . $deleted_attributes[$i]
+ . chr(0x0).chr(0x0); // value-length = 0;
+
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x14) // Set-Job-Attributes | operation-id
+ . $this->meta->operation_id // request-id
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . $this->meta->job_uri
+ . $this->meta->username
+ . $this->meta->message
+ . chr(0x02) // start job-attributes
+ . $jobattributes // setteds by setAttribute($attribute,$value)
+ . $this->meta->copies
+ . $this->meta->sides
+ . $this->meta->page_ranges
+ . $this->meta->deleted_attributes
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("set job attributes for job %s\n"),$job_uri));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['jobs'])) {
+ self::_parseServerOutput();
+ self::_parseAttributes();
+ }
+ 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(_("set job attributes for job %s: "),$job_uri)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("set job attributes for job %s: "),$job_uri)
+ .$this->serveroutput->status,1);
+ $this->last_job = $job_uri;
+ $this->jobs_uri[count($this->jobs_uri) - 1] = $job_uri;
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("set job attributes for job %s: OPERATION FAILED"),
+ $job_uri),3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ setPrinterAttributes ()
+ public function setPrinterAttributes ($document_format='',$deleted_attributes=array()) {
+ /* $document_format (RFC 3380)
+ If the client includes this attribute, the Printer MUST change
+ the supplied attributes for the document format specified by
+ this attribute. If a supplied attribute is a member of the
+ "document-format-varying-attributes" (i.e., the attribute
+ varies by document format, see section 6.3), the Printer MUST
+ change the supplied attribute for the document format specified
+ by this attribute, but not for other document formats. If a
+ supplied attribute isn't a member of the "document-format-
+ varying-attributes" (i.e., it doesn't vary by document format),
+ the Printer MUST change the supplied attribute for all document
+ formats.
+
+ If the client omits this attribute, the Printer MUST change the
+ supplied attributes for all document formats, whether or not
+ they vary by document-format.
+ */
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ unset ($this->attributes);
+
+ self::_setOperationId();
+ $this->parsed = array();
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ if (!isset($this->meta->message))
+ $this->meta->message = '';
+
+ if (!isset($this->meta->copies))
+ $this->meta->copies = '';
+
+ if (!isset($this->meta->sides))
+ $this->meta->sides = '';
+
+ if (!isset($this->meta->page_ranges))
+ $this->meta->page_ranges = '';
+
+ if ($document_format)
+ $document_format = chr(0x49) // document-format tag
+ . self::_giveMeStringLength('document-format')
+ . 'document-format' //
+ . self::_giveMeStringLength($document_format)
+ . $document_format; // value
+
+ $operationattributes = '';
+ $jobattributes = '';
+ $printerattributes = '';
+ self::_buildValues ($operationattributes,$jobattributes,$printerattributes);
+
+ $this->meta->deleted_attributes = "";
+ for ($i = 0 ; $i < count($deleted_attributes) ; $i++)
+ $this->meta->deleted_attributes .= chr(0x16) // out-of-band "deleted" value
+ . self::_giveMeStringLength($deleted_attributes[$i])
+ . $deleted_attributes[$i]
+ . chr(0x0).chr(0x0); // value-length = 0;
+
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x13) // Set-Printer-Attributes | 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->message
+ . $operationattributes
+ . chr(0x02) // start job-attributes
+ . $jobattributes // setteds by setAttribute($attribute,$value)
+ . $this->meta->copies
+ . $this->meta->sides
+ . $this->meta->page_ranges
+ . $this->meta->deleted_attributes
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("set printer attributes for job %s\n"),$this->printer_uri));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['printers'])) {
+ self::_parseServerOutput();
+ self::_parseAttributes();
+ }
+ 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(_("set printer attributes for printer %s: "),$this->printer_uri)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("set printer attributes for printer %s: "),$this->printer_uri)
+ .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("set printer attributes for printer %s: OPERATION FAILED"),
+ $this->printer_uri),1);
+
+ return false;
+
+ }
+ // }}}
+
+// REQUEST BUILDING
+
+ // {{{ _setDocumentUri ($job_uri)
+ protected function _setDocumentUri () {
+
+ $this->meta->document_uri = chr(0x45) // type uri
+ . chr(0x00).chr(0x0c) // name-length
+ . "document-uri"
+ . self::_giveMeStringLength($this->document_uri)
+ . $this->document_uri;
+
+ self::_putDebug( "document uri is: ".$this->document_uri."\n");
+ $this->setup->document_uri = 1;
+
+ }
+ // }}}
+
+ // {{{ _stringUri ()
+ protected function _stringUri () {
+
+ self::_setDocumentUri();
+
+ if (!isset($this->setup->document_uri)) {
+ trigger_error(_("_stringUri: Document URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("_stringUri: Document URI is not set: die\n"));
+ self::_errorLog("Document URI is not set, die",2);
+ return FALSE;
+ }
+ unset ($this->setup->document_uri);
+
+ if (!isset($this->setup->uri)) {
+ $this->getPrinters();
+ unset($this->jobs[count($this->jobs) - 1]);
+ unset($this->jobs_uri[count($this->jobs) - 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(_("_stringUri: Printer URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("_stringUri: Printer URI is not set: die\n"));
+ self::_errorLog("_stringUri: Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->charset))
+ $this->meta->charset = "";
+ // self::setCharset('us-ascii');
+ if (!isset($this->setup->datatype))
+ self::setBinary();
+ if (!isset($this->setup->uri)) {
+ trigger_error(_("_stringUri: Printer URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("_stringUri: Printer URI is not set: die\n"));
+ 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();
+ unset ($this->setup->mime_media_type);
+
+ if (!isset($this->setup->jobname))
+ if (is_readable($this->data))
+ self::setJobName(basename($this->data),true);
+ else
+ 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 = '';
+ self::_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 (0x03) // Print-URI | operation-id
+ . $this->meta->operation_id // request-id
+ . $this->error_generation->request_body_malformed
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . $this->meta->printer_uri
+ . $this->meta->jobname
+ . $this->meta->username
+ . $this->meta->fidelity
+ . $this->meta->document_name
+ . $this->meta->document_uri
+ . $operationattributes
+ . chr(0x02) // start job-attributes | job-attributes-tag
+ . $this->meta->copies
+ . $this->meta->sides
+ . $this->meta->page_ranges
+ . $jobattributes
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+ return TRUE;
+ }
+ // }}}
+
+ // {{{ _stringDocument ($job,$is_last)
+ protected function _stringDocument ($job,$is_last) {
+
+ if ($is_last == false)
+ $is_last = chr(0x00);
+ else
+ $is_last = chr(0x01);
+
+ 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\n"));
+ self::_errorLog(" Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->copies))
+ $this->meta->copies = "";
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->setup->mime_media_type))
+ $this->meta->mime_media_type = "";
+ if ($this->setup->datatype != "TEXT")
+ unset ($this->setup->mime_media_type);
+
+ 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 = '';
+
+ $operationattributes = '';
+ $jobattributes = '';
+ $printerattributes = '';
+ self::_buildValues($operationattributes,$jobattributes,$printerattributes);
+
+ self::_setOperationId();
+
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x06) // Send-Document | operation-id
+ . $this->meta->operation_id // request-id
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . chr(0x45) // attribute-type: uri
+ . self::_giveMeStringLength("job-uri")
+ . "job-uri"
+ . self::_giveMeStringLength($job)
+ . $job
+ . $this->meta->username
+ . $this->meta->document_name
+ . $this->meta->fidelity
+ . $this->meta->mime_media_type
+ . $operationattributes
+ . chr(0x22) // boolean
+ . self::_giveMeStringLength("last-document")
+ . "last-document"
+ . self::_giveMeStringLength($is_last)
+ . $is_last
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+
+ self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+ return TRUE;
+ }
+ // }}}
+
+ // {{{ _stringSendUri ($uri,$job,$is_last)
+ protected function _stringSendUri ($uri,$job,$is_last) {
+
+ $this->document_uri = $uri;
+ self::_setDocumentUri();
+
+ if (!isset($this->setup->document_uri)) {
+ trigger_error(_("_stringUri: Document URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("_stringUri: Document URI is not set: die\n"));
+ self::_errorLog("Document URI is not set, die",2);
+ return FALSE;
+ }
+ unset ($this->setup->document_uri);
+
+
+ if ($is_last == false)
+ $is_last = chr(0x00);
+ else
+ $is_last = chr(0x01);
+
+ 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\n"));
+ self::_errorLog(" Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->copies))
+ $this->meta->copies = "";
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->setup->mime_media_type))
+ $this->meta->mime_media_type = "";
+ unset ($this->setup->mime_media_type);
+
+ 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 = '';
+
+ $operationattributes = '';
+ $jobattributes = '';
+ $printerattributes = '';
+ self::_buildValues($operationattributes,$jobattributes,$printerattributes);
+
+ self::_setOperationId();
+
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x07) // Send-Uri | operation-id
+ . $this->meta->operation_id // request-id
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . chr(0x45) // attribute-type: uri
+ . self::_giveMeStringLength("job-uri")
+ . "job-uri"
+ . self::_giveMeStringLength($job)
+ . $job
+ . $this->meta->username
+ . $this->meta->document_uri
+ . $this->meta->fidelity
+ . $this->meta->mime_media_type
+ . $operationattributes
+ . chr(0x22) // boolean
+ . self::_giveMeStringLength("last-document")
+ . "last-document"
+ . self::_giveMeStringLength($is_last)
+ . $is_last
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+
+ self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+ return TRUE;
+ }
+ // }}}
+
+};
+
+/*
+ * Local variables:
+ * mode: php
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
+?>
diff --git a/htdocs/includes/printipp/PrintIPP.php b/htdocs/includes/printipp/PrintIPP.php
new file mode 100644
index 00000000000..9ed502c2d11
--- /dev/null
+++ b/htdocs/includes/printipp/PrintIPP.php
@@ -0,0 +1,1889 @@
+_stringJob())
+ return FALSE;
+
+ if (is_readable($this->data)){
+ self::_putDebug( _("Printing a FILE\n"),3);
+
+ $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\n"),3);
+
+ $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'])) {
+
+ if(self::_parseServerOutput()) {
+ $this->_getJobId();
+ $this->_getJobUri();
+ $this->_parseJobAttributes();
+ } else {
+ $this->jobs = array_merge($this->jobs,array(''));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(''));
+ }
+
+ }
+
+ 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
+ {
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+ self::_errorLog(sprintf("printing job: ",$this->last_job) .$this->serveroutput->status,1);
+ if ($this->with_exceptions)
+ {
+ throw new ippException(sprintf("job status: %s",
+ $this->serveroutput->status));
+ }
+ }
+ 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;
+ }
+ // }}}
+
+ // {{{ cancelJob ($job_uri)
+ public function cancelJob ($job_uri) {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+
+ self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
+
+ if (!$this->_stringCancel($job_uri))
+ return FALSE;
+
+ self::_putDebug( _("Cancelling Job $job_uri\n"),3);
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['jobs']))
+ 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("cancelling job $job_uri: ".$this->serveroutput->status,3);
+ else
+ self::_errorLog("cancelling job $job_uri: ".$this->serveroutput->status,1);
+ return $this->serveroutput->status;
+
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog("cancelling job : OPERATION FAILED",3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ validateJob ()
+ public function validateJob () {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+
+ $this->serveroutput->response = '';
+
+ self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s')));
+
+
+ self::_putDebug( _("Validate Job\n"),2);
+
+ 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\n"),3);
+ self::_errorLog(" Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->meta->copies))
+ self::setCopies(1);
+ 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))
+ if (is_readable($this->data))
+ self::setJobName(basename($this->data),true);
+ else
+ 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 = '';
+ self::_buildValues ($operationattributes,$jobattributes,$printerattributes);
+
+ self::_setOperationId();
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x04) // Validate-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
+ . chr(0x02) // start job-attributes | job-attributes-tag
+ . $this->meta->copies
+ . $this->meta->sides
+ . $this->meta->page_ranges
+ . $jobattributes
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+
+ self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['printers']))
+ if(self::_parseServerOutput())
+ self::_parseAttributes();
+
+
+ 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("validate job: ".$this->serveroutput->status,3);
+ else
+ self::_errorLog("validate job: ".$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog("validate job : OPERATION FAILED",3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ getPrinterAttributes()
+ public function getPrinterAttributes() {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+
+ $jobattributes = '';
+ $operationattributes = '';
+ self::_buildValues($operationattributes,$jobattributes,$printerattributes);
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ 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\n"),3);
+ self::_errorLog(" Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x0b) // Print-URI | 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
+ . $printerattributes
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("Getting printer attributes of %s\n"),$this->printer_uri),2);
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['root']))
+ if (self::_parseServerOutput())
+ self::_parsePrinterAttributes();
+
+ $this->attributes = &$this->printer_attributes;
+
+ 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(_("getting printer attributes of %s: %s"),$this->printer_uri,
+ $this->serveroutput->status),3);
+ else
+ self::_errorLog(sprintf(_("getting printer attributes of %s: %s"),$this->printer_uri,
+ $this->serveroutput->status),1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("getting printer's attributes of %s : OPERATION FAILED"),
+ $this->printer_uri),3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ getJobs ($my_jobs=true,$limit=0,$which_jobs="");
+ public function getJobs($my_jobs=true,$limit=0,$which_jobs="not-completed",$subset=false) {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ 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(_("getJobs: Printer URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
+ self::_errorLog("getJobs: Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ if ($limit) {
+ $limit = self::_integerBuild($limit);
+ $this->meta->limit = chr(0x21) // integer
+ . self::_giveMeStringLength('limit')
+ . 'limit'
+ . self::_giveMeStringLength($limit)
+ . $limit;
+ } else
+ $this->meta->limit = '';
+
+ if ($which_jobs == 'completed')
+ $this->meta->which_jobs = chr(0x44) // keyword
+ . self::_giveMeStringLength('which-jobs')
+ . 'which-jobs'
+ . self::_giveMeStringLength($which_jobs)
+ . $which_jobs;
+ else
+ $this->meta->which_jobs = "";
+
+ if ($my_jobs)
+ $this->meta->my_jobs = chr(0x22) // boolean
+ . self::_giveMeStringLength('my-jobs')
+ . 'my-jobs'
+ . self::_giveMeStringLength(chr(0x01))
+ . chr(0x01);
+ else
+ $this->meta->my_jobs = '';
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x0A) // Get-Jobs | 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->limit
+ . $this->meta->which_jobs
+ . $this->meta->my_jobs
+ ;
+ if ($subset) {
+ $this->stringjob .=
+ chr(0x44) // keyword
+ . self::_giveMeStringLength('requested-attributes')
+ . 'requested-attributes'
+ . self::_giveMeStringLength('job-uri')
+ . 'job-uri'
+ . chr(0x44) // keyword
+ . self::_giveMeStringLength('')
+ . ''
+ . self::_giveMeStringLength('job-name')
+ . 'job-name'
+ . chr(0x44) // keyword
+ . self::_giveMeStringLength('')
+ . ''
+ . self::_giveMeStringLength('job-state')
+ . 'job-state'
+ . chr(0x44) // keyword
+ . self::_giveMeStringLength('')
+ . ''
+ . self::_giveMeStringLength('job-state-reason')
+ . 'job-state-reason'
+ ;
+ }
+ else { # cups 1.4.4 doesn't return much of anything without this
+ $this->stringjob .=
+ chr(0x44) // keyword
+ . self::_giveMeStringLength('requested-attributes')
+ . 'requested-attributes'
+ . self::_giveMeStringLength('all')
+ . 'all'
+ ;
+ }
+ $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2);
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['jobs']))
+ if (self::_parseServerOutput())
+ self::_parseJobsAttributes();
+
+ $this->attributes = &$this->jobs_attributes;
+
+
+ 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(_("getting jobs of printer %s: "),$this->printer_uri)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("getting jobs of printer %s: "),$this->printer_uri)
+ .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("getting jobs of %s : OPERATION FAILED"),
+ $this->printer_uri),3);
+
+ return false;
+ }
+ // }}}
+
+ // {{{ getJobAttributes ($job_uri,subset="false",$attributes_group="all");
+ public function getJobAttributes($job_uri,$subset=false,$attributes_group="all") {
+
+ $this->jobs = array_merge($this->jobs,array(""));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(""));
+
+ if (!$job_uri) {
+ trigger_error(_("getJobAttributes: Job URI is not set, die."));
+ return FALSE;
+ }
+
+ self::_setOperationId();
+ $this->parsed = array();
+ unset($this->printer_attributes);
+
+ 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(_("getJobs: Printer URI is not set: die"),E_USER_WARNING);
+ self::_putDebug( _("_stringJob: Printer URI is not set: die\n"),3);
+ self::_errorLog("getJobs: Printer URI is not set, die",2);
+ return FALSE;
+ }
+ }
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+
+ if (!isset($this->meta->username))
+ self::setUserName();
+
+ $this->meta->job_uri = chr(0x45) // URI
+ . self::_giveMeStringLength('job-uri')
+ . 'job-uri'
+ . self::_giveMeStringLength($job_uri)
+ . $job_uri;
+
+ $this->stringjob = chr(0x01) . chr(0x01) // 1.1 | version-number
+ . chr(0x00) . chr (0x09) // Get-Job-Attributes | operation-id
+ . $this->meta->operation_id // request-id
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . $this->meta->job_uri
+ . $this->meta->username
+ ;
+ if ($subset)
+ $this->stringjob .=
+ chr(0x44) // keyword
+ . self::_giveMeStringLength('requested-attributes')
+ . 'requested-attributes'
+ . self::_giveMeStringLength('job-uri')
+ . 'job-uri'
+ . chr(0x44) // keyword
+ . self::_giveMeStringLength('')
+ . ''
+ . self::_giveMeStringLength('job-name')
+ . 'job-name'
+ . chr(0x44) // keyword
+ . self::_giveMeStringLength('')
+ . ''
+ . self::_giveMeStringLength('job-state')
+ . 'job-state'
+ . chr(0x44) // keyword
+ . self::_giveMeStringLength('')
+ . ''
+ . self::_giveMeStringLength('job-state-reason')
+ . 'job-state-reason'
+ ;
+ elseif($attributes_group) {
+ switch($attributes_group) {
+ case 'job-template':
+ break;
+ case 'job-description':
+ break;
+ case 'all':
+ break;
+ default:
+ trigger_error(_('not a valid attribute group: ').$attributes_group,E_USER_NOTICE);
+ $attributes_group = '';
+ break;
+ }
+ $this->stringjob .=
+ chr(0x44) // keyword
+ . self::_giveMeStringLength('requested-attributes')
+ . 'requested-attributes'
+ . self::_giveMeStringLength($attributes_group)
+ . $attributes_group;
+ }
+ $this->stringjob .= chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug(sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+
+ self::_putDebug(sprintf(_("getting jobs of %s\n"),$this->printer_uri),2);
+
+ $this->output = $this->stringjob;
+
+ $post_values = array( "Content-Type"=>"application/ipp",
+ "Data"=>$this->output);
+
+ if (self::_sendHttp ($post_values,$this->paths['jobs']))
+ if (self::_parseServerOutput())
+ self::_parseJobAttributes();
+
+ $this->attributes = &$this->job_attributes;
+
+ 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(_("getting job attributes for %s: "),$job_uri)
+ .$this->serveroutput->status,3);
+ else
+ self::_errorLog(sprintf(_("getting job attributes for %s: "),$job_uri)
+ .$this->serveroutput->status,1);
+
+ return $this->serveroutput->status;
+ }
+
+ $this->status = array_merge($this->status,array("OPERATION FAILED"));
+ self::_errorLog(date("Y-m-d H:i:s : ")
+ .basename($_SERVER['PHP_SELF'])
+ .sprintf(_("getting jobs attributes of %s : OPERATION FAILED"),
+ $job_uri),3);
+
+ return false;
+ }
+
+ // }}}
+
+ // {{{ getPrinters();
+ public function getPrinters() {
+
+ // placeholder for vendor extension operation (getAvailablePrinters for CUPS)
+ $this->jobs = array_merge($this->jobs,array(''));
+ $this->jobs_uri = array_merge($this->jobs_uri,array(''));
+ $this->status = array_merge($this->status,array(''));
+ }
+ // }}}
+
+/******************
+*
+* DEVELOPPEMENT FUNCTIONS
+*
+*******************/
+
+ // {{{ generateError($error)
+ public function generateError ($error) {
+ switch ($error) {
+ case "request_body_malformed":
+ $this->error_generation->request_body_malformed = chr(0xFF);
+ break;
+ default:
+ true;
+ break;
+ }
+ // }}}
+
+ // {{{ resetError ($error)
+ trigger_error(sprintf(_('Setting Error %s'),$error),E_USER_NOTICE);
+ }
+
+ public function resetError ($error) {
+ unset ($this->error_generation->$error);
+ trigger_error(sprintf(_('Reset Error %s'),$error),E_USER_NOTICE);
+ }
+ // }}}
+
+/******************
+*
+* PROTECTED FUNCTIONS
+*
+*******************/
+
+// 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."\n",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."\n",2);
+ }
+ // }}}
+
+// RESPONSE PARSING
+
+ // {{{ _parsePrinterAttributes()
+ protected function _parsePrinterAttributes() {
+
+ //if (!preg_match('#successful#',$this->serveroutput->status))
+ // return false;
+
+ $k = -1;
+ for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
+ for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
+ if (!empty($this->serveroutput->response[$i][$j]['name'])) {
+ $k++;
+ $l = 0;
+ $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes'];
+ $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
+ $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
+ $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
+ } else {
+ $l ++;
+ $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
+ }
+ $this->serveroutput->response = array();
+
+ $this->printer_attributes = new stdClass();
+ for ($i = 0 ; $i < count($this->parsed) ; $i ++) {
+ $name = $this->parsed[$i]['name'];
+ $php_name = str_replace('-','_',$name);
+ $type = $this->parsed[$i]['type'];
+ $range = $this->parsed[$i]['range'];
+ $this->printer_attributes->$php_name = new stdClass();
+ $this->printer_attributes->$php_name->_type = $type;
+ $this->printer_attributes->$php_name->_range = $range;
+ for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) {
+ $value = $this->parsed[$i][$j];
+ $index = '_value'.$j;
+ $this->printer_attributes->$php_name->$index = $value;
+ }
+ }
+
+ $this->parsed = array();
+
+
+ }
+ // }}}
+
+ // {{{ _parseJobsAttributes()
+ protected function _parseJobsAttributes() {
+
+ //if ($this->serveroutput->status != "successfull-ok")
+ // return false;
+
+ $job = -1;
+ for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) {
+ if ($this->serveroutput->response[$i]['attributes'] == "job-attributes")
+ $job ++;
+ $k = -1;
+ for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
+ if (!empty($this->serveroutput->response[$i][$j]['name'])) {
+ $k++;
+ $l = 0;
+ $this->parsed[$job][$k]['range'] = $this->serveroutput->response[$i]['attributes'];
+ $this->parsed[$job][$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
+ $this->parsed[$job][$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
+ $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value'];
+ } else {
+ $l ++;
+ $this->parsed[$job][$k][$l] = $this->serveroutput->response[$i][$j]['value'];
+ }
+ }
+
+ $this->serveroutput->response = array();
+ $this->jobs_attributes = new stdClass();
+ for ($job_nbr = 0 ; $job_nbr <= $job ; $job_nbr ++) {
+ $job_index = "job_".$job_nbr;
+ $this->jobs_attributes->$job_index = new stdClass();
+ for ($i = 0 ; $i < count($this->parsed[$job_nbr]) ; $i ++) {
+ $name = $this->parsed[$job_nbr][$i]['name'];
+ $php_name = str_replace('-','_',$name);
+ $type = $this->parsed[$job_nbr][$i]['type'];
+ $range = $this->parsed[$job_nbr][$i]['range'];
+ $this->jobs_attributes->$job_index->$php_name = new stdClass();
+ $this->jobs_attributes->$job_index->$php_name->_type = $type;
+ $this->jobs_attributes->$job_index->$php_name->_range = $range;
+ for ($j = 0 ; $j < (count($this->parsed[$job_nbr][$i]) - 3) ; $j ++) {
+ # This causes incorrect parsing of integer job attributes.
+ # 2010-08-16
+ # bpkroth
+ #$value = self::_interpretAttribute($name,$type,$this->parsed[$job_nbr][$i][$j]);
+ $value = $this->parsed[$job_nbr][$i][$j];
+ $index = '_value'.$j;
+ $this->jobs_attributes->$job_index->$php_name->$index = $value;
+ }
+ }
+ }
+
+ $this->parsed = array();
+
+
+ }
+ // }}}
+
+ // {{{ _readAttribute($attributes_type,$ji,&$collection=false)
+ protected function _readAttribute($attributes_type) {
+
+ $tag = ord($this->serveroutput->body[$this->_parsing->offset]);
+
+ $this->_parsing->offset += 1;
+ $j = $this->index;
+
+ $tag = self::_readTag($tag);
+
+ switch ($tag) {
+ case "begCollection": //RFC3382 (BLIND CODE)
+ if ($this->end_collection)
+ $this->index --;
+ $this->end_collection = false;
+ $this->serveroutput->response[$attributes_type][$j]['type'] = "collection";
+ self::_putDebug( "tag is: begCollection\n");
+ self::_readAttributeName ($attributes_type,$j);
+ if (!$this->serveroutput->response[$attributes_type][$j]['name']) { // it is a multi-valued collection
+ $this->collection_depth ++;
+ $this->index --;
+ $this->collection_nbr[$this->collection_depth] ++;
+ } else {
+ $this->collection_depth ++;
+ if ($this->collection_depth == 0)
+ $this->collection = (object) 'collection';
+ if (array_key_exists($this->collection_depth,$this->collection_nbr))
+ $this->collection_nbr[$this->collection_depth] ++;
+ else
+ $this->collection_nbr[$this->collection_depth] = 0;
+ unset($this->end_collection);
+
+ }
+ self::_readValue ("begCollection",$attributes_type,$j);
+ break;
+ case "endCollection": //RFC3382 (BLIND CODE)
+ $this->serveroutput->response[$attributes_type][$j]['type'] = "collection";
+ self::_putDebug( "tag is: endCollection\n");
+ self::_readAttributeName ($attributes_type,$j,0);
+ self::_readValue ('name',$attributes_type,$j,0);
+ $this->collection_depth --;
+ $this->collection_key[$this->collection_depth] = 0;
+ $this->end_collection = true;
+ break;
+ case "memberAttrName": // RFC3382 (BLIND CODE)
+ $this->serveroutput->response[$attributes_type][$j]['type'] = "memberAttrName";
+ $this->index -- ;
+ self::_putDebug( "tag is: memberAttrName\n");
+ self::_readCollection ($attributes_type,$j);
+ break;
+
+ default:
+ $this->collection_depth = -1;
+ $this->collection_key = array();
+ $this->collection_nbr = array();
+ $this->serveroutput->response[$attributes_type][$j]['type'] = $tag;
+ self::_putDebug( "tag is: $tag\n");
+ $attribute_name = self::_readAttributeName ($attributes_type,$j);
+ if (!$attribute_name)
+ $attribute_name = $this->attribute_name;
+ else
+ $this->attribute_name = $attribute_name;
+ $value = self::_readValue ($tag,$attributes_type,$j);
+ $this->serveroutput->response[$attributes_type][$j]['value'] =
+ self::_interpretAttribute($attribute_name,$tag,$this->serveroutput->response[$attributes_type][$j]['value']);
+ break;
+
+ }
+ return;
+ }
+ // }}}
+
+ // {{{ _readTag($tag)
+ protected function _readTag($tag) {
+
+ switch ($tag) {
+ case 0x10:
+ $tag = "unsupported";
+ break;
+ case 0x11:
+ $tag = "reserved for 'default'";
+ break;
+ case 0x12:
+ $tag = "unknown";
+ break;
+ case 0x13:
+ $tag = "no-value";
+ break;
+ case 0x15: // RFC 3380
+ $tag = "not-settable";
+ break;
+ case 0x16: // RFC 3380
+ $tag = "delete-attribute";
+ break;
+ case 0x17: // RFC 3380
+ $tag = "admin-define";
+ break;
+ case 0x20:
+ $tag = "IETF reserved (generic integer)";
+ break;
+ case 0x21:
+ $tag = "integer";
+ break;
+ case 0x22:
+ $tag = "boolean";
+ break;
+ case 0x23:
+ $tag = "enum";
+ break;
+ case 0x30:
+ $tag = "octetString";
+ break;
+ case 0x31:
+ $tag = "datetime";
+ break;
+ case 0x32:
+ $tag = "resolution";
+ break;
+ case 0x33:
+ $tag = "rangeOfInteger";
+ break;
+ case 0x34: //RFC3382 (BLIND CODE)
+ $tag = "begCollection";
+ break;
+ case 0x35:
+ $tag = "textWithLanguage";
+ break;
+ case 0x36:
+ $tag = "nameWithLanguage";
+ break;
+ case 0x37: //RFC3382 (BLIND CODE)
+ $tag = "endCollection";
+ break;
+ case 0x40:
+ $tag = "IETF reserved text string";
+ break;
+ case 0x41:
+ $tag = "textWithoutLanguage";
+ break;
+ case 0x42:
+ $tag = "nameWithoutLanguage";
+ break;
+ case 0x43:
+ $tag = "IETF reserved for future";
+ break;
+ case 0x44:
+ $tag = "keyword";
+ break;
+ case 0x45:
+ $tag = "uri";
+ break;
+ case 0x46:
+ $tag = "uriScheme";
+ break;
+ case 0x47:
+ $tag = "charset";
+ break;
+ case 0x48:
+ $tag = "naturalLanguage";
+ break;
+ case 0x49:
+ $tag = "mimeMediaType";
+ break;
+ case 0x4A: // RFC3382 (BLIND CODE)
+ $tag = "memberAttrName";
+ break;
+ case 0x7F:
+ $tag = "extended type";
+ break;
+ default:
+
+ if ($tag >= 0x14 && $tag < 0x15 && $tag > 0x17 && $tag <= 0x1f)
+ $tag = "out-of-band";
+ elseif (0x24 <= $tag && $tag <= 0x2f)
+ $tag = "new integer type";
+ elseif (0x38 <= $tag && $tag <= 0x3F)
+ $tag = "new octet-stream type";
+ elseif (0x4B <= $tag && $tag <= 0x5F)
+ $tag = "new character string type";
+ elseif ((0x60 <= $tag && $tag < 0x7f) || $tag >= 0x80 )
+ $tag = "IETF reserved for future";
+ else
+ $tag = sprintf("UNKNOWN: 0x%x (%u)",$tag,$tag);
+
+ break;
+ }
+ return $tag;
+ }
+ // }}}
+
+ // {{{ _readCollection($attributes_type,$j,&$collection)
+ protected function _readCollection($attributes_type,$j) {
+
+ $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
+ + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+
+ $this->_parsing->offset += 2;
+
+ self::_putDebug( "Collection name_length ". $name_length ."\n");
+
+ $name = '';
+ for ($i = 0; $i < $name_length; $i++) {
+ $name .= $this->serveroutput->body[$this->_parsing->offset];
+ $this->_parsing->offset += 1;
+ if ($this->_parsing->offset > strlen($this->serveroutput->body))
+ return;
+ }
+
+ $collection_name = $name;
+
+ $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
+ + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+ $this->_parsing->offset += 2;
+
+ self::_putDebug( "Attribute name_length ". $name_length ."\n");
+
+ $name = '';
+ for ($i = 0; $i < $name_length; $i++) {
+ $name .= $this->serveroutput->body[$this->_parsing->offset];
+ $this->_parsing->offset += 1;
+ if ($this->_parsing->offset > strlen($this->serveroutput->body))
+ return;
+ }
+
+ $attribute_name = $name;
+ if ($attribute_name == "") {
+ $attribute_name = $this->last_attribute_name;
+ $this->collection_key[$this->collection_depth] ++;
+ } else {
+ $this->collection_key[$this->collection_depth] = 0;
+ }
+ $this->last_attribute_name = $attribute_name;
+
+ self::_putDebug( "Attribute name ".$name."\n");
+
+ $tag = self::_readTag(ord($this->serveroutput->body[$this->_parsing->offset]));
+ $this->_parsing->offset ++;
+
+ $type = $tag;
+
+ $name_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
+ + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+ $this->_parsing->offset += 2;
+
+ self::_putDebug( "Collection2 name_length ". $name_length ."\n");
+
+ $name = '';
+ for ($i = 0; $i < $name_length; $i++) {
+ $name .= $this->serveroutput->body[$this->_parsing->offset];
+ $this->_parsing->offset += 1;
+ if ($this->_parsing->offset > strlen($this->serveroutput->body))
+ return;
+ }
+
+ $collection_value = $name;
+ $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
+ + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+
+ self::_putDebug( "Collection value_length ".$this->serveroutput->body[ $this->_parsing->offset]
+ . $this->serveroutput->body[$this->_parsing->offset + 1]
+ .": "
+ . $value_length
+ . " ");
+
+ $this->_parsing->offset += 2;
+
+ $value = '';
+ for ($i = 0; $i < $value_length; $i++) {
+
+ if ($this->_parsing->offset >= strlen($this->serveroutput->body))
+ return;
+ $value .= $this->serveroutput->body[$this->_parsing->offset];
+ $this->_parsing->offset += 1;
+
+ }
+
+ $object = &$this->collection;
+ for ($i = 0 ; $i <= $this->collection_depth ; $i ++) {
+ $indice = "_indice".$this->collection_nbr[$i];
+ if (!isset($object->$indice))
+ $object->$indice = (object) 'indice';
+ $object = &$object->$indice;
+ }
+
+ $value_key = "_value".$this->collection_key[$this->collection_depth];
+ $col_name_key = "_collection_name".$this->collection_key[$this->collection_depth];
+ $col_val_key = "_collection_value".$this->collection_key[$this->collection_depth];
+
+ $attribute_value = self::_interpretAttribute($attribute_name,$tag,$value);
+ $attribute_name = str_replace('-','_',$attribute_name);
+
+
+ self::_putDebug( sprintf("Value: %s\n",$value));
+ $object->$attribute_name->_type = $type;
+ $object->$attribute_name->$value_key = $attribute_value;
+ $object->$attribute_name->$col_name_key = $collection_name;
+ $object->$attribute_name->$col_val_key = $collection_value;
+
+ $this->serveroutput->response[$attributes_type][$j]['value'] = $this->collection;
+ }
+ // }}}
+
+ // {{{ _readAttributeName ($attributes_type,$j)
+ protected function _readAttributeName ($attributes_type,$j,$write=1) {
+
+ $name_length = ord($this->serveroutput->body[ $this->_parsing->offset]) * 256
+ + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+ $this->_parsing->offset += 2;
+
+ self::_putDebug( "name_length ". $name_length ."\n");
+
+ $name = '';
+ for ($i = 0; $i < $name_length; $i++) {
+ if ($this->_parsing->offset >= strlen($this->serveroutput->body))
+ return;
+ $name .= $this->serveroutput->body[$this->_parsing->offset];
+ $this->_parsing->offset += 1;
+ }
+
+ if($write)
+ $this->serveroutput->response[$attributes_type][$j]['name'] = $name;
+
+ self::_putDebug( "name " . $name . "\n");
+
+ return $name;
+ }
+ // }}}
+
+ // {{{ _readValue ($type,$attributes_type,$j)
+ protected function _readValue ($type,$attributes_type,$j,$write=1) {
+
+ $value_length = ord($this->serveroutput->body[$this->_parsing->offset]) * 256
+ + ord($this->serveroutput->body[$this->_parsing->offset + 1]);
+
+ self::_putDebug( "value_length ".$this->serveroutput->body[ $this->_parsing->offset]
+ . $this->serveroutput->body[$this->_parsing->offset + 1]
+ .": "
+ . $value_length
+ . " ");
+
+ $this->_parsing->offset += 2;
+
+ $value = '';
+ for ($i = 0; $i < $value_length; $i++) {
+
+ if ($this->_parsing->offset >= strlen($this->serveroutput->body))
+ return;
+ $value .= $this->serveroutput->body[$this->_parsing->offset];
+ $this->_parsing->offset += 1;
+
+ }
+
+ self::_putDebug( sprintf("Value: %s\n",$value));
+
+ if ($write)
+ $this->serveroutput->response[$attributes_type][$j]['value'] = $value;
+
+ return $value;
+ }
+ // }}}
+
+ // {{{ _parseAttributes()
+ protected function _parseAttributes() {
+
+ $k = -1;
+ for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
+ for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
+ if (!empty($this->serveroutput->response[$i][$j]['name'])) {
+ $k++;
+ $l = 0;
+ $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes'];
+ $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
+ $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
+ $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
+ } else {
+ $l ++;
+ $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
+ }
+ $this->serveroutput->response = array();
+ $this->attributes = new stdClass();
+ for ($i = 0 ; $i < count($this->parsed) ; $i ++) {
+ $name = $this->parsed[$i]['name'];
+ $php_name = str_replace('-','_',$name);
+ $type = $this->parsed[$i]['type'];
+ $range = $this->parsed[$i]['range'];
+ $this->attributes->$php_name = new stdClass();
+ $this->attributes->$php_name->_type = $type;
+ $this->attributes->$php_name->_range = $range;
+ for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) {
+ $value = $this->parsed[$i][$j];
+ $index = '_value'.$j;
+ $this->attributes->$php_name->$index = $value;
+ }
+ }
+
+ $this->parsed = array();
+
+ }
+ // }}}
+
+ // {{{ _parseJobAttributes()
+ protected function _parseJobAttributes() {
+
+ //if (!preg_match('#successful#',$this->serveroutput->status))
+ // return false;
+
+ $k = -1;
+ for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++)
+ for ($j = 0 ; $j < (count($this->serveroutput->response[$i]) - 1) ; $j ++)
+ if (!empty($this->serveroutput->response[$i][$j]['name'])) {
+ $k++;
+ $l = 0;
+ $this->parsed[$k]['range'] = $this->serveroutput->response[$i]['attributes'];
+ $this->parsed[$k]['name'] = $this->serveroutput->response[$i][$j]['name'];
+ $this->parsed[$k]['type'] = $this->serveroutput->response[$i][$j]['type'];
+ $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
+ } else {
+ $l ++;
+ $this->parsed[$k][$l] = $this->serveroutput->response[$i][$j]['value'];
+ }
+
+ $this->serveroutput->response = array();
+
+ $this->job_attributes = new stdClass();
+ for ($i = 0 ; $i < count($this->parsed) ; $i ++) {
+ $name = $this->parsed[$i]['name'];
+ $php_name = str_replace('-','_',$name);
+ $type = $this->parsed[$i]['type'];
+ $range = $this->parsed[$i]['range'];
+ $this->job_attributes->$php_name = new stdClass();
+ $this->job_attributes->$php_name->_type = $type;
+ $this->job_attributes->$php_name->_range = $range;
+ for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) {
+ $value = $this->parsed[$i][$j];
+ $index = '_value'.$j;
+ $this->job_attributes->$php_name->$index = $value;
+ }
+ }
+
+ $this->parsed = array();
+
+
+ }
+ // }}}
+
+ // {{{ _interpretAttribute($attribute_name,$type,$value)
+ protected function _interpretAttribute($attribute_name,$type,$value) {
+
+ switch ($type) {
+ case "integer":
+ $value = self::_interpretInteger($value);
+ break;
+ case "rangeOfInteger":
+ $value = self::_interpretRangeOfInteger($value);
+ break;
+ case 'boolean':
+ $value = ord($value);
+ if ($value == 0x00)
+ $value = 'false';
+ else
+ $value = 'true';
+ break;
+ case 'datetime':
+ $value = self::_interpretDateTime($value);
+ break;
+ case 'enum':
+ $value = $this->_interpretEnum($attribute_name,$value); // must be overwritten by children
+ break;
+ case 'resolution':
+ $unit = $value[8];
+ $value = self::_interpretRangeOfInteger(substr($value,0,8));
+ switch($unit) {
+ case chr(0x03):
+ $unit = "dpi";
+ break;
+ case chr(0x04):
+ $unit = "dpc";
+ break;
+ }
+ $value = $value." ".$unit;
+ break;
+ default:
+ break;
+ }
+ return $value;
+ }
+ // }}}
+
+ // {{{ _interpretRangeOfInteger($value)
+ protected function _interpretRangeOfInteger($value) {
+
+ $value_parsed = 0;
+ $integer1 = $integer2 = 0;
+
+ $halfsize = strlen($value) / 2;
+
+ $integer1 = self::_interpretInteger(substr($value,0,$halfsize));
+ $integer2 = self::_interpretInteger(substr($value,$halfsize,$halfsize));
+
+ $value_parsed = sprintf('%s-%s',$integer1,$integer2);
+
+
+ return $value_parsed;
+ }
+ // }}}
+
+ // {{{ _interpretDateTime($date) {
+ protected function _interpretDateTime($date) {
+ $year = self::_interpretInteger(substr($date,0,2));
+ $month = self::_interpretInteger(substr($date,2,1));
+ $day = self::_interpretInteger(substr($date,3,1));
+ $hour = self::_interpretInteger(substr($date,4,1));
+ $minute = self::_interpretInteger(substr($date,5,1));
+ $second = self::_interpretInteger(substr($date,6,1));
+ $direction = substr($date,8,1);
+ $hours_from_utc = self::_interpretInteger(substr($date,9,1));
+ $minutes_from_utc = self::_interpretInteger(substr($date,10,1));
+
+ $date = sprintf('%s-%s-%s %s:%s:%s %s%s:%s',$year,$month,$day,$hour,$minute,$second,$direction,$hours_from_utc,$minutes_from_utc);
+
+ return $date;
+ }
+ // }}}
+
+ // {{{ _interpretEnum()
+ protected function _interpretEnum($attribute_name,$value) {
+
+ $value_parsed = self::_interpretInteger($value);
+
+ switch ($attribute_name) {
+ case 'job-state':
+ switch ($value_parsed) {
+ case 0x03:
+ $value = 'pending';
+ break;
+ case 0x04:
+ $value = 'pending-held';
+ break;
+ case 0x05:
+ $value = 'processing';
+ break;
+ case 0x06:
+ $value = 'processing-stopped';
+ break;
+ case 0x07:
+ $value = 'canceled';
+ break;
+ case 0x08:
+ $value = 'aborted';
+ break;
+ case 0x09:
+ $value = 'completed';
+ break;
+ }
+ if ($value_parsed > 0x09)
+ $value = sprintf('Unknown(IETF standards track "job-state" reserved): 0x%x',$value_parsed);
+ break;
+ case 'print-quality':
+ case 'print-quality-supported':
+ case 'print-quality-default':
+ switch ($value_parsed) {
+ case 0x03:
+ $value = 'draft';
+ break;
+ case 0x04:
+ $value = 'normal';
+ break;
+ case 0x05:
+ $value = 'high';
+ break;
+ }
+ break;
+ case 'printer-state':
+ switch ($value_parsed) {
+ case 0x03:
+ $value = 'idle';
+ break;
+ case 0x04:
+ $value = 'processing';
+ break;
+ case 0x05:
+ $value = 'stopped';
+ break;
+ }
+ if ($value_parsed > 0x05)
+ $value = sprintf('Unknown(IETF standards track "printer-state" reserved): 0x%x',$value_parsed);
+ break;
+
+ case 'operations-supported':
+ switch($value_parsed) {
+ case 0x0000:
+ case 0x0001:
+ $value = sprintf('Unknown(reserved) : %s',ord($value));
+ break;
+ case 0x0002:
+ $value = 'Print-Job';
+ break;
+ case 0x0003:
+ $value = 'Print-URI';
+ break;
+ case 0x0004:
+ $value = 'Validate-Job';
+ break;
+ case 0x0005:
+ $value = 'Create-Job';
+ break;
+ case 0x0006:
+ $value = 'Send-Document';
+ break;
+ case 0x0007:
+ $value = 'Send-URI';
+ break;
+ case 0x0008:
+ $value = 'Cancel-Job';
+ break;
+ case 0x0009:
+ $value = 'Get-Job-Attributes';
+ break;
+ case 0x000A:
+ $value = 'Get-Jobs';
+ break;
+ case 0x000B:
+ $value = 'Get-Printer-Attributes';
+ break;
+ case 0x000C:
+ $value = 'Hold-Job';
+ break;
+ case 0x000D:
+ $value = 'Release-Job';
+ break;
+ case 0x000E:
+ $value = 'Restart-Job';
+ break;
+ case 0x000F:
+ $value = 'Unknown(reserved for a future operation)';
+ break;
+ case 0x0010:
+ $value = 'Pause-Printer';
+ break;
+ case 0x0011:
+ $value = 'Resume-Printer';
+ break;
+ case 0x0012:
+ $value = 'Purge-Jobs';
+ break;
+ case 0x0013:
+ $value = 'Set-Printer-Attributes'; // RFC3380
+ break;
+ case 0x0014:
+ $value = 'Set-Job-Attributes'; // RFC3380
+ break;
+ case 0x0015:
+ $value = 'Get-Printer-Supported-Values'; // RFC3380
+ break;
+ case 0x0016:
+ $value = 'Create-Printer-Subscriptions';
+ break;
+ case 0x0017:
+ $value = 'Create-Job-Subscriptions';
+ break;
+ case 0x0018:
+ $value = 'Get-Subscription-Attributes';
+ break;
+ case 0x0019:
+ $value = 'Get-Subscriptions';
+ break;
+ case 0x001A:
+ $value = 'Renew-Subscription';
+ break;
+ case 0x001B:
+ $value = 'Cancel-Subscription';
+ break;
+ case 0x001C:
+ $value = 'Get-Notifications';
+ break;
+ case 0x001D:
+ $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
+ break;
+ case 0x001E:
+ $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
+ break;
+ case 0x001F:
+ $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
+ break;
+ case 0x0020:
+ $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
+ break;
+ case 0x0021:
+ $value = sprintf('Unknown (reserved IETF "operations"): 0x%x',ord($value));
+ break;
+ case 0x0022:
+ $value = 'Enable-Printer';
+ break;
+ case 0x0023:
+ $value = 'Disable-Printer';
+ break;
+ case 0x0024:
+ $value = 'Pause-Printer-After-Current-Job';
+ break;
+ case 0x0025:
+ $value = 'Hold-New-Jobs';
+ break;
+ case 0x0026:
+ $value = 'Release-Held-New-Jobs';
+ break;
+ case 0x0027:
+ $value = 'Deactivate-Printer';
+ break;
+ case 0x0028:
+ $value = 'Activate-Printer';
+ break;
+ case 0x0029:
+ $value = 'Restart-Printer';
+ break;
+ case 0x002A:
+ $value = 'Shutdown-Printer';
+ break;
+ case 0x002B:
+ $value = 'Startup-Printer';
+ break;
+ }
+ if ($value_parsed > 0x002B && $value_parsed <= 0x3FFF)
+ $value = sprintf('Unknown(IETF standards track operations reserved): 0x%x',$value_parsed);
+ elseif ($value_parsed >= 0x4000 && $value_parsed <= 0x8FFF) {
+ if (method_exists($this,'_getEnumVendorExtensions')) {
+ $value = $this->_getEnumVendorExtensions($value_parsed);
+ } else
+ $value = sprintf('Unknown(Vendor extension for operations): 0x%x',$value_parsed);
+ } elseif ($value_parsed > 0x8FFF)
+ $value = sprintf('Unknown operation (should not exists): 0x%x',$value_parsed);
+
+ break;
+ case 'finishings':
+ case 'finishings-default':
+ case 'finishings-supported':
+ switch ($value_parsed) {
+ case 3:
+ $value = 'none';
+ break;
+ case 4:
+ $value = 'staple';
+ break;
+ case 5:
+ $value = 'punch';
+ break;
+ case 6:
+ $value = 'cover';
+ break;
+ case 7:
+ $value = 'bind';
+ break;
+ case 8:
+ $value = 'saddle-stitch';
+ break;
+ case 9:
+ $value = 'edge-stitch';
+ break;
+ case 20:
+ $value = 'staple-top-left';
+ break;
+ case 21:
+ $value = 'staple-bottom-left';
+ break;
+ case 22:
+ $value = 'staple-top-right';
+ break;
+ case 23:
+ $value = 'staple-bottom-right';
+ break;
+ case 24:
+ $value = 'edge-stitch-left';
+ break;
+ case 25:
+ $value = 'edge-stitch-top';
+ break;
+ case 26:
+ $value = 'edge-stitch-right';
+ break;
+ case 27:
+ $value = 'edge-stitch-bottom';
+ break;
+ case 28:
+ $value = 'staple-dual-left';
+ break;
+ case 29:
+ $value = 'staple-dual-top';
+ break;
+ case 30:
+ $value = 'staple-dual-right';
+ break;
+ case 31:
+ $value = 'staple-dual-bottom';
+ break;
+ }
+ if ($value_parsed > 31)
+ $value = sprintf('Unknown(IETF standards track "finishing" reserved): 0x%x',$value_parsed);
+ break;
+
+ case 'orientation-requested':
+ case 'orientation-requested-supported':
+ case 'orientation-requested-default':
+ switch ($value_parsed) {
+ case 0x03:
+ $value = 'portrait';
+ break;
+ case 0x04:
+ $value = 'landscape';
+ break;
+ case 0x05:
+ $value = 'reverse-landscape';
+ break;
+ case 0x06:
+ $value = 'reverse-portrait';
+ break;
+ }
+ if ($value_parsed > 0x06)
+ $value = sprintf('Unknown(IETF standards track "orientation" reserved): 0x%x',$value_parsed);
+ break;
+
+ default:
+ break;
+ }
+ return $value;
+ }
+ // }}}
+
+ // {{{ _getJobId ()
+ protected function _getJobId () {
+
+ if (!isset($this->serveroutput->response))
+ $this->jobs = array_merge($this->jobs,array('NO JOB'));
+
+ $jobfinded = false;
+ for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++)
+ if (($this->serveroutput->response[$i]['attributes']) == "job-attributes")
+ for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++)
+ if ($this->serveroutput->response[$i][$j]['name'] == "job-id") {
+ $this->last_job = $this->serveroutput->response[$i][$j]['value'];
+ $this->jobs = array_merge($this->jobs,array($this->serveroutput->response[$i][$j]['value']));
+ return;
+
+ }
+
+ }
+ // }}}
+
+ // {{{ _getJobUri ()
+ protected function _getJobUri () {
+
+ if (!isset($this->jobs_uri))
+ $this->jobs_uri = array();
+
+ $jobfinded = false;
+ for ($i = 0 ; (!$jobfinded && array_key_exists($i,$this->serveroutput->response)) ; $i ++)
+ if (($this->serveroutput->response[$i]['attributes']) == "job-attributes")
+ for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++)
+ if ($this->serveroutput->response[$i][$j]['name'] == "job-uri") {
+ $this->last_job = $this->serveroutput->response[$i][$j]['value'];
+ $this->jobs_uri = array_merge($this->jobs_uri,array($this->last_job));
+ return;
+
+ }
+ $this->last_job = '';
+
+ }
+ // }}}
+
+ // {{{ _parseResponse ()
+ protected function _parseResponse () {
+ $j = -1;
+ $this->index = 0;
+ for ($i = $this->_parsing->offset; $i < strlen($this->serveroutput->body) ; $i = $this->_parsing->offset) {
+
+
+ $tag = ord($this->serveroutput->body[$this->_parsing->offset]);
+
+
+ if ($tag > 0x0F) {
+
+ self::_readAttribute($j);
+ $this->index ++;
+ continue;
+ }
+
+ switch ($tag) {
+ case 0x01:
+ $j += 1;
+ $this->serveroutput->response[$j]['attributes'] = "operation-attributes";
+ $this->index = 0;
+ $this->_parsing->offset += 1;
+ break;
+ case 0x02:
+ $j += 1;
+ $this->serveroutput->response[$j]['attributes'] = "job-attributes";
+ $this->index = 0;
+ $this->_parsing->offset += 1;
+ break;
+ case 0x03:
+ $j +=1;
+ $this->serveroutput->response[$j]['attributes'] = "end-of-attributes";
+ self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n");
+ if ($this->alert_on_end_tag === 1)
+ echo "END tag OK
";
+ $this->response_completed[(count($this->response_completed) -1)] = "completed";
+ return;
+ case 0x04:
+ $j += 1;
+ $this->serveroutput->response[$j]['attributes'] = "printer-attributes";
+ $this->index = 0;
+ $this->_parsing->offset += 1;
+ break;
+ case 0x05:
+ $j += 1;
+ $this->serveroutput->response[$j]['attributes'] = "unsupported-attributes";
+ $this->index = 0;
+ $this->_parsing->offset += 1;
+ break;
+ default:
+ $j += 1;
+ $this->serveroutput->response[$j]['attributes'] = sprintf(_("0x%x (%u) : attributes tag Unknown (reserved for future versions of IPP"),$tag,$tag);
+ $this->index = 0;
+ $this->_parsing->offset += 1;
+ break;
+ }
+
+ self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n\n\n");
+
+ }
+ return;
+ }
+ // }}}
+
+
+
+
+ /*
+ // NOTICE : HAVE TO READ AGAIN RFC 2911 TO SEE IF IT IS PART OF SERVER'S RESPONSE (CUPS DO NOT)
+ // {{{ _getPrinterUri ()
+ protected function _getPrinterUri () {
+
+ for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++)
+ if (($this->serveroutput->response[$i]['attributes']) == "job-attributes")
+ for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++)
+ if ($this->serveroutput->response[$i][$j]['name'] == "printer-uri") {
+ $this->printers_uri = array_merge($this->printers_uri,array($this->serveroutput->response[$i][$j]['value']));
+
+ return;
+
+ }
+
+ $this->printers_uri = array_merge($this->printers_uri,array(''));
+
+ }
+ // }}}
+ */
+
+// REQUEST BUILDING
+
+ // {{{ _stringCancel ()
+ protected function _stringCancel ($job_uri) {
+
+ if (!isset($this->setup->charset))
+ self::setCharset('us-ascii');
+ if (!isset($this->setup->datatype))
+ self::setBinary();
+ if (!isset($this->setup->language))
+ self::setLanguage('en_us');
+ if (!$this->requesting_user)
+ self::setUserName();
+ if (!isset($this->meta->message))
+ $this->meta->message = '';
+
+ self::_setOperationId();
+
+ self::_setJobUri($job_uri);
+
+ 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 (0x08) // cancel-Job | operation-id
+ . $this->meta->operation_id // request-id
+ . $this->error_generation->request_body_malformed
+ . chr(0x01) // start operation-attributes | operation-attributes-tag
+ . $this->meta->charset
+ . $this->meta->language
+ . $this->meta->job_uri
+ . $this->meta->username
+ . $this->meta->message
+ . chr(0x03); // end-of-attributes | end-of-attributes-tag
+
+ self::_putDebug( sprintf(_("String sent to the server is:\n%s\n"), $this->stringjob));
+ return TRUE;
+ }
+ // }}}
+
+
+};
+
+/*
+ * Local variables:
+ * mode: php
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ */
+?>
diff --git a/htdocs/includes/printipp/http_class.php b/htdocs/includes/printipp/http_class.php
new file mode 100644
index 00000000000..569d4f6648f
--- /dev/null
+++ b/htdocs/includes/printipp/http_class.php
@@ -0,0 +1,615 @@
+errno = $errno;
+ }
+ public function getErrorFormatted ()
+ {
+ return sprintf ("[http_class]: %s -- "._(" file %s, line %s"),
+ $this->getMessage (), $this->getFile (), $this->getLine ());
+ }
+ public function getErrno ()
+ {
+ return $this->errno;
+ }
+}
+
+function error2string($value)
+{
+ $level_names = array(
+ E_ERROR => 'E_ERROR',
+ E_WARNING => 'E_WARNING',
+ E_PARSE => 'E_PARSE',
+ E_NOTICE => 'E_NOTICE',
+ E_CORE_ERROR => 'E_CORE_ERROR',
+ E_CORE_WARNING => 'E_CORE_WARNING',
+ E_COMPILE_ERROR => 'E_COMPILE_ERROR',
+ E_COMPILE_WARNING => 'E_COMPILE_WARNING',
+ E_USER_ERROR => 'E_USER_ERROR',
+ E_USER_WARNING => 'E_USER_WARNING',
+ E_USER_NOTICE => 'E_USER_NOTICE'
+ );
+ if(defined('E_STRICT')) $level_names[E_STRICT]='E_STRICT';
+ $levels=array();
+ if(($value&E_ALL)==E_ALL)
+ {
+ $levels[]='E_ALL';
+ $value&=~E_ALL;
+ }
+ foreach($level_names as $level=>$name)
+ if(($value&$level)==$level) $levels[]=$name;
+ return implode(' | ',$levels);
+}
+
+/***********************
+ *
+ * class http_class
+ *
+ ************************/
+class http_class
+{
+ // variables declaration
+ public $debug;
+ public $html_debug;
+ public $timeout = 30; // time waiting for connection, seconds
+ public $data_timeout = 30; // time waiting for data, milliseconds
+ public $data_chunk_timeout = 1; // time waiting between data chunks, millisecond
+ public $force_multipart_form_post;
+ public $username;
+ public $password;
+ public $request_headers = array ();
+ public $request_body = "Not a useful information";
+ public $status;
+ public $window_size = 1024; // chunk size of data
+ public $with_exceptions = 0; // compatibility mode for old scripts
+ public $port;
+ public $host;
+ private $default_port = 631;
+ private $headers;
+ private $reply_headers = array ();
+ private $reply_body = array ();
+ private $connection;
+ private $arguments;
+ private $bodystream = array ();
+ private $last_limit;
+ private $connected;
+ private $nc = 1;
+ private $user_agent = "PRINTIPP/0.81+CVS";
+ private $readed_bytes = 0;
+
+ public function __construct ()
+ {
+ true;
+ }
+
+ /*********************
+ *
+ * Public functions
+ *
+ **********************/
+
+ public function GetRequestArguments ($url, &$arguments)
+ {
+ $this->arguments = array ();
+ $arguments["URL"] = $this->arguments["URL"] = $url;
+ $arguments["RequestMethod"] = $this->arguments["RequestMethod"] = "POST";
+ $this->headers["Content-Length"] = 0;
+ $this->headers["Content-Type"] = "application/octet-stream";
+ $this->headers["Host"] = $this->host;
+ $this->headers["User-Agent"] = $this->user_agent;
+ //$this->headers["Expect"] = "100-continue";
+
+ }
+
+ public function Open ($arguments)
+ {
+ $this->connected = false;
+ $url = $arguments["URL"];
+ $port = $this->default_port;
+ #$url = split (':', $url, 2);
+ $url = preg_split ('#:#', $url, 2);
+ $transport_type = $url[0];
+ $unix = false;
+ switch ($transport_type)
+ {
+ case 'http':
+ $transport_type = 'tcp://';
+ break;
+
+ case 'https':
+ $transport_type = 'tls://';
+ break;
+
+ case 'unix':
+ $transport_type = 'unix://';
+ $port = 0;
+ $unix = true;
+ break;
+
+ default:
+ $transport_type = 'tcp://';
+ break;
+ }
+ $url = $url[1];
+ if (!$unix)
+ {
+ #$url = split ("/", preg_replace ("#^/{1,}#", '', $url), 2);
+ $url = preg_split ("#/#", preg_replace ("#^/{1,}#", '', $url), 2);
+ $url = $url[0];
+ $port = $this->port;
+ $error = sprintf (_("Cannot resolve url: %s"), $url);
+ $ip = gethostbyname ($url);
+ $ip = @gethostbyaddr ($ip);
+ if (!$ip)
+ {
+ return $this->_HttpError ($error, E_USER_WARNING);
+ }
+ if (strstr ($url, ":")) // we got an ipv6 address
+ if (!strstr ($url, "[")) // it is not escaped
+ $url = sprintf ("[%s]", $url);
+ }
+ $this->connection = @fsockopen ($transport_type.$url, $port, $errno, $errstr, $this->timeout);
+ $error =
+ sprintf (_('Unable to connect to "%s%s port %s": %s'), $transport_type,
+ $url, $port, $errstr);
+ if (!$this->connection)
+ {
+ return $this->_HttpError ($error, E_USER_WARNING);
+ }
+ $this->connected = true;
+ return array (true, "success");
+ }
+
+ public function SendRequest ($arguments)
+ {
+ $error =
+ sprintf (_('Streaming request failed to %s'), $arguments['RequestURI']);
+ $result = self::_StreamRequest ($arguments);
+ if (!$result[0])
+ {
+ return $this->_HttpError ($error." ".$result[1], E_USER_WARNING);
+ }
+ self::_ReadReply ();
+ if (!preg_match ('#http/1.1 401 unauthorized#', $this->status))
+ {
+ return array (true, "success");
+ }
+ $headers = array_keys ($this->reply_headers);
+ $error = _("need authentication but no mechanism provided");
+ if (!in_array ("www-authenticate", $headers))
+ {
+ return $this->_HttpError ($error, E_USER_WARNING);
+ }
+ #$authtype = split (' ', $this->reply_headers["www-authenticate"]);
+ $authtype = preg_split ('# #', $this->reply_headers["www-authenticate"]);
+ $authtype = strtolower ($authtype[0]);
+ switch ($authtype)
+ {
+ case 'basic':
+ $pass = base64_encode ($this->user.":".$this->password);
+ $arguments["Headers"]["Authorization"] = "Basic ".$pass;
+ break;
+
+ case 'digest':
+ $arguments["Headers"]["Authorization"] = self::_BuildDigest ();
+ break;
+
+ default:
+ $error =
+ sprintf (_("need '%s' authentication mechanism, but have not"),
+ $authtype[0]);
+ return $this->_HttpError ($error, E_USER_WARNING);
+ break;
+
+ }
+ self::Close ();
+ self::Open ($arguments);
+ $error =
+ sprintf (_
+ ('Streaming request failed to %s after a try to authenticate'),
+ $url);
+ $result = self::_StreamRequest ($arguments);
+ if (!$result[0])
+ {
+ return $this->_HttpError ($error.": ".$result[1], E_USER_WARNING);
+ }
+ self::_ReadReply ();
+ return array (true, "success");
+ }
+
+ public function ReadReplyHeaders (&$headers)
+ {
+ $headers = $this->reply_headers;
+ }
+
+ public function ReadReplyBody (&$body, $chunk_size)
+ {
+ $body = substr ($this->reply_body, $this->last_limit, $chunk_size);
+ $this->last_limit += $chunk_size;
+ }
+
+ public function Close ()
+ {
+ if (!$this->connected)
+ return;
+ fclose ($this->connection);
+ }
+
+ /*********************
+ *
+ * Private functions
+ *
+ *********************/
+
+ private function _HttpError ($msg, $level, $errno = null)
+ {
+ $trace = '';
+ $backtrace = debug_backtrace;
+ foreach ($backtrace as $trace)
+ {
+ $trace .= sprintf ("in [file: '%s'][function: '%s'][line: %s];\n", $trace['file'], $trace['function'],$trace['line']);
+ }
+ $msg = sprintf ( '%s\n%s: [errno: %s]: %s',
+ $trace, error2string ($level), $errno, $msg);
+ if ($this->with_exceptions)
+ {
+ throw new httpException ($msg, $errno);
+ }
+ else
+ {
+ trigger_error ($msg, $level);
+ return array (false, $msg);
+ }
+ }
+
+ private function _streamString ($string)
+ {
+ $success = fwrite ($this->connection, $string);
+ if (!$success)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private function _StreamRequest ($arguments)
+ {
+ $this->status = false;
+ $this->reply_headers = array ();
+ $this->reply_body = "";
+ if (!$this->connected)
+ {
+ return _HttpError (_("not connected"), E_USER_WARNING);
+ }
+ $this->arguments = $arguments;
+ $content_length = 0;
+ foreach ($this->arguments["BodyStream"] as $argument)
+ {
+ list ($type, $value) = each ($argument);
+ reset ($argument);
+ if ($type == "Data")
+ {
+ $length = strlen ($value);
+ }
+ elseif ($type == "File")
+ {
+ if (is_readable ($value))
+ {
+ $length = filesize ($value);
+ }
+ else
+ {
+ $length = 0;
+ return
+ _HttpError (sprintf (_("%s: file is not readable"), $value),
+ E_USER_WARNING);
+ }
+ }
+ else
+ {
+ $length = 0;
+ return
+ _HttpError (sprintf
+ (_("%s: not a valid argument for content"), $type),
+ E_USER_WARNING);
+ }
+ $content_length += $length;
+ }
+ $this->request_body = sprintf (_("%s Bytes"), $content_length);
+ $this->headers["Content-Length"] = $content_length;
+ $this->arguments["Headers"] =
+ array_merge ($this->headers, $this->arguments["Headers"]);
+ if ($this->arguments["RequestMethod"] != "POST")
+ {
+ return
+ _HttpError (sprintf
+ (_("%s: method not implemented"),
+ $arguments["RequestMethod"]), E_USER_WARNING);
+ }
+ $string =
+ sprintf ("POST %s HTTP/1.1\r\n", $this->arguments["RequestURI"]);
+ $this->request_headers[$string] = '';
+ if (!$this->_streamString ($string))
+ {
+ return _HttpError (_("Error while puts POST operation"),
+ E_USER_WARNING);
+ }
+ foreach ($this->arguments["Headers"] as $header => $value)
+ {
+ $string = sprintf ("%s: %s\r\n", $header, $value);
+ $this->request_headers[$header] = $value;
+ if (!$this->_streamString ($string))
+ {
+ return _HttpError (_("Error while puts HTTP headers"),
+ E_USER_WARNING);
+ }
+ }
+ $string = "\r\n";
+ if (!$this->_streamString ($string))
+ {
+ return _HttpError (_("Error while ends HTTP headers"),
+ E_USER_WARNING);
+ }
+ foreach ($this->arguments["BodyStream"] as $argument)
+ {
+ list ($type, $value) = each ($argument);
+ reset ($argument);
+ if ($type == "Data")
+ {
+ $streamed_length = 0;
+ while ($streamed_length < strlen ($value))
+ {
+ $string = substr ($value, $streamed_length, $this->window_size);
+ if (!$this->_streamString ($string))
+ {
+ return _HttpError (_("error while sending body data"),
+ E_USER_WARNING);
+ }
+ $streamed_length += $this->window_size;
+ }
+ }
+ elseif ($type == "File")
+ {
+ if (is_readable ($value))
+ {
+ $file = fopen ($value, 'rb');
+ while (!feof ($file))
+ {
+ if (gettype ($block = @fread ($file, $this->window_size)) !=
+ "string")
+ {
+ return _HttpError (_("cannot read file to upload"),
+ E_USER_WARNING);
+ }
+ if (!$this->_streamString ($block))
+ {
+ return _HttpError (_("error while sending body data"),
+ E_USER_WARNING);
+ }
+ }
+ }
+ }
+ }
+ return array (true, "success");
+ }
+
+ private function _ReadReply ()
+ {
+ if (!$this->connected)
+ {
+ return array (false, _("not connected"));
+ }
+ $this->reply_headers = array ();
+ $this->reply_body = "";
+ $headers = array ();
+ $body = "";
+ while (!feof ($this->connection))
+ {
+ $line = fgets ($this->connection, 1024);
+ if (strlen (trim($line)) == 0)
+ break; // \r\n => end of headers
+ if (preg_match ('#^[[:space:]]#', $line))
+ {
+ $headers[-1] .= sprintf(' %s', trim ($line));
+ continue;
+ }
+ $headers[] = trim ($line);
+ }
+ $this->status = isset ($headers[0]) ? strtolower ($headers[0]) : false;
+ foreach ($headers as $header)
+ {
+ $header = preg_split ("#: #", $header);
+ $header[0] = strtolower ($header[0]);
+ if ($header[0] !== "www-authenticate")
+ {
+ $header[1] = isset ($header[1]) ? strtolower ($header[1]) : "";
+ }
+ if (!isset ($this->reply_headers[$header[0]]))
+ {
+ $this->reply_headers[$header[0]] = $header[1];
+ }
+ }
+ self::_ReadStream ();
+ return true;
+ }
+
+ private function _ReadStream ()
+ {
+ if (! array_key_exists ("content-length", $this->reply_headers))
+ {
+ stream_set_blocking($this->connection, 0);
+ $this->reply_body = stream_get_contents($this->connection);
+ return true;
+ }
+ stream_set_blocking($this->connection, 1);
+ $content_length = $this->reply_headers["content-length"];
+ $this->reply_body = stream_get_contents($this->connection,$content_length);
+ return true;
+ }
+
+ private function _BuildDigest ()
+ {
+ $auth = $this->reply_headers["www-authenticate"];
+ #list ($head, $auth) = split (" ", $auth, 2);
+ list ($head, $auth) = preg_split ("# #", $auth, 2);
+ #$auth = split (", ", $auth);
+ $auth = preg_split ("#, #", $auth);
+ foreach ($auth as $sheme)
+ {
+ #list ($sheme, $value) = split ('=', $sheme);
+ list ($sheme, $value) = preg_split ('#=#', $sheme);
+ $fields[$sheme] = trim (trim ($value), '"');
+ }
+ $nc = sprintf ('%x', $this->nc);
+ $prepend = "";
+ while ((strlen ($nc) + strlen ($prepend)) < 8)
+ $prependi .= "0";
+ $nc = $prepend.$nc;
+ $cnonce = "printipp";
+ $username = $this->user;
+ $password = $this->password;
+ $A1 = $username.":".$fields["realm"].":".$password;
+ if (array_key_exists ("algorithm", $fields))
+ {
+ $algorithm = strtolower ($fields["algorithm"]);
+ switch ($algorithm)
+ {
+ case "md5":
+ break;
+
+ case "md5-sess":
+ $A1 =
+ $username.":".$fields["realm"].":".$password.":".
+ $fields['nonce'].":".$cnonce;
+ break;
+
+ default:
+ return _HttpError(
+ sprintf (_("digest Authorization: algorithm '%s' not implemented"),
+ $algorithm),
+ E_USER_WARNING);
+ return false;
+ break;
+ }
+ }
+ $A2 = "POST:".$this->arguments["RequestURI"];
+ if (array_key_exists ("qop", $fields))
+ {
+ $qop = strtolower ($fields["qop"]);
+ #$qop = split (" ", $qop);
+ $qop = preg_split ("# #", $qop);
+ if (in_array ("auth", $qop))
+ $qop = "auth";
+ else
+ {
+ self::_HttpError(
+ sprintf (_("digest Authorization: algorithm '%s' not implemented"),
+ $qop),
+ E_USER_WARNING);
+ return false;
+ }
+ }
+ $response = md5 (md5 ($A1).":".$fields["nonce"].":".md5 ($A2));
+ if (isset ($qop) && ($qop == "auth"))
+ {
+ $response =
+ md5 (md5 ($A1).":".$fields["nonce"].":".$nc.":".$cnonce.":".$qop.
+ ":".$A2);
+ }
+ $auth_scheme =
+ sprintf
+ ('Digest username="%s", realm="%s", nonce="%s", uri="%s", response="%s"',
+ $username, $fields["realm"], $fields['nonce'],
+ $this->arguments["RequestURI"], $response);
+ if (isset ($algorithm))
+ $auth_scheme .= sprintf (', algorithm="%s"', $algorithm);
+ if (isset ($qop))
+ $auth_scheme .= sprintf (', cnonce="%s"', $cnonce);
+ if (array_key_exists ("opaque", $fields))
+ $auth_scheme .= sprintf (', opaque="%s"', $fields['opaque']);
+ if (isset ($qop))
+ $auth_scheme .= sprintf (', qop="%s"', $qop);
+ $auth_scheme .= sprintf (', nc=%s', $nc);
+ $this->nc++;
+ return $auth_scheme;
+ }
+
+};
+
+/*
+ * Local variables:
+ * mode: php
+ * tab-width: 2
+ * c-basic-offset: 2
+ * End:
+ */
+?>
diff --git a/htdocs/printipp/admin/printipp.php b/htdocs/printipp/admin/printipp.php
new file mode 100644
index 00000000000..34163f125ec
--- /dev/null
+++ b/htdocs/printipp/admin/printipp.php
@@ -0,0 +1,159 @@
+.
+ */
+
+/**
+ * \file htdocs/printipp/admin/printipp.php
+ * \ingroup core
+ * \brief Page to setup printipp module
+ */
+
+require '../../main.inc.php';
+
+require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php';
+require_once DOL_DOCUMENT_ROOT.'/printipp/lib/printipp.lib.php';
+
+$langs->load("admin");
+$langs->load("printipp");
+
+if (! $user->admin) accessforbidden();
+
+$action = GETPOST('action','alpha');
+$mode = GETPOST('mode','alpha');
+
+if (!$mode) $mode='config';
+
+/*
+ * Action
+ */
+if ($action == 'setvalue' && $user->admin)
+{
+ $db->begin();
+ $result=dolibarr_set_const($db, "PRINTIPP_HOST",GETPOST('PRINTIPP_HOST','alpha'),'chaine',0,'',$conf->entity);
+ if (! $result > 0) $error++;
+ $result=dolibarr_set_const($db, "PRINTIPP_PORT",GETPOST('PRINTIPP_PORT','alpha'),'chaine',0,'',$conf->entity);
+ if (! $result > 0) $error++;
+ $result=dolibarr_set_const($db, "PRINTIPP_USER",GETPOST('PRINTIPP_USER','alpha'),'chaine',0,'',$conf->entity);
+ if (! $result > 0) $error++;
+ $result=dolibarr_set_const($db, "PRINTIPP_PASSWORD",GETPOST('PRINTIPP_PASSWORD','alpha'),'chaine',0,'',$conf->entity);
+ if (! $result > 0) $error++;
+
+ if (! $error)
+ {
+ $db->commit();
+ setEventMessage($langs->trans("SetupSaved"));
+ }
+ else
+ {
+ $db->rollback();
+ dol_print_error($db);
+ }
+}
+
+
+/*
+ * View
+ */
+
+$form = new Form($db);
+
+llxHeader('',$langs->trans("PrintIPPSetup"));
+
+$linkback=''.$langs->trans("BackToModuleList").'';
+print_fiche_titre($langs->trans("PrintIPPSetup"),$linkback,'setup');
+
+$head=printippadmin_prepare_head();
+
+dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"));
+
+print $langs->trans("PrintIPPDesc")."
\n";
+
+
+ print '
';
+
+if ($mode=='config'&& $user->admin)
+{
+ print '';
+}
+
+if ($mode=='test'&& $user->admin)
+{
+ print '';
+ $printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD);
+ $var=true;
+ print '';
+ print '| '.$langs->trans("TestConnect").' | ';
+ print print_r($printer->getlist_available_printers(),true);
+ print "
\n";
+ print '
';
+}
+
+dol_fiche_end();
+
+llxFooter();
+$db->close();
+?>
diff --git a/htdocs/printipp/index.php b/htdocs/printipp/index.php
new file mode 100644
index 00000000000..5a9e60a6280
--- /dev/null
+++ b/htdocs/printipp/index.php
@@ -0,0 +1,36 @@
+.
+ */
+
+/**
+\file htdocs/printipp/index.php
+\ingroup printipp
+\brief Printipp
+*/
+
+require '../main.inc.php';
+require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php';
+
+llxHeader("",$langs->trans("Printer"));
+
+print_fiche_titre($langs->trans("Printer"));
+
+$printer = new dolPrintIPP($db,$conf->global->PRINTIPP_HOST,$conf->global->PRINTIPP_PORT,$user->login,$conf->global->PRINTIPP_USER,$conf->global->PRINTIPP_PASSWORD);
+$printer->list_jobs('commande');
+
+llxFooter();
+
+?>
diff --git a/htdocs/printipp/lib/printipp.lib.php b/htdocs/printipp/lib/printipp.lib.php
new file mode 100644
index 00000000000..33f367a0501
--- /dev/null
+++ b/htdocs/printipp/lib/printipp.lib.php
@@ -0,0 +1,61 @@
+.
+ */
+
+/**
+ * \file htdocs/printipp/lib/printipp.lib.php
+ * \ingroup printipp
+ * \brief Library for printipp functions
+ */
+
+
+
+/**
+ * Define head array for tabs of printipp tools setup pages
+ *
+ * @return Array of head
+ */
+function printippadmin_prepare_head()
+{
+ global $langs, $conf;
+
+ $h = 0;
+ $head = array();
+
+ $head[$h][0] = DOL_URL_ROOT."/printipp/admin/printipp.php?mode=config";
+ $head[$h][1] = $langs->trans("Config");
+ $head[$h][2] = 'config';
+ $h++;
+
+ $head[$h][0] = DOL_URL_ROOT."/printipp/admin/printipp.php?mode=test";
+ $head[$h][1] = $langs->trans("Test");
+ $head[$h][2] = 'test';
+ $h++;
+
+ $object=new stdClass();
+
+ // Show more tabs from modules
+ // Entries must be declared in modules descriptor with line
+ // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
+ // $this->tabs = array('entity:-tabname); to remove a tab
+ complete_head_from_modules($conf,$langs,$object,$head,$h,'printippadmin');
+
+ complete_head_from_modules($conf,$langs,$object,$head,$h,'printipp','remove');
+
+ return $head;
+}
+
+?>