diff --git a/.tx/config b/.tx/config index e4d1fc65732c7338a1672b6270523d8c6129d953..74875508f297e73c96d0ba800d3808f4c6422a1b 100644 --- a/.tx/config +++ b/.tx/config @@ -236,6 +236,18 @@ source_file = htdocs/langs/en_US/paypal.lang source_lang = en_US type = MOZILLAPROPERTIES +[dolibarr.printgcp] +file_filter = htdocs/langs/<lang>/printgcp.lang +source_file = htdocs/langs/en_US/printgcp.lang +source_lang = en_US +type = MOZILLAPROPERTIES + +[dolibarr.printing] +file_filter = htdocs/langs/<lang>/printing.lang +source_file = htdocs/langs/en_US/printing.lang +source_lang = en_US +type = MOZILLAPROPERTIES + [dolibarr.printipp] file_filter = htdocs/langs/<lang>/printipp.lang source_file = htdocs/langs/en_US/printipp.lang diff --git a/htdocs/comm/propal.php b/htdocs/comm/propal.php index 7ef2f3bd4c9ac90e0e37dcec26bc5af55b6edca2..3efc6ba53253d44eb7b75b63f596b213fcf93683 100644 --- a/htdocs/comm/propal.php +++ b/htdocs/comm/propal.php @@ -550,7 +550,7 @@ else if ($action == 'setstatut' && $user->rights->propal->cloturer && ! GETPOST( } } -include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; /* diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index f20201ee5cc4a7ff6df76de4a2cb2e0681ffd0de..4c2e279418b8adbf9242feadadecc948847513e1 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -1141,7 +1141,7 @@ else if ($action == 'update_extras') { $action = 'edit_extras'; } -include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; /* diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php index adb46ecdae91210191e5363011bd2fe2b38edb59..82b2b56d1eea2224d4da2c11b7499089d2f24ab7 100644 --- a/htdocs/compta/facture.php +++ b/htdocs/compta/facture.php @@ -1690,7 +1690,7 @@ else if ($action == 'remove_file') { } } -include DOL_DOCUMENT_ROOT.'/core/actions_printipp.inc.php'; +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->facture->creer) { diff --git a/htdocs/core/actions_printing.inc.php b/htdocs/core/actions_printing.inc.php new file mode 100644 index 0000000000000000000000000000000000000000..431ac89a94e85e7b97781cc65900e84be2bc3578 --- /dev/null +++ b/htdocs/core/actions_printing.inc.php @@ -0,0 +1,64 @@ +<?php +/* Copyright (C) 2014 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2014 Frederic France <frederic.france@free.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/actions_printing.inc.php + * \brief Code for actions print_file to print file with calling trigger + */ + + +// $action must be defined +// $db, $user, $conf, $langs must be defined +// Filename to print must be provided into 'file' parameter + +// Print file +if ($action == 'print_file' and $user->rights->printing->read) +{ + $langs->load("printing"); + require_once DOL_DOCUMENT_ROOT . '/core/modules/printing/modules_printing.php'; + $objectprint = new PrintingDriver($db); + $list = $objectprint->listDrivers($db, 10); + if (! empty($list)) { + $errorprint=0; + $printed=0; + foreach ($list as $driver) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $langs->load($driver); + $classname = 'printing_'.$driver; + $printer = new $classname($db); + //print '<pre>'.print_r($printer, true).'</pre>'; + + if (! empty($conf->global->{$printer->active})) { + $subdir=(GETPOST('printer', 'alpha')=='expedition'?'sending':''); + $errorprint = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha'), $subdir); + //if ($errorprint < 0) { + // setEventMessage($interface->errors, 'errors'); + //} + if ($errorprint=='') { + setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file'))).' '.$langs->trans("ViaModule").' '.$printer->name); + $printed++; + } + } + } + if ($printed==0) setEventMessage($langs->trans("NoActivePrintingModuleFound")); + } else { + setEventMessage($langs->trans("NoModuleFound"), 'warning'); + } + $action = ''; +} diff --git a/htdocs/core/actions_printipp.inc.php b/htdocs/core/actions_printipp.inc.php deleted file mode 100644 index 3c18faa813b19b6f6400c37e61221669c639de29..0000000000000000000000000000000000000000 --- a/htdocs/core/actions_printipp.inc.php +++ /dev/null @@ -1,45 +0,0 @@ -<?php -/* Copyright (C) 2014 Laurent Destailleur <eldy@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * or see http://www.gnu.org/ - */ - -/** - * \file htdocs/core/actions_printipp.inc.php - * \brief Code for actions print_file to print file using ipp - */ - - -// $action must be defined -// $db, $user, $conf, $langs must be defined -// Filename to print must be provided into 'file' parameter - -// Print file -if ($action == 'print_file' and $user->rights->printipp->read) -{ - $langs->load("printipp"); - 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); - $result = $printer->print_file(GETPOST('file', 'alpha'), GETPOST('printer', 'alpha')); - if ($result) - { - setEventMessage($result,'warnings'); - } - else - { - setEventMessage($langs->trans("FileWasSentToPrinter", basename(GETPOST('file')))); - } - $action = ''; -} diff --git a/htdocs/core/class/dolprintipp.class.php b/htdocs/core/class/dolprintipp.class.php index b6e09547743b2bad1c3b53236ce482239c04d7cc..252b742cc9d52a19ed7a68f2339db9b64cfbeddd 100644 --- a/htdocs/core/class/dolprintipp.class.php +++ b/htdocs/core/class/dolprintipp.class.php @@ -28,7 +28,7 @@ class dolprintIPP { var $host; var $port; - var $userid; /* user login */ + var $userid; /* user login */ var $user; var $password; var $error; diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index bea2fa7347e1043f0ae5b500ee5e6dc912bb254d..91bf047f88a0bbd81ed2accf49d1cfb661d70781 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -273,9 +273,9 @@ class FormFile } $printer=0; - if (in_array($modulepart,array('facture','propal','proposal','order','commande'))) // This feature is implemented only for such elements + if (in_array($modulepart,array('facture','propal','proposal','order','commande','expedition'))) // This feature is implemented only for such elements { - $printer = (!empty($user->rights->printipp->read) && !empty($conf->printipp->enabled))?true:false; + $printer = (!empty($user->rights->printing->read) && !empty($conf->printing->enabled))?true:false; } $hookmanager->initHooks(array('formfile')); @@ -604,8 +604,8 @@ class FormFile $out.= '<td align="right">'; if ($delallowed) { - $out.= '<a href="'.$urlsource.(strpos($urlsource,'?')?'&':'?').'action=remove_file&file='.urlencode($relativepath); - $out.= ($param?'&'.$param:''); + $out.= '<a href="'.$urlsource.(strpos($urlsource,'?')?'&':'?').'action=remove_file&file='.urlencode($relativepath); + $out.= ($param?'&'.$param:''); //$out.= '&modulepart='.$modulepart; // TODO obsolete ? //$out.= '&urlsource='.urlencode($urlsource); // TODO obsolete ? $out.= '">'.img_picto($langs->trans("Delete"), 'delete.png').'</a>'; @@ -614,9 +614,9 @@ class FormFile if ($printer) { //$out.= '<td align="right">'; - $out.= ' <a href="'.$urlsource.(strpos($urlsource,'?')?'&':'?').'action=print_file&printer='.$modulepart.'&file='.urlencode($relativepath); - $out.= ($param?'&'.$param:''); - $out.= '">'.img_picto($langs->trans("Print"),'printer.png').'</a>'; + $out.= ' <a href="'.$urlsource.(strpos($urlsource,'?')?'&':'?').'action=print_file&printer='.$modulepart.'&file='.urlencode($relativepath); + $out.= ($param?'&'.$param:''); + $out.= '">'.img_picto($langs->trans("PrintFile", $relativepath),'printer.png').'</a>'; } if ($morepicto) { diff --git a/htdocs/core/modules/modPrintIPP.class.php b/htdocs/core/modules/modPrinting.class.php similarity index 59% rename from htdocs/core/modules/modPrintIPP.class.php rename to htdocs/core/modules/modPrinting.class.php index 3cdcd6cdfa65448208942199b75d1dd91cd73bbe..f578c463d43326dac7aba67f19b28f29c10a06eb 100644 --- a/htdocs/core/modules/modPrintIPP.class.php +++ b/htdocs/core/modules/modPrinting.class.php @@ -1,5 +1,6 @@ <?php -/* Copyright (C) 2013 Laurent Destailleur <eldy@users.sourceforge.net> +/* Copyright (C) 2014 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2014 Frederic France <frederic.france@free.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,42 +16,41 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -/** \defgroup printipp Module printipp - * \brief Module pour imprimer via CUPS +/** \defgroup printing Module printing + * \brief Module for activation of printing icon */ /** - * \file htdocs/core/modules/modPrintIPP.class.php - * \ingroup printipp - * \brief Fichier de description et activation du module OSCommerce2 + * \file htdocs/core/modules/modPrinting.class.php + * \ingroup printing + * \brief Fichier de description et activation du module Printing */ -include_once(DOL_DOCUMENT_ROOT ."/core/modules/DolibarrModules.class.php"); +include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * \class modPrintIPP - * \brief Classe de description et activation du module PrintIPP + * \class modPrinting + * \brief Classe de description et activation du module Printing */ -class modPrintIPP extends DolibarrModules +class modPrinting extends DolibarrModules { - - /** - * Constructor - * - * @param DoliDB $db Database handler - */ + /** + * Constructor + * + * @param DoliDB $db Database handler + */ function __construct($db) { $this->db = $db ; - $this->numero = 54000; + $this->numero = 112000; // 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->description = "Enable Printing System."; $this->version = 'dolibarr'; // '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) @@ -64,16 +64,15 @@ class modPrintIPP extends DolibarrModules $this->dirs = array(); // Config pages - $this->config_page_url = array("printipp.php@printipp"); + $this->config_page_url = array("printing.php@printing"); // Dependances - $this->hidden = (! empty($_SERVER["WINDIR"])); $this->depends = array(); $this->requiredby = array(); - $this->phpmin = array(5,1); // Minimum version of PHP required by module - $this->need_dolibarr_version = array(3,7,-2); // Minimum version of Dolibarr required by module + $this->phpmin = array(5,1); // Minimum version of PHP required by module + $this->need_dolibarr_version = array(3,7,-2); // Minimum version of Dolibarr required by module $this->conflictwith = array(); - $this->langfiles = array("printipp"); + $this->langfiles = array("printing"); // Constantes $this->const = array(); @@ -83,7 +82,7 @@ class modPrintIPP extends DolibarrModules // Permissions $this->rights = array(); - $this->rights_class = 'printipp'; + $this->rights_class = 'printing'; $r=0; // $this->rights[$r][0] Id permission (unique tous modules confondus) @@ -94,8 +93,8 @@ class modPrintIPP extends DolibarrModules // $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][0] = 112001; + $this->rights[$r][1] = 'Printing'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 1; $this->rights[$r][4] = 'read'; @@ -106,16 +105,16 @@ class modPrintIPP extends DolibarrModules // This is to declare the Top Menu entry: $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=home,fk_leftmenu=modulesadmintools', // 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. + 'type'=>'left', // This is a Top menu entry + 'titre'=>'Printing', + 'mainmenu'=>'printing', + 'url'=>'/printing/index.php', + 'langs'=>'printing', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>300, - 'enabled'=>'$conf->printipp->enabled && $leftmenu==\'modulesadmintools\'', - 'perms'=>'$user->rights->printipp->read', // Use 'perms'=>'1' if you want your menu with no permission rules + 'enabled'=>'$conf->printing->enabled && $leftmenu==\'modulesadmintools\'', + 'perms'=>'$user->rights->printing->read', // 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 + 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both $r++; @@ -123,13 +122,13 @@ class modPrintIPP extends DolibarrModules } /** - * Function called when module is enabled. - * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. - * It also creates data directories - * - * @param string $options Options when enabling module ('', 'noboxes') - * @return int 1 if OK, 0 if KO - */ + * Function called when module is enabled. + * The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database. + * It also creates data directories + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ function init($options='') { $sql = array(); @@ -137,15 +136,15 @@ class modPrintIPP extends DolibarrModules return $this->_init($sql, $options); } - /** - * Function called when module is disabled. - * Remove from database constants, boxes and permissions from Dolibarr database. - * Data directories are not deleted - * - * @param string $options Options when enabling module ('', 'noboxes') - * @return int 1 if OK, 0 if KO - */ - function remove($options='') + /** + * Function called when module is disabled. + * Remove from database constants, boxes and permissions from Dolibarr database. + * Data directories are not deleted + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function remove($options='') { $sql = array(); diff --git a/htdocs/printipp/admin/index.html b/htdocs/core/modules/printing/index.html similarity index 100% rename from htdocs/printipp/admin/index.html rename to htdocs/core/modules/printing/index.html diff --git a/htdocs/core/modules/printing/modules_printing.php b/htdocs/core/modules/printing/modules_printing.php new file mode 100644 index 0000000000000000000000000000000000000000..3b53711f58c455aff00c418bc215864eef693938 --- /dev/null +++ b/htdocs/core/modules/printing/modules_printing.php @@ -0,0 +1,86 @@ +<?php +/* + * Copyright (C) 2014 Frederic France <frederic.france@free.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/mailings/modules_printing.php + * \ingroup printing + * \brief File with parent class of printing modules + */ +require_once DOL_DOCUMENT_ROOT.'/core/lib/functions.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + +/** + * Parent class of emailing target selectors modules + */ +class PrintingDriver +{ + var $db; + var $error; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + $this->db = $db; + } + + /** + * Return list of printing driver + * + * @param DoliDB $db Database handler + * @param string $maxfilenamelength Max length of value to show + * @return array List of drivers + */ + static function listDrivers($db,$maxfilenamelength=0) + { + global $conf; + + $type='printing'; + $liste=array(); + + $moduledir=DOL_DOCUMENT_ROOT."/core/modules/printing/"; + $tmpfiles=dol_dir_list($moduledir,'all',0,'\modules.php','','name',SORT_ASC,0); + foreach($tmpfiles as $record) { + $list[$record['fullname']]=str_replace('.modules.php', '',$record['name']); + } + + return $list; + } + + /** + * Return description of Printing Module + * + * @return string Return translation of key PrintingModuleDescXXX where XXX is module name, or $this->desc if not exists + */ + function getDesc() + { + global $langs; + $langs->load("printing"); + $transstring="PrintingModuleDesc".$this->name; + if ($langs->trans($transstring) != $transstring) return $langs->trans($transstring); + else return $this->desc; + } + +} + diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php new file mode 100644 index 0000000000000000000000000000000000000000..2d4cb8a2c9811398e3c44331f52be11d76276872 --- /dev/null +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -0,0 +1,355 @@ +<?php +/* + * Copyright (C) 2014 Frederic France <frederic.france@free.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/printing/printgcp.modules.php + * \ingroup printing + * \brief File to provide printing with Google Cloud Print + */ + +include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php'; + +/** + * \class mailing_example + * \brief Class to provide printing with Google Cloud Print + */ +class printing_printgcp extends PrintingDriver +{ + var $name = 'printgcp'; + var $desc = 'PrintGCPDesc'; + var $picto = 'printer'; + var $active = 'PRINTING_PRINTGCP'; + var $conf = array(); + var $login = ''; + var $password = ''; + var $authtoken = ''; + var $db; + + const LOGIN_URL = 'https://www.google.com/accounts/ClientLogin'; + const PRINTERS_SEARCH_URL = 'https://www.google.com/cloudprint/interface/search'; + const PRINT_URL = 'https://www.google.com/cloudprint/interface/submit'; + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf; + + $this->db = $db; + $this->login = $conf->global->PRINTGCP_LOGIN; + $this->password = $conf->global->PRINTGCP_PASSWORD; + $this->authtoken = $conf->global->PRINTGCP_AUTHTOKEN; + $this->conf[] = array('varname'=>'PRINTGCP_LOGIN', 'required'=>1, 'example'=>'user@gmail.com', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTGCP_PASSWORD', 'required'=>1, 'example'=>'', 'type'=>'password'); + } + + /** + * Return list of available printers + * + * @return string html list of printers + */ + function listAvailablePrinters() + { + global $bc, $conf, $langs; + $langs->load('printgcp'); + $var=true; + + $html = '<tr class="liste_titre">'; + $html.= '<td>'.$langs->trans('GCP_Name').'</td>'; + $html.= '<td>'.$langs->trans('GCP_displayName').'</td>'; + $html.= '<td>'.$langs->trans('GCP_Id').'</td>'; + $html.= '<td>'.$langs->trans('GCP_OwnerName').'</td>'; + $html.= '<td>'.$langs->trans('GCP_State').'</td>'; + $html.= '<td>'.$langs->trans('GCP_connectionStatus').'</td>'; + $html.= '<td>'.$langs->trans('GCP_Type').'</td>'; + $html.= '<td align="center">'.$langs->trans("Select").'</td>'; + $html.= '</tr>'."\n"; + $list = $this->getlist_available_printers(); + //$html.= '<td><pre>'.print_r($list,true).'</pre></td>'; + $var = true; + foreach ($list['available'] as $printer_det) + { + $var=!$var; + $html.= "<tr ".$bc[$var].">"; + $html.= '<td>'.$printer_det['name'].'</td>'; + $html.= '<td>'.$printer_det['displayName'].'</td>'; + $html.= '<td>'.$printer_det['id'].'</td>'; // id to identify printer to use + $html.= '<td>'.$printer_det['ownerName'].'</td>'; + $html.= '<td>'.$printer_det['status'].'</td>'; + $html.= '<td>'.$langs->trans('STATE_'.$printer_det['connectionStatus']).'</td>'; + $html.= '<td>'.$langs->trans('TYPE_'.$printer_det['type']).'</td>'; + // Defaut + $html.= '<td align="center">'; + if ($conf->global->PRINTING_GCP_DEFAULT == $printer_det['id']) + { + $html.= img_picto($langs->trans("Default"),'on'); + } + else + $html.= '<a href="'.$_SERVER["PHP_SELF"].'?action=setvalue&mode=test&varname=PRINTING_GCP_DEFAULT&driver=printgcp&value='.urlencode($printer_det['id']).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; + $html.= '</td>'; + $html.= '</tr>'."\n"; + } + + return $html; + } + + /** + * Return list of available printers + * + * @return array list of printers + */ + function getlist_available_printers() + { + global $conf,$db; + if ($this->authtoken=='') { + $this->GoogleLogin(); + } + $ret['available'] = $this->get_printer_detail(); + return $ret; + } + + /** + * List of printers + * + * @return array list of printers + */ + function get_printer_detail() + { + // Check if we have auth token + if(empty($this->authtoken)) { + // We don't have auth token so throw exception + throw new Exception("Please first login to Google by calling loginToGoogle function"); + } + // Prepare auth headers with auth token + $authheaders = array("Authorization: GoogleLogin auth=".$this->authtoken, + "GData-Version: 3.0", + ); + // Make Http call to get printers added by user to Google Cloud Print + $responsedata = $this->makeCurl(self::PRINTERS_SEARCH_URL,array(),$authheaders); + $printers = json_decode($responsedata); + // Check if we have printers? + if(is_null($printers)) { + // We dont have printers so return blank array + return array(); + } else { + // We have printers so returns printers as array + return $this->parsePrinters($printers); + } + } + + /** + * Print selected file + * + * @param string $file file + * @param string $module module + * @param string $subdir subdir for file + * @return string '' if OK, Error message if KO + */ + function print_file($file, $module, $subdir='') + { + global $conf, $user, $db; + if ($this->authtoken=='') { + $this->GoogleLogin(); + } + // si $module=commande_fournisseur alors $conf->fournisseur->commande->dir_output + $fileprint=$conf->{$module}->dir_output; + if ($subdir!='') $fileprint.='/'.$subdir; + $fileprint.='/'.$file; + // select printer uri for module order, propal,... + $sql = 'SELECT rowid, printer_id, copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printgcp" AND userid='.$user->id; + $result = $db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj) + { + $printer_id=$obj->printer_id; + } + else + { + if (! empty($conf->global->PRINTING_GCP_DEFAULT)) + { + $printer_id=$conf->global->PRINTING_GCP_DEFAULT; + } + else + { + return 'NoDefaultPrinterDefined'; + } + } + } + + $this->sendPrintToPrinter($printer_id, $file, $fileprint, 'application/pdf'); + } + + /** + * Sends document to the printer + * + * @param string $printerid Printer id returned by Google Cloud Print + * @param string $printjobtitle Job Title + * @param string $filepath File Path to be send to Google Cloud Print + * @param string $contenttype File content type by example application/pdf, image/png + * @return array status array + */ + public function sendPrintToPrinter($printerid,$printjobtitle,$filepath,$contenttype) + { + $errors=0; + // Check auth token + if(empty($this->authtoken)) { + $errors++; + setEventMessage('Please first login to Google', 'warning'); + } + // Check if printer id + if(empty($printerid)) { + $errors++; + setEventMessage('No provided printer ID', 'warning'); + } + // Open the file which needs to be print + $handle = fopen($filepath, "rb"); + if(!$handle) { + $errors++; + setEventMessage('Could not read the file.'); + } + // Read file content + $contents = fread($handle, filesize($filepath)); + fclose($handle); + // Prepare post fields for sending print + $post_fields = array('printerid' => $printerid, + 'title' => $printjobtitle, + 'contentTransferEncoding' => 'base64', + 'content' => base64_encode($contents), // encode file content as base64 + 'contentType' => $contenttype + ); + // Prepare authorization headers + $authheaders = array("Authorization: GoogleLogin auth=" . $this->authtoken); + // Make http call for sending print Job + $response = json_decode($this->makeCurl(self::PRINT_URL,$post_fields,$authheaders)); + // Has document been successfully sent? + if($response->success=="1") { + return array('status' =>true,'errorcode' =>'','errormessage'=>""); + } else { + return array('status' =>false,'errorcode' =>$response->errorCode,'errormessage'=>$response->message); + } + } + + + /** + * Login into Google Account + * + * @return string true or false + */ + function GoogleLogin() + { + global $db, $conf; + // Prepare post fields required for the login + $loginpostfields = array("accountType" => "HOSTED_OR_GOOGLE", + "Email" => $this->login, + "Passwd" => $this->password, + "service" => "cloudprint", + "source" => "GCP" + ); + // Get the Auth token + $loginresponse = $this->makeCurl(self::LOGIN_URL,$loginpostfields); + $token = $this->getAuthToken($loginresponse); + if(! empty($token)&&!is_null($token)) { + $this->authtoken = $token; + $result=dolibarr_set_const($db, 'PRINTGCP_AUTHTOKEN', $token, 'chaine', 0, '', $conf->entity); + return true; + } else { + return false; + } + + } + + /** + * Parse json response and return printers array + * + * @param string $jsonobj Json response object + * @return array return array of printers + */ + private function parsePrinters($jsonobj) + { + $printers = array(); + if (isset($jsonobj->printers)) { + foreach ($jsonobj->printers as $gcpprinter) { + $printers[] = array('id' =>$gcpprinter->id, + 'name' =>$gcpprinter->name, + 'defaultDisplayName' =>$gcpprinter->defaultDisplayName, + 'displayName' =>$gcpprinter->displayName, + 'ownerId' =>$gcpprinter->ownerId, + 'ownerName' =>$gcpprinter->ownerName, + 'connectionStatus' =>$gcpprinter->connectionStatus, + 'status' =>$gcpprinter->status, + 'type' =>$gcpprinter->type + ); + } + } + return $printers; + } + + /** + * Parse data to get auth token + * + * @param string $response response from curl + * @return string token + */ + private function getAuthToken($response) + { + // Search Auth tag + preg_match("/Auth=([a-z0-9_-]+)/i", $response, $matches); + $authtoken = @$matches[1]; + return $authtoken; + } + + /** + * Curl request + * + * @param string $url url to hit + * @param array $postfields array of post fields + * @param array $headers array of http headers + * @return array response from curl + */ + private function makeCurl($url,$postfields=array(),$headers=array()) + { + // Curl Init + $curl = curl_init($url); + // Curl post request + if(! empty($postfields)) { + // As is HTTP post curl request so set post fields + curl_setopt($curl, CURLOPT_POST, true); + curl_setopt($curl, CURLOPT_POSTFIELDS, $postfields); + } + // Curl request headers + if(! empty($headers)) { + // As curl requires header so set headers here + curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); + } + curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + // Execute the curl and return response + $response = curl_exec($curl); + curl_close($curl); + return $response; + } + + +} diff --git a/htdocs/core/modules/printing/printipp.modules.php b/htdocs/core/modules/printing/printipp.modules.php new file mode 100644 index 0000000000000000000000000000000000000000..c8a19bffa313c06225fe00bf6523f00870c69848 --- /dev/null +++ b/htdocs/core/modules/printing/printipp.modules.php @@ -0,0 +1,284 @@ +<?php +/* + * Copyright (C) 2014 Frederic France <frederic.france@free.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * or see http://www.gnu.org/ + */ + +/** + * \file htdocs/core/modules/printing/printipp.modules.php + * \ingroup mailing + * \brief File to provide printing with PrintIPP + */ + +include_once DOL_DOCUMENT_ROOT.'/core/modules/printing/modules_printing.php'; + +/** + * \class mailing_example + * \brief Class to provide printing with PrintIPP + */ +class printing_printipp extends PrintingDriver +{ + var $name='printipp'; + var $desc='PrintIPPDesc'; + var $picto='printer'; + var $active='PRINTING_PRINTIPP'; + var $conf=array(); + var $host; + var $port; + var $userid; /* user login */ + var $user; + var $password; + var $error; + var $db; + + + /** + * Constructor + * + * @param DoliDB $db Database handler + */ + function __construct($db) + { + global $conf; + + $this->db=$db; + $this->host=$conf->global->PRINTIPP_HOST; + $this->port=$conf->global->PRINTIPP_PORT; + $this->user=$conf->global->PRINTIPP_USER; + $this->password=$conf->global->PRINTIPP_PASSWORD; + $this->conf[] = array('varname'=>'PRINTIPP_HOST', 'required'=>1, 'example'=>'localhost', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTIPP_PORT', 'required'=>1, 'example'=>'631', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTIPP_USER', 'required'=>0, 'example'=>'', 'type'=>'text'); + $this->conf[] = array('varname'=>'PRINTIPP_PASSWORD', 'required'=>0, 'example'=>'', 'type'=>'password'); + } + + /** + * Print selected file + * + * @param string $file file + * @param string $module module + * @param string $subdir subdirectory of document like for expedition subdir is sendings + * + * @return string '' if OK, Error message if KO + */ + function print_file($file, $module, $subdir='') + { + global $conf, $user, $db; + + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setJobName($file,true); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + + // select printer uri for module order, propal,... + $sql = 'SELECT rowid,printer_id,copy FROM '.MAIN_DB_PREFIX.'printing WHERE module="'.$module.'" AND driver="printipp" AND userid='.$user->id; + $result = $db->query($sql); + if ($result) + { + $obj = $this->db->fetch_object($result); + if ($obj) + { + $ipp->setPrinterURI($obj->printer_id); + } + else + { + if (! empty($conf->global->PRINTIPP_URI_DEFAULT)) + { + $ipp->setPrinterURI($conf->global->PRINTIPP_URI_DEFAULT); + } + else + { + return 'NoDefaultPrinterDefined'; + } + } + } + + // Set number of copy + $ipp->setCopies($obj->copy); + $fileprint=$conf->{$module}->dir_output; + if ($subdir!='') $fileprint.='/'.$subdir; + $fileprint.='/'.$file; + $ipp->setData($fileprint); + $ipp->printJob(); + + return ''; + } + + /** + * Return list of available printers + * + * @return string html list of printers + */ + function listAvailablePrinters() + { + global $bc, $conf, $langs; + $var=true; + + $html = '<tr class="liste_titre">'; + $html.= '<td>'.$langs->trans('IPP_Uri').'</td>'; + $html.= '<td>'.$langs->trans('IPP_Name').'</td>'; + $html.= '<td>'.$langs->trans('IPP_State').'</td>'; + $html.= '<td>'.$langs->trans('IPP_State_reason').'</td>'; + $html.= '<td>'.$langs->trans('IPP_State_reason1').'</td>'; + $html.= '<td>'.$langs->trans('IPP_BW').'</td>'; + $html.= '<td>'.$langs->trans('IPP_Color').'</td>'; + //$html.= '<td>'.$langs->trans('IPP_Device').'</td>'; + $html.= '<td>'.$langs->trans('IPP_Media').'</td>'; + $html.= '<td>'.$langs->trans('IPP_Supported').'</td>'; + $html.= '<td align="center">'.$langs->trans("Select").'</td>'; + $html.= "</tr>\n"; + $list = $this->getlist_available_printers(); + $var = true; + foreach ($list as $value) + { + $var=!$var; + $printer_det = $this->get_printer_detail($value); + $html.= "<tr ".$bc[$var].">"; + $html.= '<td>'.$value.'</td>'; + //$html.= '<td><pre>'.print_r($printer_det,true).'</pre></td>'; + $html.= '<td>'.$printer_det->printer_name->_value0.'</td>'; + $html.= '<td>'.$langs->trans('STATE_IPP_'.$printer_det->printer_state->_value0).'</td>'; + $html.= '<td>'.$langs->trans('STATE_IPP_'.$printer_det->printer_state_reasons->_value0).'</td>'; + $html.= '<td>'.(! empty($printer_det->printer_state_reasons->_value1)?$langs->trans('STATE_IPP_'.$printer_det->printer_state_reasons->_value1):'').'</td>'; + $html.= '<td>'.$langs->trans('IPP_COLOR_'.$printer_det->printer_type->_value2).'</td>'; + $html.= '<td>'.$langs->trans('IPP_COLOR_'.$printer_det->printer_type->_value3).'</td>'; + //$html.= '<td>'.$printer_det->device_uri->_value0.'</td>'; + $html.= '<td>'.$printer_det->media_default->_value0.'</td>'; + $html.= '<td>'.$langs->trans('MEDIA_IPP_'.$printer_det->media_type_supported->_value1).'</td>'; + // Defaut + $html.= '<td align="center">'; + if ($conf->global->PRINTIPP_URI_DEFAULT == $value) + { + $html.= img_picto($langs->trans("Default"),'on'); + } + else + $html.= '<a href="'.$_SERVER["PHP_SELF"].'?action=setvalue&mode=test&varname=PRINTIPP_URI_DEFAULT&driver=printipp&value='.urlencode($value).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; + $html.= '</td>'; + $html.= '</tr>'."\n"; + } + + return $html; + } + + /** + * 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.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + $ipp->getPrinters(); + return $ipp->available_printers; + } + + /** + * Get printer detail + * + * @param string $uri URI + * @return array List of attributes + */ + function get_printer_detail($uri) + { + global $conf,$db; + + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + $ipp->setPrinterURI($uri); + $ipp->getPrinterAttributes(); + return $ipp->printer_attributes; + } + + /** + * List jobs print + * + * @param string $module module + * + * @return void + */ + function list_jobs($module) + { + global $conf, $db, $bc; + include_once DOL_DOCUMENT_ROOT.'/includes/printipp/CupsPrintIPP.php'; + $ipp = new CupsPrintIPP(); + $ipp->setLog(DOL_DATA_ROOT.'/dolibarr_printipp.log','file',3); // logging very verbose + $ipp->setHost($this->host); + $ipp->setPort($this->port); + $ipp->setUserName($this->userid); + if (! empty($this->user)) $ipp->setAuthentication($this->user,$this->password); + // 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/"); + } + } + // Getting Jobs + $ipp->getJobs(false,0,'completed',false); + print '<table width="100%" class="noborder">'; + print '<tr class="liste_titre">'; + print "<td>Id</td>"; + print "<td>Owner</td>"; + print "<td>Printer</td>"; + print "<td>File</td>"; + print "<td>Status</td>"; + print "<td>Cancel</td>"; + print "</tr>\n"; + $jobs = $ipp->jobs_attributes; + $var = True; + //print '<pre>'.print_r($jobs,true).'</pre>'; + foreach ($jobs as $value ) + { + $var=!$var; + print "<tr ".$bc[$var].">"; + print '<td>'.$value->job_id->_value0.'</td>'; + print '<td>'.$value->job_originating_user_name->_value0.'</td>'; + print '<td>'.$value->printer_uri->_value0.'</td>'; + print '<td>'.$value->job_name->_value0.'</td>'; + print '<td>'.$value->job_state->_value0.'</td>'; + print '<td>'.$value->job_uri->_value0.'</td>'; + print '</tr>'; + } + print "</table>"; + } + +} diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index 7ccd24f871bafc2ebcd8abd0c650b7ddb3f0e3b5..29260ba3bb61b7f72cf519ea45229f90fa16209b 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -429,6 +429,8 @@ if (GETPOST('removedfile','alpha')) $action ='presend'; } +include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php'; + /* * Send mail */ diff --git a/htdocs/includes/printipp/BasicIPP.php b/htdocs/includes/printipp/BasicIPP.php index 3869c75bc06fdb01ca8617543591a156c0166273..1cc7851fab2e796db2d915625ac6ee0c3072c6c0 100644 --- a/htdocs/includes/printipp/BasicIPP.php +++ b/htdocs/includes/printipp/BasicIPP.php @@ -1,6 +1,6 @@ <?php -/* vim: set expandtab tabstop=2 shiftwidth=2 foldmethod=marker: */ -/* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/BasicIPP.php,v 1.6 2010/08/22 15:45:17 harding Exp $ + +/* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/BasicIPP.php,v 1.7 2012/03/01 17:21:04 harding Exp $ * * Class BasicIPP - Send Basic IPP requests, Get and parses IPP Responses. * @@ -35,1966 +35,1948 @@ - RFC 3380 - RFC 3382 */ -/* - TODO: beta tests on other servers than Cups - */ -// required and included files + require_once ("http_class.php"); -/* -// If you want http backend from http://www.phpclasses.org/browse/package/3.html -require_once("HTTP/http.php"); -include_once("SASL/sasl.php"); -include_once("SASL/basic_sasl_client.php"); -include_once("SASL/digest_sasl_client.php"); -include_once("SASL/ntlm_sasl_client.php"); - */ -/** - * Class and Function List: - * Function list: - * - __construct() - * - getErrorFormatted() - * - getErrno() - * - setPort() - * - setUnix() - * - setHost() - * - setTimeout() - * - setPrinterURI() - * - setData() - * - setRawText() - * - unsetRawText() - * - setBinary() - * - setFormFeed() - * - unsetFormFeed() - * - setCharset() - * - setLanguage() - * - setDocumentFormat() - * - setMimeMediaType() - * - setCopies() - * - setDocumentName() - * - setJobName() - * - setUserName() - * - setAuthentification() - * - setAuthentication() - * - setSides() - * - setFidelity() - * - unsetFidelity() - * - setMessage() - * - setPageRanges() - * - setAttribute() - * - unsetAttribute() - * - setLog() - * - printDebug() - * - getDebug() - * - printJob() - * - _sendHttp() - * - _initTags() - * - _setOperationId() - * - _setJobId() - * - _setJobUri() - * - _parseServerOutput() - * - _parseHttpHeaders() - * - _parseIppVersion() - * - _parseStatusCode() - * - _parseRequestID() - * - _interpretInteger() - * - _parseResponse() - * - _stringJob() - * - _buildValues() - * - _giveMeStringLength() - * - _enumBuild() - * - _integerBuild() - * - _rangeOfIntegerBuild() - * - _setJobAttribute() - * - _setOperationAttribute() - * - _setPrinterAttribute() - * - _putDebug() - * - _errorLog() - * Classes list: - * - ippException extends Exception - * - BasicIPP - */ -/*********************** - * - * ippException class - * - ************************/ -class ippException extends Exception + +class ippException extends \Exception { - protected $errno; - public function __construct($msg, $errno = null) - { - parent::__construct($msg); - $this->errno = $errno; - } - public function getErrorFormatted() - { - $return = sprintf("[ipp]: %s -- " . _(" file %s, line %s"), - $this->getMessage() , $this->getFile() , $this->getLine()); - return $return; - } - public function getErrno() - { - return $this->errno; - } + protected $errno; + + public function __construct($msg, $errno = null) + { + parent::__construct($msg); + $this->errno = $errno; + } + + public function getErrorFormatted() + { + $return = sprintf("[ipp]: %s -- " . _(" file %s, line %s"), + $this->getMessage() , $this->getFile() , $this->getLine()); + return $return; + } + + public function getErrno() + { + return $this->errno; + } } class BasicIPP { - // - // variables declaration - // - - // setup variables - - public $paths = array( - "root" => "/", - "admin" => "/admin/", - "printers" => "/printers/", - "jobs" => "/jobs/" - ); - public $http_timeout = 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) + 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 $printer_map = array(); + public $printers_uri = array(); + public $debug = array(); + public $response; + public $meta; + + // 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 $requesting_user = ''; + protected $printer_uri; + protected $timeout = "20"; //20 secs + protected $errNo; + protected $errStr; + protected $datatype; + protected $datahead; + protected $datatail; + 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 + protected $output; + + public function __construct() { - self::_setOperationAttribute($attribute, $value); + $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(); } - } - } - elseif (in_array($attribute, $job_attributes_tags)) - { - if (!is_array($values)) - { - self::_setJobAttribute($attribute, $values); - } - else - { - foreach($values as $value) + + public function setPort($port = '631') { - self::_setJobAttribute($attribute, $value); + $this->port = $port; + self::_putDebug("Port is " . $this->port, 2); } - } - } - elseif (in_array($attribute, $printer_attributes_tags)) - { - if (!is_array($values)) - { - self::_setPrinterAttribute($attribute, $values); - } - else - { - foreach($values as $value) + + public function setUnix($socket = '/var/run/cups/cups.sock') { - self::_setPrinterAttribute($attribute, $value); + $this->host = $socket; + $this->unix = true; + self::_putDebug("Host is " . $this->host, 2); } - } - } - 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++) + + public function setHost($host = 'localhost') { - $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]); - } + $this->host = $host; + $this->unix = false; + self::_putDebug("Host is " . $this->host, 2); } - 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++) + + public function setTimeout($timeout) { - $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++; - } + $this->timeout = $timeout; } - self::_putDebug("\n\nResponse body:\n"); - $this->serveroutput->body = ""; - for (;;) + + public function setPrinterURI($uri) { - $http->ReadReplyBody($body, 1024); - if (strlen($body) == 0) break; + $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; + } - self::_putDebug(htmlentities($body)); - $this->serveroutput->body.= $body; + 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); } - 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) + public function unsetFormFeed() { - 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++; + $this->datatail = ''; + $this->setup->noFormFeed = 1; } - } - } - $jobattributes = ''; - foreach($this->job_tags as $key => $values) - { - $item = 0; - if (array_key_exists('value', $values)) - { - foreach($values['value'] as $item_value) + + public function setCharset($charset = 'utf-8') { - 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++; + $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; } - } - } - $printerattributes = ''; - foreach($this->printer_tags as $key => $values) - { - $item = 0; - if (array_key_exists('value', $values)) - { - foreach($values['value'] as $item_value) + + public function setLanguage($language = 'en_us') { - 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++; + $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; } - } - } - 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) + + public function setDocumentFormat($mime_media_type = 'application/octet-stream') { - case 'portrait': - $value = chr(3); - break; + 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); + } - case 'landscape': - $value = chr(4); - break; + 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; + } - case 'reverse-landscape': - $value = chr(5); - break; + 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 - case 'reverse-portrait': - $value = chr(6); - break; } - break; - case "print-quality": - switch ($value) + public function setJobName($jobname = '', $absolute = false) { - case 'draft': - $value = chr(3); - break; + $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; + } - case 'normal': - $value = chr(4); - break; + 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; + } - case 'high': - $value = chr(5); - break; + public function setAuthentification($username, $password) + { + self::setAuthentication($username, $password); } - break; - case "finishing": - switch ($value) + public function setAuthentication($username, $password) { - case 'none': - $value = chr(3); - break; + $this->password = $password; + $this->username = $username; + self::_putDebug(_("Setting password") , 2); + $this->setup->password = 1; + } - case 'staple': - $value = chr(4); - break; + 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; + } + + $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); + } - case 'punch': - $value = chr(5); - break; + 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); + } - case 'cover': - $value = chr(6); - break; + 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); + } - case 'bind': - $value = chr(7); - break; + 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); + } - case 'saddle-stitch': - $value = chr(8); - break; + 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; + } + } + } - case 'edge-stitch': - $value = chr(9); - break; + 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; + } + } - case 'staple-top-left': - $value = chr(20); - break; + 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 + // + /** + * Sets log file destination. Creates the file if has permission. + * + * @param string $log_destination + * @param string $destination_type + * @param int $level + * + * @throws ippException + */ + public function setLog($log_destination, $destination_type = 'file', $level = 2) + { + if (!file_exists($log_destination) && is_writable(dirname($log_destination))) + { + touch($log_destination); + chmod($log_destination, 0777); + } + + 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; + } + + // + // 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; + } - case 'staple-bottom-left': - $value = chr(21); - break; + // + // 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" + ) + ); + } - case 'staple-top-right': - $value = chr(22); - break; + // + // 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); + } - case 'staple-bottom-right': - $value = chr(23); - break; + 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; + } - case 'edge-stitch-left': - $value = chr(24); - break; + 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); + } - case 'edge-stitch-top': - $value = chr(25); - break; + // + // 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; + } - case 'edge-stitch-right': - $value = chr(26); - break; + 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; + } - case 'edge-stitch-bottom': - $value = chr(27); - break; + 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; + } - case 'staple-dual-left': - $value = chr(28); - break; + 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; + } - case 'staple-dual-top': - $value = chr(29); - break; + 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; + } - case 'staple-dual-right': - $value = chr(30); - break; + 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; + } - case 'staple-dual-bottom': - $value = chr(31); - break; + protected function _parseResponse() + { } - 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|-)#' + + // + // REQUEST BUILDING + // + protected function _stringJob() + { + if (!isset($this->setup->charset)) { + self::setCharset(); + } + 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) ); - $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: - */ -?> + 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 'boolean': + 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; + } +} diff --git a/htdocs/includes/printipp/CupsPrintIPP.php b/htdocs/includes/printipp/CupsPrintIPP.php index a7e5a305da55d72fe3d4f4e1019a6db6649ed35a..7808c64a7221088d0b8ee6fb5ab375f622f98399 100644 --- a/htdocs/includes/printipp/CupsPrintIPP.php +++ b/htdocs/includes/printipp/CupsPrintIPP.php @@ -1,5 +1,5 @@ <?php -/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ + /* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/CupsPrintIPP.php,v 1.1 2008/06/21 00:30:56 harding Exp $ * * Class PrintIPP - Send extended IPP requests. @@ -22,11 +22,10 @@ * * mailto:thomas.harding@laposte.net * Thomas Harding, 56 rue de la bourie rouge, 45 000 ORLEANS -- FRANCE - * + * */ - -/* +/* This class is intended to implement Internet Printing Protocol on client side. References needed to debug / add functionnalities: @@ -39,57 +38,64 @@ require_once("ExtendedPrintIPP.php"); -class CupsPrintIPP extends ExtendedPrintIPP { - - // {{{ variables declaration - +class CupsPrintIPP extends ExtendedPrintIPP +{ public $printers_attributes; public $defaults_attributes; - - // }}} - // {{{ constructor - public function __construct() { + protected $parsed; + protected $output; + + public function __construct() + { parent::__construct(); self::_initTags(); } - // }}} // // OPERATIONS // + public function cupsGetDefaults($attributes=array("all")) + { + //The CUPS-Get-Default operation returns the default printer URI and attributes - // {{{ cupsGetDefaults ($attributes="all") - public function cupsGetDefaults($attributes=array("all")) { - //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'); - + { + self::setCharset(); + } + 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 + } + } + + $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 @@ -97,69 +103,83 @@ class CupsPrintIPP extends ExtendedPrintIPP { . $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::_sendHttp ($post_values,'/')) + { + if(self::_parseServerOutput()) + { self::_parsePrinterAttributes(); } - + } + $this->attributes = &$this->printer_attributes; - - if (isset($this->printer_attributes->printer_type)) { + + 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++ ) { + + 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)) { - + 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 { + } + + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting defaults : OPERATION FAILED",1); } - return false; + return false; } - // }}} - - // {{{ cupsAcceptJobs ($printer_uri) - public function 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'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en'); - + } + self::_setOperationId(); - - $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 + + $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 @@ -171,65 +191,80 @@ class CupsPrintIPP extends ExtendedPrintIPP { . 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::_sendHttp ($post_values,'/admin/')) + { + if(self::_parseServerOutput()) + { self::_parseAttributes(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + 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 { + } + + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting defaults : OPERATION FAILED",1); } - return false; + return false; } - // }}} - // {{{ cupsRejectJobs ($printer_uri,$printer_state_message=false) - public function cupsRejectJobs($printer_uri,$printer_state_message) { + + 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'); - + { + self::setCharset(); + } + 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 + $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 @@ -242,89 +277,111 @@ class CupsPrintIPP extends ExtendedPrintIPP { . $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::_sendHttp ($post_values,'/admin/')) + { + if(self::_parseServerOutput()) + { self::_parseAttributes(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + 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 { + } + + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting defaults : OPERATION FAILED",1); - } - return false; + } + return false; } - // }}} - // {{{ getPrinters() - public function getPrinters($printer_location=false,$printer_info=false,$attributes=array()) { - + + 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'); + { + true; + } + $attributes=array('printer-uri-supported', 'printer-location', 'printer-info', 'printer-type', 'color-supported', 'printer-name'); $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'); - + { + self::setCharset(); + } + 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 + $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 @@ -332,78 +389,89 @@ class CupsPrintIPP extends ExtendedPrintIPP { . $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::_sendHttp ($post_values,'/')) + { + if(self::_parseServerOutput()) + { $this->_getAvailablePrinters(); - } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + 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 { + } + return $this->serveroutput->status; + } + else + { $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("getting printers : OPERATION FAILED",1); - } - return false; + } + return false; } - // }}} - // {{{ cupsGetPrinters () - public function cupsGetPrinters () { - // alias for getPrinters(); + + public function cupsGetPrinters () + { + // alias for getPrinters(); self::getPrinters(); } - // }}} - // {{{ getPrinterAttributes() - public function getPrinterAttributes() { - // complete informations from parent with Cups-specific stuff - + + 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)) { + } + + 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++ ) { + + for($i = 0 ; $i < count($table) ; $i++ ) + { $index = '_value'.$i; $this->printer_attributes->printer_type->$index = $table[$i]; - } } + } - return $result; + return $result; } - // }}} // // SETUP // - - // {{{ _initTags () - protected function _initTags () { - + protected function _initTags () + { // override parent with specific cups attributes - - $operation_tags = array (); + + $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"), @@ -430,25 +498,23 @@ class CupsPrintIPP extends ExtendedPrintIPP { "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) { - + // + // REQUEST BUILDING + // + protected function _enumBuild ($tag,$value) + { $value_built = parent::_enumBuild($tag,$value); - - switch ($tag) { - case "cpi": - switch ($value) { + switch ($tag) + { + case "cpi": + switch ($value) + { case '10': $value_built = chr(10); break; @@ -463,7 +529,8 @@ class CupsPrintIPP extends ExtendedPrintIPP { } break; case "lpi": - switch ($value) { + switch ($value) + { case '6': $value_built = chr(6); break; @@ -479,60 +546,66 @@ class CupsPrintIPP extends ExtendedPrintIPP { $prepend = ''; while ((strlen($value_built) + strlen($prepend)) < 4) $prepend .= chr(0); - return $prepend.$value_built; + return $prepend.$value_built; } - // }}} - -// -// RESPONSE PARSING -// - // {{{ _getAvailablePrinters () - private function _getAvailablePrinters () { - + // + // RESPONSE PARSING + // + private function _getAvailablePrinters () + { $this->available_printers = array(); + $this->printer_map = array(); $k = 0; - $this->printers_attributes = new stdClass(); + $this->printers_attributes = new \stdClass(); for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++) - if (($this->serveroutput->response[$i]['attributes']) == "printer-attributes") { + { + 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++) { - + $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) { + + 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++ ) { + $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; + case 'printer_name': + $this->printer_map[$value] = $k; + break; default: $this->printers_attributes->$phpname->$name = $value; break; - } - - } - $k ++; + } } + $k ++; + } + } } - // }}} - - // {{{ _getEnumVendorExtensions - protected function _getEnumVendorExtensions ($value_parsed) { - switch ($value_parsed) { + + protected function _getEnumVendorExtensions ($value_parsed) + { + switch ($value_parsed) + { case 0x4002: $value = 'Get-Availables-Printers'; break; @@ -541,110 +614,152 @@ class CupsPrintIPP extends ExtendedPrintIPP { break; } - if (isset($value)) - return ($value); - - return sprintf('Unknown: 0x%x',$value_parsed); + if (isset($value)) + { + return ($value); + } + + return sprintf('Unknown: 0x%x',$value_parsed); } - // }}} - // {{{ _interpretPrinterType($type) - private function _interpretPrinterType($value) { + + 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) { + + if ($value_parsed %2 == 1) + { $type[0] = 'printer-class'; $value_parsed -= 1; - } - if ($value_parsed %4 == 2 ) { + } + + if ($value_parsed %4 == 2 ) + { $type[1] = 'remote-destination'; $value_parsed -= 2; - } - if ($value_parsed %8 == 4 ) { + } + + if ($value_parsed %8 == 4 ) + { $type[2] = 'print-black'; $value_parsed -= 4; - } - if ($value_parsed %16 == 8 ) { + } + + if ($value_parsed %16 == 8 ) + { $type[3] = 'print-color'; $value_parsed -= 8; - } - if ($value_parsed %32 == 16) { + } + + if ($value_parsed %32 == 16) + { $type[4] = 'hardware-print-on-both-sides'; $value_parsed -= 16; - } - if ($value_parsed %64 == 32) { + } + + if ($value_parsed %64 == 32) + { $type[5] = 'hardware-staple-output'; $value_parsed -= 32; - } - if ($value_parsed %128 == 64) { + } + + if ($value_parsed %128 == 64) + { $type[6] = 'hardware-fast-copies'; $value_parsed -= 64; - } - if ($value_parsed %256 == 128) { + } + + if ($value_parsed %256 == 128) + { $type[7] = 'hardware-fast-copy-collation'; $value_parsed -= 128; - } - if ($value_parsed %512 == 256) { + } + + if ($value_parsed %512 == 256) + { $type[8] = 'punch-output'; $value_parsed -= 256; - } - if ($value_parsed %1024 == 512) { + } + + if ($value_parsed %1024 == 512) + { $type[9] = 'cover-output'; $value_parsed -= 512; - } - if ($value_parsed %2048 == 1024) { + } + + if ($value_parsed %2048 == 1024) + { $type[10] = 'bind-output'; $value_parsed -= 1024; - } - if ($value_parsed %4096 == 2048) { + } + + if ($value_parsed %4096 == 2048) + { $type[11] = 'sort-output'; $value_parsed -= 2048; - } - if ($value_parsed %8192 == 4096) { + } + + if ($value_parsed %8192 == 4096) + { $type[12] = 'handle-media-up-to-US-Legal-A4'; $value_parsed -= 4096; - } - if ($value_parsed %16384 == 8192) { + } + + 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) { + } + + if ($value_parsed %32768 == 16384) + { $type[14] = 'handle-media-larger-than-ISO_C-A2'; $value_parsed -= 16384; - } - if ($value_parsed %65536 == 32768) { + } + + if ($value_parsed %65536 == 32768) + { $type[15] = 'handle-user-defined-media-sizes'; $value_parsed -= 32768; - } - if ($value_parsed %131072 == 65536) { + } + + if ($value_parsed %131072 == 65536) + { $type[16] = 'implicit-server-generated-class'; $value_parsed -= 65536; - } - if ($value_parsed %262144 == 131072) { + } + + if ($value_parsed %262144 == 131072) + { $type[17] = 'network-default-printer'; $value_parsed -= 131072; - } - if ($value_parsed %524288 == 262144) { + } + + if ($value_parsed %524288 == 262144) + { $type[18] = 'fax-device'; $value_parsed -= 262144; - } - return $type; + } + + return $type; } - // }}} - // {{{ _interpretEnum() - protected function _interpretEnum($attribute_name,$value) { - + + protected function _interpretEnum($attribute_name,$value) + { $value_parsed = self::_interpretInteger($value); - - switch ($attribute_name) { + + switch ($attribute_name) + { case 'cpi': case 'lpi': $value = $value_parsed; @@ -652,20 +767,8 @@ class CupsPrintIPP extends ExtendedPrintIPP { default: $value = parent::_interpretEnum($attribute_name,$value); break; - } - - - return $value; - } - // }}} - -}; + } -/* - * Local variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ -?> + return $value; + } +} \ No newline at end of file diff --git a/htdocs/includes/printipp/ExtendedPrintIPP.php b/htdocs/includes/printipp/ExtendedPrintIPP.php index e736f4bd972ad47f15157518a265cd46dd8400d1..3effacb828fada4dd11db1791939bc4be5f9fe4c 100644 --- a/htdocs/includes/printipp/ExtendedPrintIPP.php +++ b/htdocs/includes/printipp/ExtendedPrintIPP.php @@ -1,5 +1,5 @@ <?php -/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ + /* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/ExtendedPrintIPP.php,v 1.1 2008/06/21 00:30:57 harding Exp $ * * Class PrintIPP - Send extended IPP requests. @@ -43,113 +43,118 @@ require_once("PrintIPP.php"); -class ExtendedPrintIPP extends PrintIPP { - - - // {{{ constructor - public function __construct() { +class ExtendedPrintIPP extends PrintIPP +{ + public function __construct() + { parent::__construct(); } - // }}} - - -/****************** -* -* PUBLIC FUNCTIONS -* -*******************/ - -// OPERATIONS - // {{{ printURI ($uri) - public function printURI ($uri) { + // OPERATIONS + public function printURI ($uri) + { self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); - if (!empty($uri)) { + if (!empty($uri)) + { $this->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()) { + + 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)) { - + + 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 { + } + 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; } - + return $this->serveroutput->status; + } + $this->status = array_merge($this->status,array("OPERATION FAILED")); self::_errorLog("printing uri $uri : OPERATION FAILED",1); - - return false; + + return false; } - // }}} - // {{{ purgeJobs() - public function 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)) { + + 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 { + } + 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'); - + { + self::setCharset(); + } + 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 @@ -164,116 +169,141 @@ class ExtendedPrintIPP extends PrintIPP { . 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'])) { + + if (self::_sendHttp ($post_values,$this->paths['admin'])) + { self::_parseServerOutput(); self::_parseAttributes(); } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + 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() { - + return false; + } + public function createJob() + { self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + 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 { + } + 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'); - + { + self::setCharset(); + } + 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 @@ -292,40 +322,44 @@ class ExtendedPrintIPP extends PrintIPP { . $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()) { + { + if(self::_parseServerOutput()) + { $this->_getJobId(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + 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)) { - + 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 { + } + else + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); @@ -333,186 +367,207 @@ class ExtendedPrintIPP extends PrintIPP { } 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; + return false; } - // }}} - - // {{{ sendDocument($job) - public function sendDocument($job,$is_last=false){ - + 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)){ + } + + 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" - - + { + $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 { + } + } + 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()) { + } + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + + if(self::_parseServerOutput()) + { $this->_getJobId(); //$this->_getPrinterUri(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + 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)) { - + 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 { + } + 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; - } + 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; + + return false; } - // }}} - // {{{ sendURI ($uri,$job,$is_last=false) - public function 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()) { + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + if(self::_parseServerOutput()) + { $this->_getJobId(); //$this->_getPrinterUri(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + 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)) { - + 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 { + } + 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; - } + 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; + + return false; } - // }}} - // {{{ pausePrinter () - public function 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)) { + + 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 { + } + 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'); - + { + self::setCharset(); + } + 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 @@ -527,81 +582,94 @@ class ExtendedPrintIPP extends PrintIPP { . 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'])) { + + if (self::_sendHttp ($post_values,$this->paths['admin'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } + } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + 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; + + return false; } - // }}} - // {{{ resumePrinter () - public function 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)) { + + 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 { + } + 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'); - + { + self::setCharset(); + } + 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 @@ -611,82 +679,97 @@ class ExtendedPrintIPP extends PrintIPP { . $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'])) { + + if (self::_sendHttp ($post_values,$this->paths['admin'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } + } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + 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; + + return false; } - // }}} - // {{{ holdJob ($job_uri) - public function holdJob ($job_uri,$until='indefinite') { - + + 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'); - + { + self::setCharset(); + } + 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 @@ -698,68 +781,81 @@ class ExtendedPrintIPP extends PrintIPP { . $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'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { + 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; + + return false; } - // }}} - - // {{{ releaseJob ($job_uri) - public function 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'); - + { + self::setCharset(); + } + 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 @@ -770,75 +866,85 @@ class ExtendedPrintIPP extends PrintIPP { . $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'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + 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; + + return false; } - // }}} - - // {{{ restartJob ($job_uri) - public function 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'); - + { + self::setCharset(); + } + 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 @@ -850,92 +956,110 @@ class ExtendedPrintIPP extends PrintIPP { . $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'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + + 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; + + return false; } - // }}} - - // {{{ setJobAttributes ($job_uri,$deleted_attributes=array()) - public function 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'); - + { + self::setCharset(); + } + 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->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 @@ -952,47 +1076,52 @@ class ExtendedPrintIPP extends PrintIPP { . $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'])) { + + if (self::_sendHttp ($post_values,$this->paths['jobs'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + 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; + + return false; } - // }}} - - // {{{ setPrinterAttributes () - public function setPrinterAttributes ($document_format='',$deleted_attributes=array()) { + + + 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 @@ -1010,55 +1139,72 @@ class ExtendedPrintIPP extends PrintIPP { 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'); - + { + self::setCharset(); + } + 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 + . 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; - - + . 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 @@ -1076,144 +1222,176 @@ class ExtendedPrintIPP extends PrintIPP { . $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'])) { + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { self::_parseServerOutput(); self::_parseAttributes(); - } - if (isset($this->serveroutput) && isset($this->serveroutput->status)) { - + } + 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 + return false; + } - // {{{ _setDocumentUri ($job_uri) - protected function _setDocumentUri () { - + // REQUEST BUILDING + 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 () { - + + protected function _stringUri () + { self::_setDocumentUri(); - - if (!isset($this->setup->document_uri)) { + + 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)) { + + 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 { + } + 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)) { + } + 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 @@ -1234,72 +1412,98 @@ class ExtendedPrintIPP extends PrintIPP { . $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) { - + + + 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'); + { + self::setCharset(); + } if (!isset($this->setup->datatype)) + { self::setBinary(); + } - if (!isset($this->setup->uri)) { + 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 { + } + 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 @@ -1322,84 +1526,107 @@ class ExtendedPrintIPP extends PrintIPP { . 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) { - + + protected function _stringSendUri ($uri,$job,$is_last) + { $this->document_uri = $uri; self::_setDocumentUri(); - - if (!isset($this->setup->document_uri)) { + + 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'); + { + self::setCharset(); + } if (!isset($this->setup->datatype)) + { self::setBinary(); + } - if (!isset($this->setup->uri)) { + 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 { + } + 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 @@ -1422,20 +1649,8 @@ class ExtendedPrintIPP extends PrintIPP { . 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: - */ -?> +} \ No newline at end of file diff --git a/htdocs/includes/printipp/PrintIPP.php b/htdocs/includes/printipp/PrintIPP.php index 9ed502c2d112e27e175fb368762a50c66735826c..ffda9e8f1f71291ae4d2b1806ea30771c530628c 100644 --- a/htdocs/includes/printipp/PrintIPP.php +++ b/htdocs/includes/printipp/PrintIPP.php @@ -1,5 +1,5 @@ <?php -/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */ + /* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/PrintIPP.php,v 1.3 2010/09/06 22:41:41 harding Exp $ * * Class PrintIPP - Send IPP requests, Get and parses IPP Responses. @@ -40,58 +40,49 @@ TODO: beta tests on other servers than Cups */ +require_once("BasicIPP.php"); - // {{{ required and included files - - require_once("BasicIPP.php"); - - // }}} - - -class PrintIPP extends BasicIPP { - - // {{{ constructor - public function __construct() { +class PrintIPP extends BasicIPP +{ + public function __construct() + { parent::__construct(); } - // }}} - -/***************** -* -* PUBLIC FUNCTIONS -* -*******************/ -// SETTINGS // OPERATIONS - - // {{{ printJob() - public function printJob(){ - + public function printJob() + { self::_putDebug( sprintf("*************************\nDate: %s\n*************************\n\n",date('Y-m-d H:i:s'))); if (!$this->_stringJob()) + { return FALSE; - - if (is_readable($this->data)){ + } + + 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 { + } + } + else + { self::_putDebug( _("Printing DATA\n"),3); - + $this->output = $this->stringjob; $this->output .= $this->datahead; $this->output .= $this->data; @@ -99,25 +90,25 @@ class PrintIPP extends BasicIPP { $post_values = array( "Content-Type" => "application/ipp", "Data" => $this->output); - - - } - - if (self::_sendHttp ($post_values,$this->paths['printers'])) { - - if(self::_parseServerOutput()) { + } + + if (self::_sendHttp ($post_values,$this->paths['printers'])) + { + if(self::_parseServerOutput()) + { $this->_getJobId(); $this->_getJobUri(); $this->_parseJobAttributes(); - } else { + } + 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)) { - + + if (isset($this->serveroutput) && isset($this->serveroutput->status)) + { $this->status = array_merge($this->status,array($this->serveroutput->status)); if ($this->serveroutput->status == "successfull-ok") @@ -131,138 +122,174 @@ class PrintIPP extends BasicIPP { self::_errorLog(sprintf("printing job: ",$this->last_job) .$this->serveroutput->status,1); if ($this->with_exceptions) { - throw new ippException(sprintf("job status: %s", + 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; + + return false; } - // }}} - // {{{ cancelJob ($job_uri) - public function 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; - + { + 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)) { - + } + + 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 + } + 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); - $this->status = array_merge($this->status,array("OPERATION FAILED")); - self::_errorLog("cancelling job : OPERATION FAILED",3); - - return false; + return false; } - // }}} - // {{{ validateJob () - public function 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'); + { + self::setCharset(); + } if (!isset($this->setup->datatype)) + { self::setBinary(); + } - if (!isset($this->setup->uri)) { + 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 { + } + 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); - + { + 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 @@ -284,43 +311,45 @@ class PrintIPP extends BasicIPP { . $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)) { - + { + 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 + } + 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); - $this->status = array_merge($this->status,array("OPERATION FAILED")); - self::_errorLog("validate job : OPERATION FAILED",3); - - return false; + return false; } - // }}} - // {{{ getPrinterAttributes() - public function getPrinterAttributes() { - + public function getPrinterAttributes() + { $this->jobs = array_merge($this->jobs,array("")); $this->jobs_uri = array_merge($this->jobs_uri,array("")); @@ -330,32 +359,42 @@ class PrintIPP extends BasicIPP { self::_setOperationId(); $this->parsed = array(); unset($this->printer_attributes); - - if (!isset($this->setup->uri)) { + + 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 { + } + 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'); - + { + self::setCharset(); + } + 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 @@ -366,109 +405,137 @@ class PrintIPP extends BasicIPP { . $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)) { - + + 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; + $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) { - + 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)) { + + 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 { + } + 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'); - + { + self::setCharset(); + } + if (!isset($this->setup->language)) + { self::setLanguage('en_us'); + } if (!isset($this->meta->username)) + { self::setUserName(); + } - if ($limit) { + if ($limit) + { $limit = self::_integerBuild($limit); $this->meta->limit = chr(0x21) // integer . self::_giveMeStringLength('limit') . 'limit' . self::_giveMeStringLength($limit) . $limit; - } else + } + 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 @@ -479,9 +546,9 @@ class PrintIPP extends BasicIPP { . $this->meta->username . $this->meta->limit . $this->meta->which_jobs - . $this->meta->my_jobs - ; - if ($subset) { + . $this->meta->my_jobs; + if ($subset) + { $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') @@ -502,106 +569,122 @@ class PrintIPP extends BasicIPP { . self::_giveMeStringLength('') . '' . self::_giveMeStringLength('job-state-reason') - . 'job-state-reason' - ; + . 'job-state-reason'; } - else { # cups 1.4.4 doesn't return much of anything without this + 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' - ; + . '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)) { - + 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") { - + + 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) { + + 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)) { + + 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 { + } + 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'); - + { + self::setCharset(); + } + 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 @@ -609,10 +692,10 @@ class PrintIPP extends BasicIPP { . $this->meta->charset . $this->meta->language . $this->meta->job_uri - . $this->meta->username - ; - if ($subset) - $this->stringjob .= + . $this->meta->username; + if ($subset) + { + $this->stringjob .= chr(0x44) // keyword . self::_giveMeStringLength('requested-attributes') . 'requested-attributes' @@ -632,10 +715,12 @@ class PrintIPP extends BasicIPP { . self::_giveMeStringLength('') . '' . self::_giveMeStringLength('job-state-reason') - . 'job-state-reason' - ; - elseif($attributes_group) { - switch($attributes_group) { + . 'job-state-reason'; + } + elseif($attributes_group) + { + switch($attributes_group) + { case 'job-template': break; case 'job-description': @@ -646,127 +731,116 @@ class PrintIPP extends BasicIPP { 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)) { - + + 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() { + return false; + } + 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) { + 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) { + 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 () { + // 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."\n",2); } - // }}} - // {{{ _setJobId() - protected function _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) { - + protected function _setJobUri ($job_uri) + { $this->meta->job_uri = chr(0x45) // type uri . chr(0x00).chr(0x07) // name-length . "job-uri" @@ -776,441 +850,490 @@ class PrintIPP extends BasicIPP { self::_putDebug( "job-uri is: ".$job_uri."\n",2); } - // }}} - -// RESPONSE PARSING - - // {{{ _parsePrinterAttributes() - protected function _parsePrinterAttributes() { + // RESPONSE PARSING + protected function _parsePrinterAttributes() + { //if (!preg_match('#successful#',$this->serveroutput->status)) // return false; $k = -1; + $l = 0; 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'])) { + { + 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 { + } + 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 ++) { + + $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 = 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 ++) { + 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() { + protected function _parseJobsAttributes() + { //if ($this->serveroutput->status != "successfull-ok") // return false; - + $job = -1; - for ($i = 0 ; $i < count($this->serveroutput->response) ; $i++) { + $l = 0; + 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'])) { + { + 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 { + } + 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 ++) { + $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->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 --; + + 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_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; - } - // }}} + { + $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; - // {{{ _readTag($tag) - protected function _readTag($tag) { + 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; + } - 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: + 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"; - 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; + else + { + $tag = sprintf("UNKNOWN: 0x%x (%u)",$tag,$tag); + } + break; + } + + return $tag; } - // }}} - // {{{ _readCollection($attributes_type,$j,&$collection) - protected function _readCollection($attributes_type,$j) { - + 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++) { + 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++) { + 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 == "") { + if ($attribute_name == "") + { $attribute_name = $this->last_attribute_name; $this->collection_key[$this->collection_depth] ++; - } else { + } + 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++) { + 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++) { - + 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 ++) { + 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; } - + $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; + + $this->serveroutput->response[$attributes_type][$j]['value'] = $this->collection; } - // }}} - - // {{{ _readAttributeName ($attributes_type,$j) - protected function _readAttributeName ($attributes_type,$j,$write=1) { + 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++) { + 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; + { + $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) { + return $name; + } + 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]); @@ -1219,116 +1342,130 @@ class PrintIPP extends BasicIPP { .": " . $value_length . " "); - + $this->_parsing->offset += 2; - + $value = ''; - for ($i = 0; $i < $value_length; $i++) { - + 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; + { + $this->serveroutput->response[$attributes_type][$j]['value'] = $value; + } - return $value; + return $value; } - // }}} - // {{{ _parseAttributes() - protected function _parseAttributes() { - + protected function _parseAttributes() + { $k = -1; + $l = 0; 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'])) { + { + 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 { + } + 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 ++) { + $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 = new \stdClass(); $this->attributes->$php_name->_type = $type; $this->attributes->$php_name->_range = $range; - for ($j = 0 ; $j < (count($this->parsed[$i]) - 3) ; $j ++) { + 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() { + protected function _parseJobAttributes() + { //if (!preg_match('#successful#',$this->serveroutput->status)) // return false; - $k = -1; + $l = 0; 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'])) { + { + 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 { + } + 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 ++) { + + $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 = 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 ++) { + 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) { + protected function _interpretAttribute($attribute_name,$type,$value) + { + switch ($type) + { case "integer": $value = self::_interpretInteger($value); break; @@ -1338,9 +1475,13 @@ class PrintIPP extends BasicIPP { case 'boolean': $value = ord($value); if ($value == 0x00) + { $value = 'false'; + } else + { $value = 'true'; + } break; case 'datetime': $value = self::_interpretDateTime($value); @@ -1351,7 +1492,8 @@ class PrintIPP extends BasicIPP { case 'resolution': $unit = $value[8]; $value = self::_interpretRangeOfInteger(substr($value,0,8)); - switch($unit) { + switch($unit) + { case chr(0x03): $unit = "dpi"; break; @@ -1363,31 +1505,27 @@ class PrintIPP extends BasicIPP { break; default: break; - } - return $value; + } + return $value; } - // }}} - - // {{{ _interpretRangeOfInteger($value) - protected function _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; + + return $value_parsed; } - // }}} - - // {{{ _interpretDateTime($date) { - protected function _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)); @@ -1397,21 +1535,21 @@ class PrintIPP extends BasicIPP { $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) { - + return $date; + } + + protected function _interpretEnum($attribute_name,$value) + { $value_parsed = self::_interpretInteger($value); - - switch ($attribute_name) { + + switch ($attribute_name) + { case 'job-state': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'pending'; break; @@ -1433,14 +1571,17 @@ class PrintIPP extends BasicIPP { 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) { + switch ($value_parsed) + { case 0x03: $value = 'draft'; break; @@ -1453,7 +1594,8 @@ class PrintIPP extends BasicIPP { } break; case 'printer-state': - switch ($value_parsed) { + switch ($value_parsed) + { case 0x03: $value = 'idle'; break; @@ -1463,13 +1605,16 @@ class PrintIPP extends BasicIPP { 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) { + switch($value_parsed) + { case 0x0000: case 0x0001: $value = sprintf('Unknown(reserved) : %s',ord($value)); @@ -1602,20 +1747,31 @@ class PrintIPP extends BasicIPP { 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')) { + } + elseif ($value_parsed >= 0x4000 && $value_parsed <= 0x8FFF) + { + if (method_exists($this,'_getEnumVendorExtensions')) + { $value = $this->_getEnumVendorExtensions($value_parsed); - } else + } + else + { $value = sprintf('Unknown(Vendor extension for operations): 0x%x',$value_parsed); - } elseif ($value_parsed > 0x8FFF) + } + } + 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) { + switch ($value_parsed) + { case 3: $value = 'none'; break; @@ -1673,15 +1829,18 @@ class PrintIPP extends BasicIPP { 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) { + switch ($value_parsed) + { case 0x03: $value = 'portrait'; break; @@ -1694,77 +1853,87 @@ class PrintIPP extends BasicIPP { 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; + } + return $value; } - // }}} - - // {{{ _getJobId () - protected function _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") { + { + 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 () { + 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") { + { + 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 () { + + protected function _parseResponse () + { $j = -1; $this->index = 0; - for ($i = $this->_parsing->offset; $i < strlen($this->serveroutput->body) ; $i = $this->_parsing->offset) { - - + 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) { - + + if ($tag > 0x0F) + { self::_readAttribute($j); $this->index ++; continue; - } + } - switch ($tag) { + switch ($tag) + { case 0x01: $j += 1; $this->serveroutput->response[$j]['attributes'] = "operation-attributes"; @@ -1782,7 +1951,9 @@ class PrintIPP extends BasicIPP { $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<br />"; + } $this->response_completed[(count($this->response_completed) -1)] = "completed"; return; case 0x04: @@ -1803,21 +1974,16 @@ class PrintIPP extends BasicIPP { $this->index = 0; $this->_parsing->offset += 1; break; - } - - self::_putDebug( "tag is: ".$this->serveroutput->response[$j]['attributes']."\n\n\n"); - - } - return; - } - // }}} - - + } + 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 ++) @@ -1833,32 +1999,43 @@ class PrintIPP extends BasicIPP { $this->printers_uri = array_merge($this->printers_uri,array('')); } - // }}} + */ -// REQUEST BUILDING - - // {{{ _stringCancel () - protected function _stringCancel ($job_uri) { + // REQUEST BUILDING + protected function _stringCancel ($job_uri) + { if (!isset($this->setup->charset)) - self::setCharset('us-ascii'); + { + self::setCharset(); + } 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 @@ -1874,16 +2051,4 @@ class PrintIPP extends BasicIPP { 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 index 569d4f6648ff9c938bb3959dcaeb2d9ff34d7849..30bb33d663babb791410d142bc1288e9ce087f34 100644 --- a/htdocs/includes/printipp/http_class.php +++ b/htdocs/includes/printipp/http_class.php @@ -29,7 +29,7 @@ */ /** * This class is intended to implement a subset of Hyper Text Transfer Protocol - * (HTTP/1.1) on client side (currently: POST operation), with file streaming + * (HTTP/1.1) on client side (currently: POST operation), with file streaming * capability. * * It can perform Basic and Digest authentication. @@ -66,48 +66,58 @@ ************************/ class httpException extends Exception { - protected $errno; - public function __construct ($msg, $errno = null) - { - parent::__construct ($msg); - $this->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; - } + protected $errno; + + public function __construct ($msg, $errno = null) + { + parent::__construct ($msg); + $this->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); + $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); } /*********************** @@ -117,499 +127,486 @@ function error2string($value) ************************/ 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"; + // 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 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; + /********************* + * + * Public functions + * + **********************/ - case 'https': - $transport_type = 'tls://'; - break; + public function GetRequestArguments ($url, &$arguments) + { + $this->arguments = array (); + $this->arguments["URL"] = $arguments["URL"] = $url; + $this->arguments["RequestMethod"] = $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"; + } - case 'unix': - $transport_type = 'unix://'; - $port = 0; - $unix = true; - break; + 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; - 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"); - } + case 'https': + $transport_type = 'tls://'; + break; - 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 'unix': + $transport_type = 'unix://'; + $port = 0; + $unix = true; + break; - case 'digest': - $arguments["Headers"]["Authorization"] = self::_BuildDigest (); - 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"); + } - default: - $error = - sprintf (_("need '%s' authentication mechanism, but have not"), - $authtype[0]); - return $this->_HttpError ($error, E_USER_WARNING); - break; + 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; - } - 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"); - } + case 'digest': + $arguments["Headers"]["Authorization"] = self::_BuildDigest (); + break; - public function ReadReplyHeaders (&$headers) - { - $headers = $this->reply_headers; - } + 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); - public function ReadReplyBody (&$body, $chunk_size) - { - $body = substr ($this->reply_body, $this->last_limit, $chunk_size); - $this->last_limit += $chunk_size; - } + $error = sprintf(_('Streaming request failed to %s after a try to authenticate'), $arguments['RequestURI']); + $result = self::_StreamRequest ($arguments); + if (!$result[0]) + { + return $this->_HttpError ($error.": ".$result[1], E_USER_WARNING); + } + self::_ReadReply (); + return array (true, "success"); + } - public function Close () - { - if (!$this->connected) - return; - fclose ($this->connection); - } + public function ReadReplyHeaders (&$headers) + { + $headers = $this->reply_headers; + } - /********************* - * - * Private functions - * - *********************/ + public function ReadReplyBody (&$body, $chunk_size) + { + $body = substr ($this->reply_body, $this->last_limit, $chunk_size); + $this->last_limit += $chunk_size; + } - 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); - } - } + public function Close () + { + if (!$this->connected) + { + return; + } + fclose ($this->connection); + } - private function _streamString ($string) - { - $success = fwrite ($this->connection, $string); - if (!$success) - { - return false; - } - return true; - } + /********************* + * + * Private functions + * + *********************/ - 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)) + private function _HttpError ($msg, $level, $errno = null) { - $length = filesize ($value); + $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); + } } - else + + private function _streamString ($string) { - $length = 0; - return - _HttpError (sprintf (_("%s: file is not readable"), $value), - E_USER_WARNING); + $success = fwrite ($this->connection, $string); + if (!$success) + { + return false; + } + return true; } - } - 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)) + + private function _StreamRequest ($arguments) { - $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; + $this->status = false; + $this->reply_headers = array (); + $this->reply_body = ""; + if (!$this->connected) + { + return $this->_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 $this->_HttpError (sprintf (_("%s: file is not readable"), $value), E_USER_WARNING); + } + } + else + { + $length = 0; + return $this->_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 $this->_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 $this->_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 $this->_HttpError (_("Error while puts HTTP headers"), E_USER_WARNING); + } + } + $string = "\r\n"; + if (!$this->_streamString ($string)) + { + return $this->_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 $this->_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 $this->_HttpError (_("cannot read file to upload"), E_USER_WARNING); + } + if (!$this->_streamString ($block)) + { + return $this->_HttpError (_("error while sending body data"), E_USER_WARNING); + } + } + } + } + } + return array (true, "success"); } - } - elseif ($type == "File") - { - if (is_readable ($value)) + + private function _ReadReply () { - $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); - } - } + 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; } - } - } - 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; + 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; + } - 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; - } + 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; -/* - * Local variables: - * mode: php - * tab-width: 2 - * c-basic-offset: 2 - * End: - */ -?> + default: + return $this->_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; + } +} diff --git a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql index 9a48f6378eab4d54ff70c586108d62185127a7c7..d5ac52fd4aa6f284b18fc61293dd4c58a160b8ff 100755 --- a/htdocs/install/mysql/migration/3.7.0-3.8.0.sql +++ b/htdocs/install/mysql/migration/3.7.0-3.8.0.sql @@ -26,6 +26,21 @@ create table llx_c_price_expression expression varchar(80) NOT NULL )ENGINE=innodb; +--create table for user conf of printing driver +CREATE TABLE llx_printing +( + rowid integer AUTO_INCREMENT PRIMARY KEY, + tms timestamp, + datec datetime, + printer_name text NOT NULL, + printer_location text NOT NULL, + printer_id varchar(255) NOT NULL, + copy integer NOT NULL DEFAULT '1', + module varchar(16) NOT NULL, + driver varchar(16) NOT NULL, + userid integer +)ENGINE=innodb; + ALTER TABLE llx_product_fournisseur_price ADD fk_price_expression integer DEFAULT NULL; -- Taiwan VAT Rates diff --git a/htdocs/install/mysql/tables/llx_printer_ipp.sql b/htdocs/install/mysql/tables/llx_printing.sql similarity index 77% rename from htdocs/install/mysql/tables/llx_printer_ipp.sql rename to htdocs/install/mysql/tables/llx_printing.sql index a19e05587d63fb4d30beb3066d65f381d8965a14..451564ff74b1cb02fa0979ba612601425b14b2b7 100644 --- a/htdocs/install/mysql/tables/llx_printer_ipp.sql +++ b/htdocs/install/mysql/tables/llx_printing.sql @@ -1,5 +1,6 @@ -- ============================================================================ --- Copyright (C) 2013 Florian HENRY <florian.henry@open-concept.pro> +-- Copyright (C) 2013 Florian HENRY <florian.henry@open-concept.pro> +-- Copyright (C) 2014 Frederic France <frederic.france@free.fr> -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by @@ -16,15 +17,16 @@ -- -- ============================================================================ -CREATE TABLE llx_printer_ipp +CREATE TABLE llx_printing ( rowid integer AUTO_INCREMENT PRIMARY KEY, - tms timestamp, - datec datetime, + tms timestamp, + datec datetime, printer_name text NOT NULL, printer_location text NOT NULL, - printer_uri varchar(255) NOT NULL, + printer_id varchar(255) NOT NULL, copy integer NOT NULL DEFAULT '1', module varchar(16) NOT NULL, - login varchar(32) NOT NULL + driver varchar(16) NOT NULL, + userid integer )ENGINE=innodb; diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index bfded6f40e2e597cf7641de510c48b2bf9f9f672..5562002b58ba6e2274a2371cab42d6fb4924634c 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -685,6 +685,7 @@ XMoreLines=%s line(s) hidden PublicUrl=Public URL AddBox=Add box SelectElementAndClickRefresh=Select an element and click Refresh +PrintFile=Print File %s # Week day Monday=Monday Tuesday=Tuesday diff --git a/htdocs/langs/en_US/printgcp.lang b/htdocs/langs/en_US/printgcp.lang new file mode 100644 index 0000000000000000000000000000000000000000..ded5fb63d6e4722f2d4f6d1114f59568484bfd93 --- /dev/null +++ b/htdocs/langs/en_US/printgcp.lang @@ -0,0 +1,25 @@ +# Dolibarr language file - Source file is en_US - printgccp +PRINTGCP=Google Cloud Print +PrintGCPDesc=This driver allow to send documents directly to a printer with Google Cloud Print. +PrintingDriverDescprintgcp=Configuration variables for printing driver Google Cloud Print. +PrintTestDescprintgcp=List of Printers for Google Cloud Print. +PRINTGCP_LOGIN=Google Account Login +PRINTGCP_PASSWORD=Google Account Password +STATE_ONLINE=Online +STATE_UNKNOWN=Unknown +STATE_OFFLINE=Offline +STATE_DORMANT=Offline for quite a while +TYPE_GOOGLE=Google +TYPE_HP=HP Printer +TYPE_DOCS=DOCS +TYPE_DRIVE=Google Drive +TYPE_FEDEX=Fedex +TYPE_ANDROID_CHROME_SNAPSHOT=Android +TYPE_IOS_CHROME_SNAPSHOT=IOS +GCP_Name=Name +GCP_displayName=Display Name +GCP_Id=Printer Id +GCP_OwnerName=Owner Name +GCP_State=Printer State +GCP_connectionStatus=Online State +GCP_Type=Printer Type diff --git a/htdocs/langs/en_US/printing.lang b/htdocs/langs/en_US/printing.lang new file mode 100644 index 0000000000000000000000000000000000000000..77c6388463614732cd87fb6237faba29d0ecd3cc --- /dev/null +++ b/htdocs/langs/en_US/printing.lang @@ -0,0 +1,10 @@ +# Dolibarr language file - Source file is en_US - printing +PrintingSetup=Setup of Printing System +PrintingDesc=This module adds a Print button to send documents directly to a printer with various module. +ModuleDriverSetup=Setup Module Driver +PrintingDriverDesc=Configuration variables for printing driver. +ListDrivers=List of drivers +PrintTestDesc=List of Printers. +FileWasSentToPrinter=File %s was sent to printer +NoActivePrintingModuleFound=No active module to print document +PleaseSelectaDriverfromList=Please select a driver from list. diff --git a/htdocs/langs/en_US/printipp.lang b/htdocs/langs/en_US/printipp.lang index 835e6827f12ee4e466c21f2ee540526389fa7e03..e85d53627c45cbd65b18843bf880498ebdd2b55e 100644 --- a/htdocs/langs/en_US/printipp.lang +++ b/htdocs/langs/en_US/printipp.lang @@ -1,6 +1,9 @@ # Dolibarr language file - Source file is en_US - printipp +PRINTIPP=PrintIPP Driver PrintIPPSetup=Setup of Direct Print module -PrintIPPDesc=This module adds a Print button to send documents directly to a printer. It requires a Linux system with CUPS installed. +PrintIPPDesc=This driver allow to send documents directly to a printer. It requires a Linux system with CUPS installed. +PrintingDriverDescprintipp=Configuration variables for printing driver PrintIPP. +PrintTestDescprintipp=List of Printers for driver PrintIPP. PRINTIPP_ENABLED=Show "Direct print" icon in document lists PRINTIPP_HOST=Print server PRINTIPP_PORT=Port @@ -12,3 +15,23 @@ NoDefaultPrinterDefined=No default printer defined DefaultPrinter=Default printer Printer=Printer CupsServer=CUPS Server +IPP_Uri=Printer Uri +IPP_Name=Printer Name +IPP_State=Printer State +IPP_State_reason=State reason +IPP_State_reason1=State reason1 +IPP_BW=BW +IPP_Color=Color +IPP_Device=Device +IPP_Media=Printer media +IPP_Supported=Type of media +STATE_IPP_idle=Idle +STATE_IPP_stopped=Stopped +STATE_IPP_paused=Paused +STATE_IPP_toner-low-report=Low Toner +STATE_IPP_none=None +MEDIA_IPP_stationery=Stationery +MEDIA_IPP_thermal=Thermal +IPP_COLOR_print-black=BW Printer +IPP_COLOR_print-color=Color Printer +IPP_COLOR_=No diff --git a/htdocs/printipp/lib/index.html b/htdocs/printing/admin/index.html similarity index 100% rename from htdocs/printipp/lib/index.html rename to htdocs/printing/admin/index.html diff --git a/htdocs/printing/admin/printing.php b/htdocs/printing/admin/printing.php new file mode 100644 index 0000000000000000000000000000000000000000..63784e560f0af256fe9dac55adb1afdaf13c652e --- /dev/null +++ b/htdocs/printing/admin/printing.php @@ -0,0 +1,277 @@ +<?php +/* Copyright (C) 2013 Laurent Destailleur <eldy@users.sourceforge.net> + * Copyright (C) 2014 Frederic France <frederic.france@free.fr> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file htdocs/printing/admin/printing.php + * \ingroup printing + * \brief Page to setup printing 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/modules/printing/modules_printing.php'; +require_once DOL_DOCUMENT_ROOT.'/printing/lib/printing.lib.php'; + +$langs->load("admin"); +$langs->load("printing"); + +if (! $user->admin) accessforbidden(); + +$action = GETPOST('action','alpha'); +$mode = GETPOST('mode','alpha'); +$value = GETPOST('value','alpha'); +$varname = GETPOST('varname', 'alpha'); +$driver = GETPOST('driver', 'alpha'); + +if (! empty($driver)) $langs->load($driver); + +if (!$mode) $mode='config'; + +/* + * Action + */ + +if (($mode == 'test' || $mode == 'setup') && empty($driver)) +{ + setEventMessage($langs->trans('PleaseSelectaDriverfromList')); + header("Location: ".$_SERVER['PHP_SELF'].'?mode=config'); + exit; +} + +if ($action == 'setconst' && $user->admin) +{ + $error=0; + $db->begin(); + foreach ($_POST['setupdriver'] as $setupconst) { + //print '<pre>'.print_r($setupconst, true).'</pre>'; + $result=dolibarr_set_const($db, $setupconst['varname'],$setupconst['value'],'chaine',0,'',$conf->entity); + if (! $result > 0) $error++; + } + + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans("SetupSaved")); + } + else + { + $db->rollback(); + dol_print_error($db); + } + $action=''; +} + +if ($action == 'setvalue' && $user->admin) +{ + $db->begin(); + + $result=dolibarr_set_const($db, $varname, $value,'chaine',0,'',$conf->entity); + if (! $result > 0) $error++; + + if (! $error) + { + $db->commit(); + setEventMessage($langs->trans("SetupSaved")); + } + else + { + $db->rollback(); + dol_print_error($db); + } + $action = ''; +} + +/* + * View + */ + +$form = new Form($db); + +llxHeader('',$langs->trans("PrintingSetup")); + +$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>'; +print_fiche_titre($langs->trans("PrintingSetup"),$linkback,'setup'); + +$head=printingadmin_prepare_head(); + +if ($mode == 'setup' && $user->admin) +{ + print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=setup&driver='.$driver.'">'; + print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; + print '<input type="hidden" name="action" value="setconst">'; + + dol_fiche_head($head, $mode, $langs->trans("ModuleDriverSetup"), 0, 'technic'); + + print $langs->trans("PrintingDriverDesc".$driver)."<br><br>\n"; + + print '<table class="noborder" width="100%">'."\n"; + $var=true; + print '<tr class="liste_titre">'; + print '<th>'.$langs->trans("Parameters").'</th>'; + print '<th>'.$langs->trans("Value").'</th>'; + print "</tr>\n"; + + if (! empty($driver)) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $classname = 'printing_'.$driver; + $langs->load($driver); + $printer = new $classname($db); + //print '<pre>'.print_r($printer, true).'</pre>'; + $i=0; + foreach ($printer->conf as $key) { + $var=!$var; + print '<tr '.$bc[$var].'>'; + print '<td'.($key['required']?' class=required':'').'>'.$langs->trans($key['varname']).'</td><td>'; + print '<input size="32" type="'.(empty($key['type'])?'text':$key['type']).'" name="setupdriver['.$i.'][value]" value="'.$conf->global->{$key['varname']}.'">'; + print '<input type="hidden" name="setupdriver['.$i.'][varname]" value="'.$key['varname'].'">'; + print ' '.($key['example']!=''?$langs->trans("Example").' : '.$key['example']:''); + print '</tr>'; + $i++; + } + } else { + print $langs->trans('PleaseSelectaDriverfromList'); + } + + print '</table>'; + if (! empty($driver)) { + print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Modify")).'"></center>'; + } + print '</form>'; + dol_fiche_end(); + +} +if ($mode == 'config' && $user->admin) +{ + dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); + + print $langs->trans("PrintingDesc")."<br><br>\n"; + + print '<table class="noborder" width="100%">'."\n"; + + $var=true; + print '<tr class="liste_titre">'; + print '<th>'.$langs->trans("Description").'</th>'; + print '<th class="center">'.$langs->trans("Active").'</th>'; + print '<th class="center">'.$langs->trans("Setup").'</th>'; + print '<th class="center">'.$langs->trans("Test").'</th>'; + print "</tr>\n"; + + $object = new PrintingDriver($db); + $result = $object->listDrivers($db, 10); + foreach ($result as $driver) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $classname = 'printing_'.$driver; + $langs->load($driver); + $printer = new $classname($db); + //print '<pre>'.print_r($printer, true).'</pre>'; + $var=!$var; + print '<tr '.$bc[$var].'>'; + print '<td>'.img_picto('', $printer->picto).$langs->trans($printer->desc).'</td>'; + print '<td class="center">'; + if (! empty($conf->use_javascript_ajax)) + { + print ajax_constantonoff($printer->active); + } + else + { + if (empty($conf->global->{$printer->conf})) + { + print '<a href="'.$_SERVER['PHP_SELF'].'?action=setvalue&varname='.$printer->active.'&value=1">'.img_picto($langs->trans("Disabled"),'off').'</a>'; + } + else + { + print '<a href="'.$_SERVER['PHP_SELF'].'?action=setvalue&varname='.$printer->active.'&value=0">'.img_picto($langs->trans("Enabled"),'on').'</a>'; + } + } + print '<td class="center"><a href="'.$_SERVER['PHP_SELF'].'?mode=setup&driver='.$printer->name.'">'.img_picto('', 'setup').'</a></td>'; + print '<td class="center"><a href="'.$_SERVER['PHP_SELF'].'?mode=test&driver='.$printer->name.'">'.img_picto('', 'setup').'</a></td>'; + print '</tr>'."\n"; + } + + print '</table>'; + + dol_fiche_end(); +} + +if ($mode == 'test' && $user->admin) +{ + dol_fiche_head($head, $mode, $langs->trans("PrintingTest"), 0, 'technic'); + + print $langs->trans('PrintTestDesc'.$driver)."<br><br>\n"; + + print '<table class="noborder" width="100%">'; + if (! empty($driver)) { + require_once DOL_DOCUMENT_ROOT.'/core/modules/printing/'.$driver.'.modules.php'; + $classname = 'printing_'.$driver; + $langs->load($driver); + $printer = new $classname($db); + //print '<pre>'.print_r($printer, true).'</pre>'; + print $printer->listAvailablePrinters(); + + } else { + print $langs->trans('PleaseSelectaDriverfromList'); + } + print '</table>'; + + dol_fiche_end(); +} + +if ($mode == 'userconf' && $user->admin) +{ + dol_fiche_head($head, $mode, $langs->trans("UserConf"), 0, 'technic'); + + print $langs->trans('PrintUserConfDesc'.$driver)."<br><br>\n"; + + print '<table class="noborder" width="100%">'; + $var=true; + print '<tr class="liste_titre">'; + print '<th>'.$langs->trans("User").'</th>'; + print '<th>'.$langs->trans("PrintModule").'</th>'; + print '<th>'.$langs->trans("PrintDriver").'</th>'; + print '<th>'.$langs->trans("Printer").'</th>'; + print '<th>'.$langs->trans("PrinterLocation").'</th>'; + print '<th>'.$langs->trans("PrinterId").'</th>'; + print '<th>'.$langs->trans("NumberOfCopy").'</th>'; + print '<th class="center">'.$langs->trans("Delete").'</th>'; + print "</tr>\n"; + $sql = 'SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login FROM '.MAIN_DB_PREFIX.'printing as p, '.MAIN_DB_PREFIX.'user as u WHERE p.userid=u.rowid'; + $resql = $db->query($sql); + while ($row=$db->fetch_array($resql)) { + $var=!$var; + print '<tr '.$bc[$var].'>'; + print '<td>'.$row['login'].'</td>'; + print '<td>'.$row['module'].'</td>'; + print '<td>'.$row['driver'].'</td>'; + print '<td>'.$row['printer_name'].'</td>'; + print '<td>'.$row['printer_location'].'</td>'; + print '<td>'.$row['printer_id'].'</td>'; + print '<td>'.$row['copy'].'</td>'; + print '<td class="center">'.img_picto($langs->trans("Delete"), 'delete').'</td>'; + print "</tr>\n"; + } + print '</table>'; + + dol_fiche_end(); + +} + +llxFooter(); + +$db->close(); diff --git a/htdocs/printipp/index.php b/htdocs/printing/index.php similarity index 61% rename from htdocs/printipp/index.php rename to htdocs/printing/index.php index a130805f16ebd3ee3863a21cd22148d9c2804eb7..e8669f44585b4cba1db19a22084808a808ee9b49 100644 --- a/htdocs/printipp/index.php +++ b/htdocs/printing/index.php @@ -1,5 +1,6 @@ <?php /* + * Copyright (C) 2014 Frederic France <frederic.france@free.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,20 +17,21 @@ */ /** - * \file htdocs/printipp/index.php - * \ingroup printipp - * \brief Printipp + * \file htdocs/printing/index.php + * \ingroup printing + * \brief Printing */ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/dolprintipp.class.php'; -llxHeader("",$langs->trans("Printer")); +llxHeader("",$langs->trans("Printing")); -print_fiche_titre($langs->trans("Printer")); +print_fiche_titre($langs->trans("Printing")); -$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'); +// List Jobs from printing modules +//$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/printing/lib/index.html b/htdocs/printing/lib/index.html new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/htdocs/printipp/lib/printipp.lib.php b/htdocs/printing/lib/printing.lib.php similarity index 55% rename from htdocs/printipp/lib/printipp.lib.php rename to htdocs/printing/lib/printing.lib.php index 64c14609df5ffd19f837820ca80c98777b2930c0..1d09daba0dc536ee88850af86d62caa057dcadda 100644 --- a/htdocs/printipp/lib/printipp.lib.php +++ b/htdocs/printing/lib/printing.lib.php @@ -16,44 +16,54 @@ */ /** - * \file htdocs/printipp/lib/printipp.lib.php - * \ingroup printipp - * \brief Library for printipp functions + * \file htdocs/printing/lib/printing.lib.php + * \ingroup printing + * \brief Library for printing functions */ /** - * Define head array for tabs of printipp tools setup pages + * Define head array for tabs of printing tools setup pages * * @return Array of head */ -function printippadmin_prepare_head() +function printingadmin_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("CupsServer"); + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=config"; + $head[$h][1] = $langs->trans("ListDrivers"); $head[$h][2] = 'config'; $h++; - $head[$h][0] = DOL_URL_ROOT."/printipp/admin/printipp.php?mode=test"; - $head[$h][1] = $langs->trans("Printer"); + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=setup"; + $head[$h][1] = $langs->trans("SetupDriver"); + $head[$h][2] = 'setup'; + $h++; + + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=test"; + $head[$h][1] = $langs->trans("TestDriver"); $head[$h][2] = 'test'; $h++; - $object=new stdClass(); + $head[$h][0] = DOL_URL_ROOT."/printing/admin/printing.php?mode=userconf"; + $head[$h][1] = $langs->trans("UserConf"); + $head[$h][2] = 'userconf'; + $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,'printingadmin'); - complete_head_from_modules($conf,$langs,$object,$head,$h,'printipp','remove'); + //complete_head_from_modules($conf,$langs,$object,$head,$h,'printing','remove'); return $head; } diff --git a/htdocs/printipp/admin/printipp.php b/htdocs/printipp/admin/printipp.php deleted file mode 100644 index 28ad55453eb42b3874f557878eb79eb4627e7cc5..0000000000000000000000000000000000000000 --- a/htdocs/printipp/admin/printipp.php +++ /dev/null @@ -1,246 +0,0 @@ -<?php -/* Copyright (C) 2013 Laurent Destailleur <eldy@users.sourceforge.net> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/** - * \file htdocs/printipp/admin/printipp.php - * \ingroup printipp - * \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'); -$value = GETPOST('value','alpha'); - -if (!$mode) $mode='config'; - -/* - * Action - */ - -if ($action == 'setvalue' && $user->admin) -{ - $db->begin(); - - if (! $result > 0) $error++; - $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); - } -} - -// Set default model -else if ($action == 'setprinteruri') -{ - if (dolibarr_set_const($db, "PRINTIPP_URI_DEFAULT",$value,'chaine',0,'',$conf->entity)) - { - // La constante qui a ete lue en avant du nouveau set - // on passe donc par une variable pour avoir un affichage coherent - $conf->global->PRINTIPP_URI_DEFAULT = $value; - } -} - - -/* - * View - */ - -$form = new Form($db); - -llxHeader('',$langs->trans("PrintIPPSetup")); - -$linkback='<a href="'.DOL_URL_ROOT.'/admin/modules.php">'.$langs->trans("BackToModuleList").'</a>'; -print_fiche_titre($langs->trans("PrintIPPSetup"),$linkback,'setup'); - -$head=printippadmin_prepare_head(); - - -if ($mode == 'config' && $user->admin) -{ - print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=config">'; - print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'; - print '<input type="hidden" name="action" value="setvalue">'; - - dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); - - print $langs->trans("PrintIPPDesc")."<br><br>\n"; - - print '<table class="noborder" width="100%">'; - - $var=true; - print '<tr class="liste_titre">'; - print '<td>'.$langs->trans("Parameters").'</td>'; - print '<td>'.$langs->trans("Value").'</td>'; - print "</tr>\n"; - - /* - $var=!$var; - print '<tr '.$bc[$var].'><td>'; - print $langs->trans("PRINTIPP_ENABLED").'</td><td colspan="2" align="left">'; - - if (! empty($conf->use_javascript_ajax)) - { - print ajax_constantonoff('PRINTIPP_ENABLED'); - } - else - { - if (empty($conf->global->PRINTIPP_ENABLED)) - { - print '<a href="'.$_SERVER['PHP_SELF'].'?action=set_PRINTIPP_ENABLED">'.img_picto($langs->trans("Disabled"),'off').'</a>'; - } - else - { - print '<a href="'.$_SERVER['PHP_SELF'].'?action=del_PRINTIPP_ENABLED">'.img_picto($langs->trans("Enabled"),'on').'</a>'; - } - } - print '</td></tr>'; - */ - - $var=!$var; - print '<tr '.$bc[$var].'><td class="fieldrequired">'; - print $langs->trans("PRINTIPP_HOST").'</td><td>'; - print '<input size="64" type="text" name="PRINTIPP_HOST" value="'.$conf->global->PRINTIPP_HOST.'">'; - print ' '.$langs->trans("Example").': localhost'; - print '</td></tr>'; - - $var=!$var; - print '<tr '.$bc[$var].'><td class="fieldrequired">'; - print $langs->trans("PRINTIPP_PORT").'</td><td>'; - print '<input size="32" type="text" name="PRINTIPP_PORT" value="'.$conf->global->PRINTIPP_PORT.'">'; - print ' '.$langs->trans("Example").': 631'; - print '</td></tr>'; - - $var=!$var; - print '<tr '.$bc[$var].'><td>'; - print $langs->trans("PRINTIPP_USER").'</td><td>'; - print '<input size="32" type="text" name="PRINTIPP_USER" value="'.$conf->global->PRINTIPP_USER.'">'; - print '</td></tr>'; - - $var=!$var; - print '<tr '.$bc[$var].'><td>'; - print $langs->trans("PRINTIPP_PASSWORD").'</td><td>'; - print '<input size="32" type="text" name="PRINTIPP_PASSWORD" value="'.$conf->global->PRINTIPP_PASSWORD.'">'; - print '</td></tr>'; - - //$var=true; - //print '<tr class="liste_titre">'; - //print '<td>'.$langs->trans("OtherParameter").'</td>'; - //print '<td>'.$langs->trans("Value").'</td>'; - //print "</tr>\n"; - - print '</table>'; - - dol_fiche_end(); - - print '<div class="center"><input type="submit" class="button" value="'.dol_escape_htmltag($langs->trans("Modify")).'"></center>'; - - print '</form>'; -} - -if ($mode == 'test' && $user->admin) -{ - dol_fiche_head($head, $mode, $langs->trans("ModuleSetup"), 0, 'technic'); - - print $langs->trans("PrintIPPDesc")."<br><br>\n"; - - print '<table class="nobordernopadding" width="100%">'; - $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 '<table width="100%" class="noborder">'; - print '<tr class="liste_titre">'; - print '<td>Uri</td>'; - print '<td>Name</td>'; - print '<td>State</td>'; - print '<td>State_reason</td>'; - print '<td>State_reason1</td>'; - print '<td>BW</td>'; - print '<td>Color</td>'; - //print '<td>Device</td>'; - print '<td>Media</td>'; - print '<td>Supported</td>'; - print '<td>'.$langs->trans("Select").'</td>'; - print "</tr>\n"; - - $list = $printer->getlist_available_printers(); - $var = true; - foreach ($list as $value) - { - $var=!$var; - $printer_det = $printer->get_printer_detail($value); - print "<tr ".$bc[$var].">"; - print '<td>'.$value.'</td>'; - //print '<td><pre>'.print_r($printer_det,true).'</pre></td>'; - print '<td>'.$printer_det->printer_name->_value0.'</td>'; - print '<td>'.$printer_det->printer_state->_value0.'</td>'; - print '<td>'.$printer_det->printer_state_reasons->_value0.'</td>'; - print '<td>'.$printer_det->printer_state_reasons->_value1.'</td>'; - print '<td>'.$printer_det->printer_type->_value2.'</td>'; - print '<td>'.$printer_det->printer_type->_value3.'</td>'; - //print '<td>'.$printer_det->device_uri->_value0.'</td>'; - print '<td>'.$printer_det->media_default->_value0.'</td>'; - print '<td>'.$printer_det->media_type_supported->_value1.'</td>'; - // Defaut - print "<td align=\"center\">"; - if ($conf->global->PRINTIPP_URI_DEFAULT == "$value") - { - print img_picto($langs->trans("Default"),'on'); - } - else - { - print '<a href="'.$_SERVER["PHP_SELF"].'?action=setprinteruri&mode=test&value='.urlencode($value).'" alt="'.$langs->trans("Default").'">'.img_picto($langs->trans("Disabled"),'off').'</a>'; - } - print '</td>'; - print "</tr>\n"; - } - print '</table>'; - - if (count($list) == 0) print $langs->trans("NoPrinterFound"); - - dol_fiche_end(); -} - - - -llxFooter(); - -$db->close();