PageRenderTime 283ms CodeModel.GetById 94ms app.highlight 76ms RepoModel.GetById 105ms app.codeStats 0ms

/root/usr/share/nethesis/NethServer/Tool/phpprintipp/CupsPrintIPP.php

https://github.com/nethesis/nethserver-cups
PHP | 671 lines | 462 code | 120 blank | 89 comment | 105 complexity | c5e931c42d5d38c854e728ade7d57d0e MD5 | raw file
  1<?php
  2/* vim: set expandtab tabstop=4 shiftwidth=4 foldmethod=marker: */
  3/* @(#) $Header: /sources/phpprintipp/phpprintipp/php_classes/CupsPrintIPP.php,v 1.1 2008/06/21 00:30:56 harding Exp $
  4 *
  5 * Class PrintIPP - Send extended IPP requests.
  6 *
  7 *   Copyright (C) 2005-2006  Thomas HARDING
  8 *
  9 *   This library is free software; you can redistribute it and/or
 10 *   modify it under the terms of the GNU Library General Public
 11 *   License as published by the Free Software Foundation; either
 12 *   version 2 of the License, or (at your option) any later version.
 13 *
 14 *   This library is distributed in the hope that it will be useful,
 15 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 *   Library General Public License for more details.
 18 *
 19 *   You should have received a copy of the GNU Library General Public
 20 *   License along with this library; if not, write to the Free Software
 21 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 22 *
 23 *   mailto:thomas.harding@laposte.net
 24 *   Thomas Harding, 56 rue de la bourie rouge, 45 000 ORLEANS -- FRANCE
 25 *   
 26 */
 27    
 28/*
 29
 30    This class is intended to implement Internet Printing Protocol on client side.
 31
 32    References needed to debug / add functionnalities:
 33        - RFC 2910
 34        - RFC 2911
 35        - RFC 3382
 36        - ...
 37        - CUPS-IPP-1.1
 38*/
 39
 40require_once("ExtendedPrintIPP.php");
 41
 42class CupsPrintIPP extends ExtendedPrintIPP {
 43
 44    // {{{ variables declaration
 45    
 46    public $printers_attributes;
 47    public $defaults_attributes;
 48    
 49    // }}}
 50
 51    // {{{ constructor
 52    public function __construct() {
 53        parent::__construct();
 54        self::_initTags();
 55    }
 56    // }}}
 57
 58//
 59// OPERATIONS
 60//
 61
 62    // {{{ cupsGetDefaults ($attributes="all")
 63    public function cupsGetDefaults($attributes=array("all")) {
 64    //The CUPS-Get-Default operation returns the default printer URI and attributes
 65     
 66        $this->jobs = array_merge($this->jobs,array(""));
 67        $this->jobs_uri = array_merge($this->jobs_uri,array(""));
 68        $this->parsed = array();
 69        unset($this->printer_attributes);
 70        
 71        if (!isset($this->setup->charset))
 72            self::setCharset('us-ascii');
 73        
 74        if (!isset($this->setup->language))
 75            self::setLanguage('en');
 76            
 77        self::_setOperationId();
 78        
 79        for($i = 0 ; $i < count($attributes) ; $i++)
 80            if ($i == 0)
 81                $this->meta->attributes = chr(0x44) // Keyword
 82                                        . self::_giveMeStringLength('requested-attributes')
 83                                        . 'requested-attributes'
 84                                        . self::_giveMeStringLength($attributes[0])
 85                                        . $attributes[0];
 86            else
 87                $this->meta->attributes .= chr(0x44) // Keyword
 88                                        .  chr(0x0).chr(0x0) // zero-length name
 89                                        .  self::_giveMeStringLength($attributes[$i])
 90                                        .  $attributes[$i];
 91                                        
 92        $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 
 93                         . chr(0x40). chr(0x01) // operation:  cups vendor extension: get defaults
 94                         . $this->meta->operation_id // request-id
 95                         . chr(0x01) // start operation-attributes | operation-attributes-tag
 96                         . $this->meta->charset
 97                         . $this->meta->language
 98                         . $this->meta->attributes
 99                         . chr(0x03); // end operations attribute
100                        
101        $this->output = $this->stringjob;
102        
103        self::_putDebug("Request: ".$this->output);
104        
105        $post_values = array( "Content-Type" => "application/ipp",
106                              "Data" => $this->output);
107            
108        if (self::_sendHttp ($post_values,'/')) {
109            
110            if(self::_parseServerOutput())
111                self::_parsePrinterAttributes();
112            }
113        
114       $this->attributes = &$this->printer_attributes;
115        
116       if (isset($this->printer_attributes->printer_type)) {
117                    $printer_type = $this->printer_attributes->printer_type->_value0;
118                    $table = self::_interpretPrinterType($printer_type);
119        
120                    for($i = 0 ; $i < count($table) ; $i++ ) {
121                        $index = '_value'.$i;
122                        $this->printer_attributes->printer_type->$index = $table[$i];
123                        }
124
125                    }
126
127        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
128            
129            $this->status = array_merge($this->status,array($this->serveroutput->status));
130            if ($this->serveroutput->status == "successfull-ok")
131                self::_errorLog("getting defaults: ".$this->serveroutput->status,3);
132            else
133                self::_errorLog("getting defaults: ".$this->serveroutput->status,1);
134            
135            return $this->serveroutput->status; 
136            
137        } else {
138            $this->status = array_merge($this->status,array("OPERATION FAILED"));
139            self::_errorLog("getting defaults : OPERATION FAILED",1);
140            }
141    return false;   
142    }
143    // }}}
144    
145    // {{{ cupsAcceptJobs ($printer_uri)
146    public function cupsAcceptJobs($printer_uri) {
147    //The CUPS-Get-Default operation returns the default printer URI and attributes
148     
149        $this->jobs = array_merge($this->jobs,array(""));
150        $this->jobs_uri = array_merge($this->jobs_uri,array(""));
151        $this->parsed = array();
152        unset($this->printer_attributes);
153        
154        if (!isset($this->setup->charset))
155            self::setCharset('us-ascii');
156        
157        if (!isset($this->setup->language))
158            self::setLanguage('en');
159            
160        self::_setOperationId();
161       
162       $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 
163                         . chr(0x40). chr(0x08) // operation:  cups vendor extension: Accept-Jobs
164                         . $this->meta->operation_id // request-id
165                         . chr(0x01) // start operation-attributes | operation-attributes-tag
166                         . $this->meta->charset
167                         . $this->meta->language
168                         . chr(0x45) // uri
169                         . self::_giveMeStringLength('printer-uri')
170                         . 'printer-uri'
171                         . self::_giveMeStringLength($printer_uri)
172                         . $printer_uri
173                         . chr(0x03); // end operations attribute
174                        
175        $this->output = $this->stringjob;
176        
177        self::_putDebug("Request: ".$this->output);
178        
179        $post_values = array( "Content-Type" => "application/ipp",
180                              "Data" => $this->output);
181            
182        if (self::_sendHttp ($post_values,'/admin/')) {
183            
184            if(self::_parseServerOutput())
185                self::_parseAttributes();
186            }
187                
188        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
189            
190            $this->status = array_merge($this->status,array($this->serveroutput->status));
191            if ($this->serveroutput->status == "successfull-ok")
192                self::_errorLog("getting defaults: ".$this->serveroutput->status,3);
193            else
194                self::_errorLog("getting defaults: ".$this->serveroutput->status,1);
195            
196            return $this->serveroutput->status; 
197            
198        } else {
199            $this->status = array_merge($this->status,array("OPERATION FAILED"));
200            self::_errorLog("getting defaults : OPERATION FAILED",1);
201            }
202    return false;   
203    }
204    // }}}
205
206    // {{{ cupsRejectJobs ($printer_uri,$printer_state_message=false)
207    public function cupsRejectJobs($printer_uri,$printer_state_message) {
208    //The CUPS-Get-Default operation returns the default printer URI and attributes
209     
210        $this->jobs = array_merge($this->jobs,array(""));
211        $this->jobs_uri = array_merge($this->jobs_uri,array(""));
212        $this->parsed = array();
213        unset($this->attributes);
214        
215        if (!isset($this->setup->charset))
216            self::setCharset('us-ascii');
217        
218        if (!isset($this->setup->language))
219            self::setLanguage('en');
220            
221        self::_setOperationId();
222        
223        $message = "";
224        if ($printer_state_message)
225            $message = chr(0x04) // start printer-attributes
226                     . chr(0x41) // textWithoutLanguage
227                     . self::_giveMeStringLength("printer-state-message")
228                     . "printer-state-message"
229                     . self::_giveMeStringLength($printer_state_message)
230                     . $printer_state_message;
231
232       $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 
233                         . chr(0x40). chr(0x09) // operation:  cups vendor extension: Reject-Jobs
234                         . $this->meta->operation_id // request-id
235                         . chr(0x01) // start operation-attributes | operation-attributes-tag
236                         . $this->meta->charset
237                         . $this->meta->language
238                         . chr(0x45) // uri
239                         . self::_giveMeStringLength('printer-uri')
240                         . 'printer-uri'
241                         . self::_giveMeStringLength($printer_uri)
242                         . $printer_uri
243                         . $message
244                         . chr(0x03); // end operations attribute
245                        
246        $this->output = $this->stringjob;
247        
248        self::_putDebug("Request: ".$this->output);
249        
250        $post_values = array( "Content-Type" => "application/ipp",
251                              "Data" => $this->output);
252            
253        if (self::_sendHttp ($post_values,'/admin/')) {
254            
255            if(self::_parseServerOutput())
256                self::_parseAttributes();
257            }
258                
259        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
260            
261            $this->status = array_merge($this->status,array($this->serveroutput->status));
262            if ($this->serveroutput->status == "successfull-ok")
263                self::_errorLog("getting defaults: ".$this->serveroutput->status,3);
264            else
265                self::_errorLog("getting defaults: ".$this->serveroutput->status,1);
266            
267            return $this->serveroutput->status; 
268            
269        } else {
270            $this->status = array_merge($this->status,array("OPERATION FAILED"));
271            self::_errorLog("getting defaults : OPERATION FAILED",1);
272            }
273    return false;   
274    }
275    // }}}
276
277    // {{{ getPrinters()
278    public function getPrinters($printer_location=false,$printer_info=false,$attributes=array()) {
279        
280        if (count($attributes) == 0)
281        true;
282            $attributes=array('printer-uri-supported','printer-location','printer-info','printer-type','color-supported');
283        $this->jobs = array_merge($this->jobs,array(""));
284        $this->jobs_uri = array_merge($this->jobs_uri,array(""));
285        
286        unset ($this->printers_attributes);
287        
288        if (!isset($this->setup->charset))
289            self::setCharset('us-ascii');
290        
291        if (!isset($this->setup->language))
292            self::setLanguage('en-us');
293            
294        self::_setOperationId();
295        
296        $this->meta->attributes='';
297        
298        if ($printer_location)
299            $this->meta->attributes .= chr(0x41) // textWithoutLanguage
300                                    . self::_giveMeStringLength('printer-location')
301                                    . 'printer-location'
302                                    . self::_giveMeStringLength($printer_location)
303                                    . $printer_location;
304        
305        
306        if ($printer_info)
307            $this->meta->attributes .= chr(0x41) // textWithoutLanguage
308                                    . self::_giveMeStringLength('printer-info')
309                                    . 'printer-info'
310                                    . self::_giveMeStringLength($printer_info)
311                                    . $printer_info;
312        
313        for($i = 0 ; $i < count($attributes) ; $i++)
314            if ($i == 0)
315                $this->meta->attributes .= chr(0x44) // Keyword
316                                        . self::_giveMeStringLength('requested-attributes')
317                                        . 'requested-attributes'
318                                        . self::_giveMeStringLength($attributes[0])
319                                        . $attributes[0];
320            else
321                $this->meta->attributes .= chr(0x44) // Keyword
322                                        .  chr(0x0).chr(0x0) // zero-length name
323                                        .  self::_giveMeStringLength($attributes[$i])
324                                        .  $attributes[$i];
325
326        
327        $this->stringjob = chr(0x01) . chr(0x01) // IPP version 1.1 
328                         . chr(0x40). chr(0x02) // operation:  cups vendor extension: get printers
329                         . $this->meta->operation_id //           request-id
330                         . chr(0x01) // start operation-attributes | operation-attributes-tag
331                         . $this->meta->charset
332                         . $this->meta->language
333                         . $this->meta->attributes
334                         . chr(0x03); // end operations attribute
335                        
336        $this->output = $this->stringjob;
337           
338        $post_values = array( "Content-Type" => "application/ipp",
339                              "Data" => $this->output);
340            
341        if (self::_sendHttp ($post_values,'/')) {
342            
343            if(self::_parseServerOutput())
344                $this->_getAvailablePrinters();
345
346            }
347        
348        if (isset($this->serveroutput) && isset($this->serveroutput->status)) {
349            
350            $this->status = array_merge($this->status,array($this->serveroutput->status));
351            if ($this->serveroutput->status == "successfull-ok")
352                self::_errorLog("getting printers: ".$this->serveroutput->status,3);
353            else
354                self::_errorLog("getting printers: ".$this->serveroutput->status,1);
355            return $this->serveroutput->status; 
356            
357        } else {
358            $this->status = array_merge($this->status,array("OPERATION FAILED"));
359            self::_errorLog("getting printers : OPERATION FAILED",1);
360            }
361    return false;   
362    }
363    // }}}
364
365    // {{{ cupsGetPrinters ()
366    public function cupsGetPrinters () {
367    // alias for getPrinters();
368        self::getPrinters();
369    }
370    // }}}
371
372    // {{{ getPrinterAttributes()
373    public function getPrinterAttributes() {
374    // complete informations from parent with Cups-specific stuff
375    
376        if(!$result = parent::getPrinterAttributes())
377            return FALSE;
378        if(!isset($this->printer_attributes))
379            return FALSE;
380        
381        if (isset ($this->printer_attributes->printer_type)) {
382            $printer_type = $this->printer_attributes->printer_type->_value0;
383            $table = self::_interpretPrinterType($printer_type);
384        
385            for($i = 0 ; $i < count($table) ; $i++ ) {
386                $index = '_value'.$i;
387                $this->printer_attributes->printer_type->$index = $table[$i];
388                }
389            }
390
391    return $result;
392    }
393    // }}}
394
395//
396// SETUP
397//
398
399    // {{{ _initTags ()
400    protected function _initTags () {
401        
402        // override parent with specific cups attributes
403        
404        $operation_tags = array (); 
405        $this->operation_tags = array_merge ($this->operation_tags, $operation_tags);
406               
407        $job_tags = array ( "job-billing" => array("tag" => "textWithoutLanguage"),
408                            "blackplot" => array("tag" => "boolean"),
409                            "brightness" => array("tag" => "integer"),
410                            "columns" => array("tag" => "integer"),
411                            "cpi" => array("tag" => "enum"),
412                            "fitplot" => array("tag" => "boolean"),
413                            "gamma" => array("tag" => "integer"),
414                            "hue" => array("tag" => "integer"),
415                            "lpi" => array("tag" => "enum"),
416                            "mirror" => array("tag","boolean"),
417                            "natural-scaling" => array("tag" => "integer"),
418                            "number-up-layout" => array("tag" => "keyword"),
419                            "page-border" => array("tag" => "keyword"),
420                            "page-bottom" => array("tag" => "integer"),
421                            "page-label" => array("tag" => "textWithoutLanguage"),
422                            "page-left" => array("tag" => "integer"),
423                            "page-right" => array("tag" => "integer"),
424                            "page-set" => array("tag" => "keyword"),
425                            "page-top" => array("tag" => "integer"),
426                            "penwidth" => array("tag" => "integer"),
427                            "position" => array("tag" => "keyword"),
428                            "ppi" => array("tag" => "integer"),
429                            "prettyprint" => array("tag","boolean"),
430                            "saturation" => array("tag" => "integer"),
431                            "scaling" => array("tag" => "integer"),
432                            "wrap" => array("tag","boolean"),
433                            
434                            );
435        $this->job_tags = array_merge ($this->job_tags, $job_tags);
436    }
437    // }}}
438
439//
440// REQUEST BUILDING
441//
442
443    // {{{ _enumBuild ($tag,$value)
444    protected function _enumBuild ($tag,$value) {
445        
446        $value_built = parent::_enumBuild($tag,$value);
447       
448
449        switch ($tag) {
450           case "cpi":     
451                switch ($value) {
452                    case '10':
453                        $value_built = chr(10);
454                        break;
455                    case '12':
456                        $value_built = chr(12);
457                        break;
458                    case '17':
459                        $value_built = chr(17);
460                        break;
461                    default:
462                        $value_built = chr(10);
463                }
464            break;
465            case "lpi":
466                switch ($value) {
467                    case '6':
468                        $value_built = chr(6);
469                        break;
470                    case '8':
471                        $value_built = chr(8);
472                        break;
473                    default:
474                        $value_built = chr(6);
475                }
476            break;
477            }
478
479        $prepend = '';
480        while ((strlen($value_built) + strlen($prepend)) < 4)
481            $prepend .= chr(0);
482    return $prepend.$value_built;
483    }
484    // }}}
485    
486//
487// RESPONSE PARSING
488//
489
490    // {{{ _getAvailablePrinters ()
491    private function _getAvailablePrinters () {
492      
493        $this->available_printers = array();
494        $k = 0;
495        $this->printers_attributes = new stdClass();
496
497        for ($i = 0 ; (array_key_exists($i,$this->serveroutput->response)) ; $i ++)
498            if (($this->serveroutput->response[$i]['attributes']) == "printer-attributes") {
499                $phpname = "_printer".$k;
500                $this->printers_attributes->$phpname = new stdClass();
501                for ($j = 0 ; array_key_exists($j,$this->serveroutput->response[$i]) ; $j++) {
502                
503                    $value = $this->serveroutput->response[$i][$j]['value'];
504                    $name = str_replace("-","_",$this->serveroutput->response[$i][$j]['name']);
505                    
506                    switch ($name) {
507                        case "printer_uri_supported":
508                            $this->available_printers = array_merge($this->available_printers,array($value));
509                            break;
510                        case "printer_type":
511                            $table = self::_interpretPrinterType($value);
512                            $this->printers_attributes->$phpname->$name = new stdClass();
513        
514                            for($l = 0 ; $l < count($table) ; $l++ ) {
515                                $index = '_value'.$l;
516                                $this->printers_attributes->$phpname->$name->$index = $table[$l];
517                            }
518                            
519                            break;
520                        case '':
521                            break;
522                        default:
523                            $this->printers_attributes->$phpname->$name = $value;
524                            break;
525                        }
526
527                    }    
528                $k ++;
529                }
530    }
531    // }}}
532    
533    // {{{ _getEnumVendorExtensions
534    protected function _getEnumVendorExtensions ($value_parsed) {
535        switch ($value_parsed) {
536            case 0x4002:
537                $value = 'Get-Availables-Printers';
538                break;
539            default:
540                $value = sprintf('Unknown(Cups extension for operations): 0x%x',$value_parsed);
541                break;
542        }
543
544    if (isset($value))
545        return ($value);
546  
547    return sprintf('Unknown: 0x%x',$value_parsed);
548    }
549    // }}}
550
551    // {{{ _interpretPrinterType($type)
552    private function _interpretPrinterType($value) {
553        $value_parsed = 0;
554        for ($i = strlen($value) ; $i > 0 ; $i --)
555            $value_parsed += pow(256,($i - 1)) * ord($value[strlen($value) - $i]);
556       
557        $type[0] = $type[1] = $type[2] = $type[3] = $type[4] = $type[5] = '';
558        $type[6] = $type[7] = $type[8] = $type[9] = $type[10] = '';
559        $type[11] = $type[12] = $type[13] = $type[14] = $type[15] = '';
560        $type[16] = $type[17] = $type[18] = $type[19] = '';
561        
562        if ($value_parsed %2 == 1) {
563            $type[0] = 'printer-class';
564            $value_parsed -= 1;
565            }
566        if ($value_parsed %4 == 2 )  {
567            $type[1] = 'remote-destination';
568            $value_parsed -= 2;
569            }
570        if ($value_parsed %8 == 4 )  {
571            $type[2] = 'print-black';
572            $value_parsed -= 4;
573            }
574        if ($value_parsed %16 == 8 )  {
575            $type[3] = 'print-color';
576            $value_parsed -= 8;
577            }
578        if ($value_parsed %32 == 16) {
579            $type[4] = 'hardware-print-on-both-sides';
580            $value_parsed -= 16;
581            }
582        if ($value_parsed %64 == 32) {
583            $type[5] = 'hardware-staple-output';
584            $value_parsed -= 32;
585            }
586        if ($value_parsed %128 == 64) {
587            $type[6] = 'hardware-fast-copies';
588            $value_parsed -= 64;
589            }
590        if ($value_parsed %256 == 128) {
591            $type[7] = 'hardware-fast-copy-collation';
592            $value_parsed -= 128;
593            }
594        if ($value_parsed %512 == 256) {
595            $type[8] = 'punch-output';
596            $value_parsed -= 256;
597            }
598        if ($value_parsed %1024 == 512) {
599            $type[9] = 'cover-output';
600            $value_parsed -= 512;
601            }
602        if ($value_parsed %2048 == 1024) {
603            $type[10] = 'bind-output';
604            $value_parsed -= 1024;
605            }
606        if ($value_parsed %4096 == 2048) {
607            $type[11] = 'sort-output';
608            $value_parsed -= 2048;
609            }
610        if ($value_parsed %8192 == 4096) {
611            $type[12] = 'handle-media-up-to-US-Legal-A4';
612            $value_parsed -= 4096;
613            }
614        if ($value_parsed %16384 == 8192) {
615            $type[13] = 'handle-media-between-US-Legal-A4-and-ISO_C-A2';
616            $value_parsed -= 8192;
617            }
618        if ($value_parsed %32768 == 16384) {
619            $type[14] = 'handle-media-larger-than-ISO_C-A2';
620            $value_parsed -= 16384;
621            }
622        if ($value_parsed %65536 == 32768) {
623            $type[15] = 'handle-user-defined-media-sizes';
624            $value_parsed -= 32768;
625            }
626        if ($value_parsed %131072 == 65536) {
627            $type[16] = 'implicit-server-generated-class';
628            $value_parsed -= 65536;
629            }
630        if ($value_parsed %262144 == 131072) {
631            $type[17] = 'network-default-printer';
632            $value_parsed -= 131072;
633            }
634        if ($value_parsed %524288 == 262144) {
635            $type[18] = 'fax-device';
636            $value_parsed -= 262144;
637            }
638    return $type;   
639    }
640    // }}}
641
642    // {{{ _interpretEnum()
643    protected function _interpretEnum($attribute_name,$value) {
644       
645        $value_parsed = self::_interpretInteger($value);
646        
647        switch ($attribute_name) {
648            case 'cpi':
649            case 'lpi':
650                $value = $value_parsed;
651                break;
652            default:
653                $value = parent::_interpretEnum($attribute_name,$value);
654                break;
655            }
656        
657    
658    return $value;
659    }
660    // }}}
661    
662};
663
664/*
665 * Local variables:
666 * mode: php
667 * tab-width: 4
668 * c-basic-offset: 4
669 * End:
670 */
671?>